blob: bc2b4e992f468474fe05bafe67cd51d8f6b751e8 [file]
#!/usr/bin/env python3
import datetime
import ipaddress
import os
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
# All state is placed in this directory
STATE_DIR = os.environ.get("STATE_DIR", "./state")
HYPERCORN_SECRETS_DIR = os.path.join(STATE_DIR, "hypercorn", "secrets")
CERT_PATH = os.path.join(HYPERCORN_SECRETS_DIR, "cert.pem")
KEY_PATH = os.path.join(HYPERCORN_SECRETS_DIR, "key.pem")
def generate_self_signed_cert() -> None:
# Ensure that the Hypercorn secrets directory exists
os.makedirs(HYPERCORN_SECRETS_DIR, exist_ok=True)
# Generate a private RSA key
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
subject = issuer = x509.Name(
[
x509.NameAttribute(NameOID.COMMON_NAME, "127.0.0.1"),
]
)
# Use timezone-aware datetime objects for UTC
now = datetime.datetime.now(datetime.UTC)
# Build a certificate with a SAN for 127.0.0.1
cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(issuer)
.public_key(key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(now - datetime.timedelta(minutes=1))
.not_valid_after(now + datetime.timedelta(days=365))
.add_extension(
x509.SubjectAlternativeName([x509.IPAddress(ipaddress.IPv4Address("127.0.0.1"))]),
critical=False,
)
.sign(key, hashes.SHA256())
)
# Write out the private key with 400 permissions
os.umask(0o277)
with open(KEY_PATH, "wb") as f:
f.write(
key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)
# Write out the certificate
with open(CERT_PATH, "wb") as f:
f.write(cert.public_bytes(serialization.Encoding.PEM))
# codeql[py/clear-text-logging-sensitive-data]
print(f"Certificate generated:\n Cert: {CERT_PATH}\n Key: {KEY_PATH}")
if __name__ == "__main__":
generate_self_signed_cert()