tools/testing/sign_csr.py (100 lines of code) (raw):

#!/usr/bin/env python3 """ Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. """ import os import sys import datetime from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.serialization import Encoding def print_usage(): print ("Usage: {0} <CSR> <CA key> <root CA key>".format (sys.argv[0])) sys.exit (1) if (len (sys.argv) < 4): print_usage () if (not os.path.exists (sys.argv[1])): print ("Can't find CSR file to sign: {0}".format (sys.argv[1])) sys.exit (1) with (open (sys.argv[1], "rb")) as csr_file: csr_data = csr_file.read () csr = x509.load_der_x509_csr (csr_data, backend = default_backend ()) if (not os.path.exists (sys.argv[2])): print ("Can't find CA key file: {0}".format (sys.argv[2])) sys.exit (1) with (open (sys.argv[2], "rb")) as key_file: key_data = key_file.read () ca_key_priv = serialization.load_pem_private_key (key_data, password = None, backend = default_backend ()) ca_key = ca_key_priv.public_key () if ((ca_key_priv.key_size == 384) or (ca_key_priv.key_size > 2048)): ca_hash = hashes.SHA384 () else: ca_hash = hashes.SHA256 () if (not os.path.exists (sys.argv[3])): print ("Can't find root CA key file: {0}".format (sys.argv[3])) sys.exit (1) with (open (sys.argv[3], "rb")) as key_file: key_data = key_file.read () root_key_priv = serialization.load_pem_private_key (key_data, password = None, backend = default_backend ()) root_key = root_key_priv.public_key () if ((root_key_priv.key_size == 384) or (root_key_priv.key_size > 2048)): root_hash = hashes.SHA384 () else: root_hash = hashes.SHA256 () # Generate the root CA certificate root = x509.CertificateBuilder () root = root.subject_name (x509.Name ([x509.NameAttribute (NameOID.COMMON_NAME, "Root")])) root = root.issuer_name (x509.Name ([x509.NameAttribute (NameOID.COMMON_NAME, "Root")])) root = root.serial_number (0x12345678) root = root.not_valid_before (datetime.datetime (2019, 1, 1, 0, 0, 0)) root = root.not_valid_after (datetime.datetime (9999, 12, 31, 23, 59, 59)) root = root.add_extension (x509.SubjectKeyIdentifier.from_public_key (root_key), critical = False) root = root.add_extension (x509.AuthorityKeyIdentifier.from_issuer_public_key (root_key), critical = False) root = root.add_extension (x509.BasicConstraints (ca = True, path_length = None), critical = True) root = root.add_extension (x509.KeyUsage (digital_signature = False, content_commitment = False, key_encipherment = False, data_encipherment = False, key_agreement = False, key_cert_sign = True, crl_sign = False, encipher_only = False, decipher_only = False), critical = True) root = root.public_key (root_key) root_cert = root.sign (private_key = root_key_priv, algorithm = root_hash, backend = default_backend ()) with (open ("root.crt", "wb")) as cert_file: cert_file.write (root_cert.public_bytes (Encoding.DER)) # Generate an intermediate CA certificate ca = x509.CertificateBuilder () ca = ca.subject_name (x509.Name ([x509.NameAttribute (NameOID.COMMON_NAME, "IntrCA")])) ca = ca.issuer_name (x509.Name ([x509.NameAttribute (NameOID.COMMON_NAME, "Root")])) ca = ca.serial_number (0x76543210) ca = ca.not_valid_before (datetime.datetime (2019, 1, 1, 0, 0, 0)) ca = ca.not_valid_after (datetime.datetime (9999, 12, 31, 23, 59, 59)) ca = ca.add_extension (x509.SubjectKeyIdentifier.from_public_key (ca_key), critical = False) ca = ca.add_extension (x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier ( root_cert.extensions.get_extension_for_class (x509.SubjectKeyIdentifier).value), critical = False) ca = ca.add_extension (x509.BasicConstraints (ca = True, path_length = None), critical = True) ca = ca.add_extension (x509.KeyUsage (digital_signature = False, content_commitment = False, key_encipherment = False, data_encipherment = False, key_agreement = False, key_cert_sign = True, crl_sign = False, encipher_only = False, decipher_only = False), critical = True) ca = ca.public_key (ca_key) ca_cert = ca.sign (private_key = root_key_priv, algorithm = root_hash, backend = default_backend ()) with (open ("ca.crt", "wb")) as cert_file: cert_file.write (ca_cert.public_bytes (Encoding.DER)) # Sign the CSR cert = x509.CertificateBuilder () cert = cert.subject_name (csr.subject) cert = cert.issuer_name (x509.Name ([x509.NameAttribute (NameOID.COMMON_NAME, "IntrCA")])) cert = cert.serial_number (0x11223344) cert = cert.not_valid_before (datetime.datetime (2019, 1, 1, 0, 0, 0)) cert = cert.not_valid_after (datetime.datetime (9999, 12, 31, 23, 59, 59)) cert = cert.add_extension (x509.SubjectKeyIdentifier.from_public_key (csr.public_key ()), critical = False) cert = cert.add_extension (x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier ( ca_cert.extensions.get_extension_for_class (x509.SubjectKeyIdentifier).value), critical = False) for ext in csr.extensions: cert = cert.add_extension (ext.value, critical = ext.critical) cert = cert.public_key (csr.public_key ()) image_cert = cert.sign (private_key = ca_key_priv, algorithm = ca_hash, backend = default_backend ()) with (open ("cert.crt", "wb")) as cert_file: cert_file.write (image_cert.public_bytes (Encoding.DER))