#!/usr/bin/env python3 import json from datetime import datetime from datetime import timedelta from os import environ from pathlib import Path from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa """ this script creates a locally signed ca certificate. """ # paths tls_root_dir = Path("config") / "tls" path_server_cert = tls_root_dir / "server.pem" path_server_key = tls_root_dir / "server-key.pem" if __name__ == "__main__": # get configuration from environment variable conf_common_name = environ["TLS_COMMON_NAME"] conf_tls_expire_after_days = int(environ["TLS_EXPIRE_AFTER_DAYS"]) try: conf_alternative_name1 = environ["TLS_ALT_NAME1"] except KeyError: conf_alternative_name1 = None try: conf_alternative_name2 = environ["TLS_ALT_NAME2"] except KeyError: conf_alternative_name2 = None # generate server cert & key private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, backend=default_backend() ) subject = issuer = x509.Name([ x509.NameAttribute(x509.oid.NameOID.COUNTRY_NAME, "--"), x509.NameAttribute(x509.oid.NameOID.STATE_OR_PROVINCE_NAME, "--"), x509.NameAttribute(x509.oid.NameOID.LOCALITY_NAME, "--"), x509.NameAttribute(x509.oid.NameOID.ORGANIZATION_NAME, "--"), x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, conf_common_name) ]) cert_sans = [] if conf_alternative_name1 != None: cert_sans.append(x509.DNSName(conf_alternative_name1)) if conf_alternative_name2 != None: cert_sans.append(x509.DNSName(conf_alternative_name2)) certificate = x509.CertificateBuilder()\ .subject_name(subject)\ .issuer_name(issuer)\ .public_key(private_key.public_key())\ .serial_number(x509.random_serial_number())\ .not_valid_before(datetime.utcnow())\ .not_valid_after(datetime.utcnow() + timedelta(days=conf_tls_expire_after_days))\ .add_extension(x509.SubjectAlternativeName(cert_sans), critical=False)\ .add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True)\ .sign(private_key, hashes.SHA512(), backend=default_backend()) with path_server_cert.open("wb") as certout: certout.write(certificate.public_bytes(serialization.Encoding.PEM)) with path_server_key.open("wb") as keyout: private_key_bytes = private_key.private_bytes( encoding = serialization.Encoding.PEM, format = serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() ) keyout.write(private_key_bytes) print("Generated TLS certificate & key.")