]> Cypherpunks.ru repositories - pygost.git/commitdiff
Properly add AKID to issued child certificates
authorSergey Matveev <stargrave@stargrave.org>
Tue, 26 Jan 2021 12:05:14 +0000 (15:05 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Tue, 26 Jan 2021 12:06:00 +0000 (15:06 +0300)
pygost/asn1schemas/cert-selfsigned-example.py
pygost/asn1schemas/oids.py
pygost/asn1schemas/x509.py

index 94b4b34cf4ba318dc5bf75a0ac427b12d58dab65..1f505aae09e9e327fa9a2ea407690715634b6224 100755 (executable)
@@ -20,6 +20,7 @@ from pyderasn import PrintableString
 from pyderasn import UTCTime
 
 from pygost.asn1schemas.oids import id_at_commonName
+from pygost.asn1schemas.oids import id_ce_authorityKeyIdentifier
 from pygost.asn1schemas.oids import id_ce_basicConstraints
 from pygost.asn1schemas.oids import id_ce_subjectAltName
 from pygost.asn1schemas.oids import id_ce_subjectKeyIdentifier
@@ -41,6 +42,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 AuthorityKeyIdentifier
 from pygost.asn1schemas.x509 import BasicConstraints
 from pygost.asn1schemas.x509 import Certificate
 from pygost.asn1schemas.x509 import CertificateSerialNumber
@@ -48,6 +50,7 @@ from pygost.asn1schemas.x509 import Extension
 from pygost.asn1schemas.x509 import Extensions
 from pygost.asn1schemas.x509 import GeneralName
 from pygost.asn1schemas.x509 import GostR34102012PublicKeyParameters
+from pygost.asn1schemas.x509 import KeyIdentifier
 from pygost.asn1schemas.x509 import Name
 from pygost.asn1schemas.x509 import RDNSequence
 from pygost.asn1schemas.x509 import RelativeDistinguishedName
@@ -148,6 +151,7 @@ AIs = {
 ai = AIs[args.ai]
 
 ca_prv = None
+ca_cert = None
 ca_subj = None
 ca_ai = None
 if args.issue_with is not None:
@@ -163,7 +167,8 @@ if args.issue_with is not None:
     cert_raw = standard_b64decode(lines[idx + 1])
     pki = PrivateKeyInfo().decod(prv_raw)
     ca_prv = prv_unmarshal(bytes(OctetString().decod(bytes(pki["privateKey"]))))
-    tbs = Certificate().decod(cert_raw)["tbsCertificate"]
+    ca_cert = Certificate().decod(cert_raw)
+    tbs = ca_cert["tbsCertificate"]
     ca_subj = tbs["subject"]
     curve_oid = GostR34102012PublicKeyParameters().decod(bytes(
         tbs["subjectPublicKeyInfo"]["algorithm"]["parameters"]
@@ -232,6 +237,19 @@ if args.ca:
         ("extnID", id_ce_basicConstraints),
         ("extnValue", OctetString(BasicConstraints((("cA", Boolean(True)),)).encode())),
     )))
+if ca_ai is not None:
+    caKeyId = [
+        bytes(SubjectKeyIdentifier().decod(bytes(ext["extnValue"])))
+        for ext in ca_cert["tbsCertificate"]["extensions"]
+        if ext["extnID"] == id_ce_subjectKeyIdentifier
+    ][0]
+    exts.append(Extension((
+        ("extnID", id_ce_authorityKeyIdentifier),
+        ("extnValue", OctetString(AuthorityKeyIdentifier((
+            ("keyIdentifier", KeyIdentifier(caKeyId)),
+        )).encode())),
+    )))
+
 tbs = TBSCertificate((
     ("version", Version("v3")),
     ("serialNumber", CertificateSerialNumber(12345)),
index 54d2b0df04d57b90bf459ac7e07773894c1a20e3..d5b9031c42a586bb52f5c8c066cadf3de43e3231 100644 (file)
@@ -52,3 +52,4 @@ id_at_commonName = ObjectIdentifier("2.5.4.3")
 id_ce_basicConstraints = ObjectIdentifier("2.5.29.19")
 id_ce_subjectKeyIdentifier = ObjectIdentifier("2.5.29.14")
 id_ce_subjectAltName = ObjectIdentifier("2.5.29.17")
+id_ce_authorityKeyIdentifier = ObjectIdentifier("2.5.29.35")
index 29a0a601eb285cc25a07dd6f0c1b171d202e372e..cda11da42dcb4d1a8daff65bb054b9c6d02108f4 100644 (file)
@@ -215,23 +215,34 @@ class CertificateList(Sequence):
 
 class GeneralName(Choice):
     schema = (
-        # ('otherName', AnotherName(impl=tag_ctxc(0))),
-        # ('rfc822Name', IA5String(impl=tag_ctxp(1))),
-        ('dNSName', IA5String(impl=tag_ctxp(2))),
-        # ('x400Address', ORAddress(impl=tag_ctxp(3))),
-        # ('x400Address', OctetString(impl=tag_ctxp(3))),
-        # ('directoryName', Name(expl=tag_ctxc(4))),
-        # ('ediPartyName', EDIPartyName(impl=tag_ctxc(5))),
-        # ('uniformResourceIdentifier', IA5String(impl=tag_ctxp(6))),
-        # ('iPAddress', OctetString(impl=tag_ctxp(7))),
-        # ('registeredID', ObjectIdentifier(impl=tag_ctxp(8))),
+        # ("otherName", AnotherName(impl=tag_ctxc(0))),
+        # ("rfc822Name", IA5String(impl=tag_ctxp(1))),
+        ("dNSName", IA5String(impl=tag_ctxp(2))),
+        # ("x400Address", ORAddress(impl=tag_ctxp(3))),
+        # ("x400Address", OctetString(impl=tag_ctxp(3))),
+        # ("directoryName", Name(expl=tag_ctxc(4))),
+        # ("ediPartyName", EDIPartyName(impl=tag_ctxc(5))),
+        # ("uniformResourceIdentifier", IA5String(impl=tag_ctxp(6))),
+        # ("iPAddress", OctetString(impl=tag_ctxp(7))),
+        # ("registeredID", ObjectIdentifier(impl=tag_ctxp(8))),
     )
 
 
 class GeneralNames(SequenceOf):
     schema = GeneralName()
-    bounds = (1, float('+inf'))
+    bounds = (1, float("+inf"))
 
 
 class SubjectAltName(GeneralNames):
     pass
+
+
+class AuthorityKeyIdentifier(Sequence):
+    schema = (
+        ("keyIdentifier", KeyIdentifier(impl=tag_ctxp(0), optional=True)),
+        # ("authorityCertIssuer", GeneralNames(impl=tag_ctxc(1), optional=True)),
+        # (
+        #     "authorityCertSerialNumber",
+        #     CertificateSerialNumber(impl=tag_ctxp(2), optional=True),
+        # ),
+    )