"""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
-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.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
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):
- return fill(standard_b64encode(obj.encode()).decode('ascii'), 64)
+ 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)
prv = prv_unmarshal(prv_raw)
curve = CURVES["id-tc26-gost-3410-12-512-paramSetA"]
-pub_raw = pub_marshal(public_key(curve, prv), mode=2012)
+pub_raw = pub_marshal(public_key(curve, prv))
subj = Name(("rdnSequence", RDNSequence([
RelativeDistinguishedName((
AttributeTypeAndValue((
("type", AttributeType(id_at_commonName)),
- ("value", AttributeValue(PrintableString(argv[1]))),
+ ("value", AttributeValue(PrintableString(args.cn))),
)),
))
])))
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)),
))),
("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),
("signatureValue", BitString(sign(
curve,
prv,
- GOST34112012512(tbs.encode()).digest(),
- mode=2012,
+ GOST34112012512(tbs.encode()).digest()[::-1],
))),
))
print("-----BEGIN CERTIFICATE-----")