From 87e57c36c455cabde82f7cad027bfb89251681f5 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Fri, 4 Sep 2020 22:01:41 +0300 Subject: [PATCH] cert-selfsigned-example optionally can create create CA certificate --- news.texi | 11 +++-- pygost/asn1schemas/cert-selfsigned-example.py | 44 +++++++++++++------ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/news.texi b/news.texi index ac5b730..cf26c32 100644 --- a/news.texi +++ b/news.texi @@ -5,9 +5,14 @@ @anchor{Release 5.0} @item 5.0 -Backward incompatible removing of misleading and excess @option{mode} -keyword argument from all @code{gost3410*} related functions. Point/key -sizes are determined by looking at curve's parameters size. + @itemize + @item Backward incompatible removing of misleading and excess + @option{mode} keyword argument from all @code{gost3410*} related + functions. Point/key sizes are determined by looking at curve's + parameters size. + @item @command{asn1schemas/cert-selfsigned-example.py} optionally + can create CA certificate. + @end itemize @anchor{Release 4.9} @item 4.9 diff --git a/pygost/asn1schemas/cert-selfsigned-example.py b/pygost/asn1schemas/cert-selfsigned-example.py index 43a7e44..198ce2f 100644 --- a/pygost/asn1schemas/cert-selfsigned-example.py +++ b/pygost/asn1schemas/cert-selfsigned-example.py @@ -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), -- 2.44.0