]> Cypherpunks.ru repositories - pygost.git/blobdiff - pygost/asn1schemas/cert-selfsigned-example.py
cert-selfsigned-example optionally can create create CA certificate
[pygost.git] / pygost / asn1schemas / cert-selfsigned-example.py
index 43a7e4412a6cc6ccd1ea1e738a09c5adcc0aadfd..198ce2f6ca426926bb750b06fb47e4b430509e77 100644 (file)
@@ -1,22 +1,23 @@
 """Create example self-signed X.509 certificate
 """
 
+from argparse import ArgumentParser
 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 textwrap import fill
 
 from pyderasn import Any
 from pyderasn import BitString
+from pyderasn import Boolean
 from pyderasn import Integer
 from pyderasn import OctetString
 from pyderasn import PrintableString
 from pyderasn import UTCTime
 
 from pygost.asn1schemas.oids import id_at_commonName
+from pygost.asn1schemas.oids import id_ce_basicConstraints
 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
@@ -28,6 +29,7 @@ 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 BasicConstraints
 from pygost.asn1schemas.x509 import Certificate
 from pygost.asn1schemas.x509 import CertificateSerialNumber
 from pygost.asn1schemas.x509 import Extension
@@ -49,8 +51,18 @@ from pygost.gost3410 import public_key
 from pygost.gost3410 import sign
 from pygost.gost34112012512 import GOST34112012512
 
-if len(argv) != 2:
-    sys_exit("Usage: cert-selfsigned-example.py COMMON-NAME")
+parser = ArgumentParser(description="Self-signed X.509 certificate creator")
+parser.add_argument(
+    "--ca",
+    action="store_true",
+    help="Enable BasicConstraints.cA",
+)
+parser.add_argument(
+    "--cn",
+    required=True,
+    help="Subject's CommonName",
+)
+args = parser.parse_args()
 
 
 def pem(obj):
@@ -80,7 +92,7 @@ subj = Name(("rdnSequence", RDNSequence([
     RelativeDistinguishedName((
         AttributeTypeAndValue((
             ("type", AttributeType(id_at_commonName)),
-            ("value", AttributeValue(PrintableString(argv[1]))),
+            ("value", AttributeValue(PrintableString(args.cn))),
         )),
     ))
 ])))
@@ -89,6 +101,19 @@ not_after = not_before + timedelta(days=365)
 ai_sign = AlgorithmIdentifier((
     ("algorithm", id_tc26_signwithdigest_gost3410_2012_512),
 ))
+exts = [
+    Extension((
+        ("extnID", id_ce_subjectKeyIdentifier),
+        ("extnValue", OctetString(
+            SubjectKeyIdentifier(GOST34112012512(pub_raw).digest()[:20]).encode()
+        )),
+    )),
+]
+if args.ca:
+    exts.append(Extension((
+        ("extnID", id_ce_basicConstraints),
+        ("extnValue", OctetString(BasicConstraints((("cA", Boolean(True)),)).encode())),
+    )))
 tbs = TBSCertificate((
     ("version", Version("v3")),
     ("serialNumber", CertificateSerialNumber(12345)),
@@ -106,14 +131,7 @@ tbs = TBSCertificate((
         ))),
         ("subjectPublicKey", BitString(OctetString(pub_raw).encode())),
     ))),
-    ("extensions", Extensions((
-        Extension((
-            ("extnID", id_ce_subjectKeyIdentifier),
-            ("extnValue", OctetString(
-                SubjectKeyIdentifier(GOST34112012512(pub_raw).digest()[:20]).encode()
-            )),
-        )),
-    ))),
+    ("extensions", Extensions(exts)),
 ))
 cert = Certificate((
     ("tbsCertificate", tbs),