]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/asn1schemas/cert-selfsigned-example.py
Example X.509 self-signed certificate creation utility
[pygost.git] / pygost / asn1schemas / cert-selfsigned-example.py
diff --git a/pygost/asn1schemas/cert-selfsigned-example.py b/pygost/asn1schemas/cert-selfsigned-example.py
new file mode 100644 (file)
index 0000000..5cdca8f
--- /dev/null
@@ -0,0 +1,133 @@
+"""Create example self-signed X.509 certificate
+"""
+
+from base64 import standard_b64encode
+from datetime import datetime
+from datetime import timedelta
+from os import urandom
+from sys import argv
+from sys import exit as sys_exit
+from sys import stderr
+from textwrap import fill
+
+from pyderasn import Any
+from pyderasn import BitString
+from pyderasn import Integer
+from pyderasn import ObjectIdentifier
+from pyderasn import OctetString
+from pyderasn import PrintableString
+from pyderasn import UTCTime
+
+from pygost.asn1schemas.oids import id_ce_subjectKeyIdentifier
+from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512
+from pygost.asn1schemas.oids import id_tc26_gost3410_2012_512_paramSetA
+from pygost.asn1schemas.oids import id_tc26_gost3411_2012_512
+from pygost.asn1schemas.oids import id_tc26_signwithdigest_gost3410_2012_512
+from pygost.asn1schemas.prvkey import PrivateKey
+from pygost.asn1schemas.prvkey import PrivateKeyAlgorithmIdentifier
+from pygost.asn1schemas.prvkey import PrivateKeyInfo
+from pygost.asn1schemas.x509 import AlgorithmIdentifier
+from pygost.asn1schemas.x509 import AttributeType
+from pygost.asn1schemas.x509 import AttributeTypeAndValue
+from pygost.asn1schemas.x509 import AttributeValue
+from pygost.asn1schemas.x509 import Certificate
+from pygost.asn1schemas.x509 import CertificateSerialNumber
+from pygost.asn1schemas.x509 import Extension
+from pygost.asn1schemas.x509 import Extensions
+from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters
+from pygost.asn1schemas.x509 import Name
+from pygost.asn1schemas.x509 import RDNSequence
+from pygost.asn1schemas.x509 import RelativeDistinguishedName
+from pygost.asn1schemas.x509 import SubjectKeyIdentifier
+from pygost.asn1schemas.x509 import SubjectPublicKeyInfo
+from pygost.asn1schemas.x509 import TBSCertificate
+from pygost.asn1schemas.x509 import Time
+from pygost.asn1schemas.x509 import Validity
+from pygost.asn1schemas.x509 import Version
+from pygost.gost3410 import CURVES
+from pygost.gost3410 import prv_unmarshal
+from pygost.gost3410 import pub_marshal
+from pygost.gost3410 import public_key
+from pygost.gost3410 import sign
+from pygost.gost34112012512 import GOST34112012512
+
+if len(argv) != 2:
+    print("Usage: cert-selfsigned-example.py COMMON-NAME", file=stderr)
+    sys_exit(1)
+
+def pem(obj):
+    return fill(standard_b64encode(obj.encode()).decode('ascii'), 64)
+
+key_params = GostR34102012PublicKeyParameters((
+    ("publicKeyParamSet", id_tc26_gost3410_2012_512_paramSetA),
+    ("digestParamSet", id_tc26_gost3411_2012_512),
+))
+
+prv_raw = urandom(64)
+print("-----BEGIN PRIVATE KEY-----")
+print(pem(PrivateKeyInfo((
+    ("version", Integer(0)),
+    ("privateKeyAlgorithm", PrivateKeyAlgorithmIdentifier((
+        ("algorithm", id_tc26_gost3410_2012_512),
+        ("parameters", Any(key_params)),
+    ))),
+    ("privateKey", PrivateKey(prv_raw)),
+))))
+print("-----END PRIVATE KEY-----")
+
+prv = prv_unmarshal(prv_raw)
+curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"]
+pub_raw = pub_marshal(public_key(curve, prv), mode=2012)
+id_at_commonName = ObjectIdentifier("2.5.4.3")
+subj = Name(("rdnSequence", RDNSequence([
+    RelativeDistinguishedName((
+        AttributeTypeAndValue((
+            ("type", AttributeType(id_at_commonName)),
+            ("value", AttributeValue(PrintableString(argv[1]))),
+        )),
+    ))
+])))
+not_before = datetime.utcnow()
+not_after = not_before + timedelta(days=365)
+ai_sign = AlgorithmIdentifier((
+    ("algorithm", id_tc26_signwithdigest_gost3410_2012_512),
+))
+tbs = TBSCertificate((
+    ("version", Version("v3")),
+    ("serialNumber", CertificateSerialNumber(12345)),
+    ("signature", ai_sign),
+    ("issuer", subj),
+    ("validity", Validity((
+        ("notBefore", Time(("utcTime", UTCTime(not_before)))),
+        ("notAfter", Time(("utcTime", UTCTime(not_after)))),
+    ))),
+    ("subject", subj),
+    ("subjectPublicKeyInfo", SubjectPublicKeyInfo((
+        ("algorithm", AlgorithmIdentifier((
+            ("algorithm", id_tc26_gost3410_2012_512),
+            ("parameters", Any(key_params)),
+        ))),
+        ("subjectPublicKey", BitString(OctetString(pub_raw).encode())),
+    ))),
+    ("extensions", Extensions((
+        Extension((
+            ("extnID", id_ce_subjectKeyIdentifier),
+            ("extnValue", OctetString(
+                SubjectKeyIdentifier(GOST34112012512(pub_raw).digest()[:20]).encode()
+            )),
+        )),
+    ))),
+))
+cert = Certificate((
+    ("tbsCertificate", tbs),
+    ("signatureAlgorithm", ai_sign),
+    ("signatureValue", BitString(sign(
+        curve,
+        prv,
+        GOST34112012512(tbs.encode()).digest(),
+        mode=2012,
+    ))),
+))
+print("-----BEGIN CERTIFICATE-----")
+print(pem(cert))
+print("-----END CERTIFICATE-----")