]> Cypherpunks.ru repositories - pygost.git/blob - pygost/asn1schemas/cert-selfsigned-example.py
Example X.509 self-signed certificate creation utility
[pygost.git] / pygost / asn1schemas / cert-selfsigned-example.py
1 """Create example self-signed X.509 certificate
2 """
3
4 from base64 import standard_b64encode
5 from datetime import datetime
6 from datetime import timedelta
7 from os import urandom
8 from sys import argv
9 from sys import exit as sys_exit
10 from sys import stderr
11 from textwrap import fill
12
13 from pyderasn import Any
14 from pyderasn import BitString
15 from pyderasn import Integer
16 from pyderasn import ObjectIdentifier
17 from pyderasn import OctetString
18 from pyderasn import PrintableString
19 from pyderasn import UTCTime
20
21 from pygost.asn1schemas.oids import id_ce_subjectKeyIdentifier
22 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512
23 from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA
24 from pygost.asn1schemas.oids import id_tc26_gost3411_2012_512
25 from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512
26 from pygost.asn1schemas.prvkey import PrivateKey
27 from pygost.asn1schemas.prvkey import PrivateKeyAlgorithmIdentifier
28 from pygost.asn1schemas.prvkey import PrivateKeyInfo
29 from pygost.asn1schemas.x509 import AlgorithmIdentifier
30 from pygost.asn1schemas.x509 import AttributeType
31 from pygost.asn1schemas.x509 import AttributeTypeAndValue
32 from pygost.asn1schemas.x509 import AttributeValue
33 from pygost.asn1schemas.x509 import Certificate
34 from pygost.asn1schemas.x509 import CertificateSerialNumber
35 from pygost.asn1schemas.x509 import Extension
36 from pygost.asn1schemas.x509 import Extensions
37 from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters
38 from pygost.asn1schemas.x509 import Name
39 from pygost.asn1schemas.x509 import RDNSequence
40 from pygost.asn1schemas.x509 import RelativeDistinguishedName
41 from pygost.asn1schemas.x509 import SubjectKeyIdentifier
42 from pygost.asn1schemas.x509 import SubjectPublicKeyInfo
43 from pygost.asn1schemas.x509 import TBSCertificate
44 from pygost.asn1schemas.x509 import Time
45 from pygost.asn1schemas.x509 import Validity
46 from pygost.asn1schemas.x509 import Version
47 from pygost.gost3410 import CURVES
48 from pygost.gost3410 import prv_unmarshal
49 from pygost.gost3410 import pub_marshal
50 from pygost.gost3410 import public_key
51 from pygost.gost3410 import sign
52 from pygost.gost34112012512 import GOST34112012512
53
54 if len(argv) != 2:
55     print("Usage: cert-selfsigned-example.py COMMON-NAME", file=stderr)
56     sys_exit(1)
57
58 def pem(obj):
59     return fill(standard_b64encode(obj.encode()).decode('ascii'), 64)
60
61 key_params = GostR34102012PublicKeyParameters((
62     ("publicKeyParamSet", id_tc26_gost3410_2012_512_paramSetA),
63     ("digestParamSet", id_tc26_gost3411_2012_512),
64 ))
65
66 prv_raw = urandom(64)
67 print("-----BEGIN PRIVATE KEY-----")
68 print(pem(PrivateKeyInfo((
69     ("version", Integer(0)),
70     ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier((
71         ("algorithm", id_tc26_gost3410_2012_512),
72         ("parameters", Any(key_params)),
73     ))),
74     ("privateKey", PrivateKey(prv_raw)),
75 ))))
76 print("-----END PRIVATE KEY-----")
77
78 prv = prv_unmarshal(prv_raw)
79 curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"]
80 pub_raw = pub_marshal(public_key(curve, prv), mode=2012)
81 id_at_commonName = ObjectIdentifier("2.5.4.3")
82 subj = Name(("rdnSequence", RDNSequence([
83     RelativeDistinguishedName((
84         AttributeTypeAndValue((
85             ("type", AttributeType(id_at_commonName)),
86             ("value", AttributeValue(PrintableString(argv[1]))),
87         )),
88     ))
89 ])))
90 not_before = datetime.utcnow()
91 not_after = not_before + timedelta(days=365)
92 ai_sign = AlgorithmIdentifier((
93     ("algorithm", id_tc26_signwithdigest_gost3410_2012_512),
94 ))
95 tbs = TBSCertificate((
96     ("version", Version("v3")),
97     ("serialNumber", CertificateSerialNumber(12345)),
98     ("signature", ai_sign),
99     ("issuer", subj),
100     ("validity", Validity((
101         ("notBefore", Time(("utcTime", UTCTime(not_before)))),
102         ("notAfter", Time(("utcTime", UTCTime(not_after)))),
103     ))),
104     ("subject", subj),
105     ("subjectPublicKeyInfo", SubjectPublicKeyInfo((
106         ("algorithm", AlgorithmIdentifier((
107             ("algorithm", id_tc26_gost3410_2012_512),
108             ("parameters", Any(key_params)),
109         ))),
110         ("subjectPublicKey", BitString(OctetString(pub_raw).encode())),
111     ))),
112     ("extensions", Extensions((
113         Extension((
114             ("extnID", id_ce_subjectKeyIdentifier),
115             ("extnValue", OctetString(
116                 SubjectKeyIdentifier(GOST34112012512(pub_raw).digest()[:20]).encode()
117             )),
118         )),
119     ))),
120 ))
121 cert = Certificate((
122     ("tbsCertificate", tbs),
123     ("signatureAlgorithm", ai_sign),
124     ("signatureValue", BitString(sign(
125         curve,
126         prv,
127         GOST34112012512(tbs.encode()).digest(),
128         mode=2012,
129     ))),
130 ))
131 print("-----BEGIN CERTIFICATE-----")
132 print(pem(cert))
133 print("-----END CERTIFICATE-----")