Created
June 25, 2025 13:20
-
-
Save debakarr/b4d1d2f1b45d3a41ed4a2c6e2c590442 to your computer and use it in GitHub Desktop.
Code to create Certs using Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import logging | |
| from datetime import datetime, timedelta | |
| import pytest | |
| from cryptography import x509 | |
| from cryptography.hazmat.primitives import hashes, serialization | |
| from cryptography.hazmat.primitives.asymmetric import rsa | |
| from cryptography.x509.oid import NameOID | |
| # Set up logger | |
| logger = logging.getLogger(__name__) | |
| def generate_key(): | |
| logger.info("Generating RSA private key") | |
| return rsa.generate_private_key(public_exponent=65537, key_size=2048) | |
| def generate_cert(subject, issuer, public_key, issuer_key, is_ca=False, alt_names=None): | |
| logger.info( | |
| "Generating certificate: subject=%s, issuer=%s, is_ca=%s, alt_names=%s", | |
| subject.rfc4514_string(), | |
| issuer.rfc4514_string(), | |
| is_ca, | |
| alt_names, | |
| ) | |
| builder = ( | |
| x509.CertificateBuilder() | |
| .subject_name(subject) | |
| .issuer_name(issuer) | |
| .public_key(public_key) | |
| .serial_number(x509.random_serial_number()) | |
| .not_valid_before(datetime.utcnow()) | |
| .not_valid_after(datetime.utcnow() + timedelta(days=3650)) | |
| ) | |
| builder = builder.add_extension( | |
| x509.BasicConstraints(ca=is_ca, path_length=None), critical=True | |
| ) | |
| # Add Subject Alternative Names (SANs) if provided | |
| if alt_names: | |
| logger.info("Adding Subject Alternative Names: %s", alt_names) | |
| san = x509.SubjectAlternativeName([x509.DNSName(name) for name in alt_names]) | |
| builder = builder.add_extension(san, critical=False) | |
| cert = builder.sign(private_key=issuer_key, algorithm=hashes.SHA256()) | |
| logger.info("Certificate generated successfully") | |
| return cert | |
| def write_key(key, path): | |
| logger.info("Writing key to %s", path) | |
| path.write_bytes( | |
| key.private_bytes( | |
| encoding=serialization.Encoding.PEM, | |
| format=serialization.PrivateFormat.TraditionalOpenSSL, | |
| encryption_algorithm=serialization.NoEncryption(), | |
| ) | |
| ) | |
| def write_cert(cert, path): | |
| logger.info("Writing certificate to %s", path) | |
| path.write_bytes(cert.public_bytes(serialization.Encoding.PEM)) | |
| def build_subject(name): | |
| logger.info("Building X.509 subject for %s", name) | |
| return x509.Name( | |
| [ | |
| x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), | |
| x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Test Org"), | |
| x509.NameAttribute(NameOID.COMMON_NAME, name), | |
| ] | |
| ) | |
| @pytest.fixture(scope="session") | |
| def generated_cert_chain(tmp_path_factory): | |
| logger.info("Creating temporary directory for certificate chain") | |
| tmp = tmp_path_factory.mktemp("cert_chain") | |
| # === Generate CA key and cert === | |
| logger.info("Generating CA key and certificate") | |
| ca_key = generate_key() | |
| ca_subject = build_subject("MyTestCA") | |
| ca_cert = generate_cert( | |
| ca_subject, ca_subject, ca_key.public_key(), ca_key, is_ca=True | |
| ) | |
| write_key(ca_key, tmp / "ca-key.pem") | |
| write_cert(ca_cert, tmp / "ca-cert.pem") | |
| # === Generate Server key and cert === | |
| logger.info("Generating server key and certificate") | |
| server_key = generate_key() | |
| server_subject = build_subject("pytest-fixture-server") | |
| alt_names = ["localhost", "127.0.0.1", "host.docker.internal"] | |
| server_cert = generate_cert( | |
| server_subject, ca_subject, server_key.public_key(), ca_key, alt_names=alt_names | |
| ) | |
| write_key(server_key, tmp / "server-key.pem") | |
| write_cert(server_cert, tmp / "server-cert.pem") | |
| # === Generate Client key and cert === | |
| logger.info("Generating client key and certificate") | |
| client_key = generate_key() | |
| client_subject = build_subject("pytest-fixture-client") | |
| client_cert = generate_cert( | |
| client_subject, ca_subject, client_key.public_key(), ca_key | |
| ) | |
| write_key(client_key, tmp / "client-key.pem") | |
| write_cert(client_cert, tmp / "client-cert.pem") | |
| logger.info("Certificate chain generation complete. Output directory: %s", tmp) | |
| return { | |
| "dir": tmp, | |
| "ca_cert": tmp / "ca-cert.pem", | |
| "ca_key": tmp / "ca-key.pem", | |
| "server_cert": tmp / "server-cert.pem", | |
| "server_key": tmp / "server-key.pem", | |
| "client_cert": tmp / "client-cert.pem", | |
| "client_key": tmp / "client-key.pem", | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment