51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""Certificate helpers shared by tests (not pytest fixtures)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import datetime
|
|
|
|
from cryptography import x509
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.x509.oid import NameOID
|
|
|
|
|
|
def _name(cn: str) -> x509.Name:
|
|
return x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)])
|
|
|
|
|
|
def issue_test_ca() -> tuple[rsa.RSAPrivateKey, x509.Certificate]:
|
|
key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
now = datetime.datetime.now(datetime.UTC)
|
|
cert = (
|
|
x509.CertificateBuilder()
|
|
.subject_name(_name("Test CA"))
|
|
.issuer_name(_name("Test CA"))
|
|
.public_key(key.public_key())
|
|
.serial_number(1)
|
|
.not_valid_before(now - datetime.timedelta(minutes=1))
|
|
.not_valid_after(now + datetime.timedelta(days=30))
|
|
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
|
|
.sign(key, hashes.SHA256())
|
|
)
|
|
return key, cert
|
|
|
|
|
|
def sign_csr(csr: x509.CertificateSigningRequest, ca_key, ca_cert) -> x509.Certificate:
|
|
now = datetime.datetime.now(datetime.UTC)
|
|
builder = (
|
|
x509.CertificateBuilder()
|
|
.subject_name(csr.subject)
|
|
.issuer_name(ca_cert.subject)
|
|
.public_key(csr.public_key())
|
|
.serial_number(x509.random_serial_number())
|
|
.not_valid_before(now - datetime.timedelta(minutes=1))
|
|
.not_valid_after(now + datetime.timedelta(days=7))
|
|
)
|
|
try:
|
|
san = csr.extensions.get_extension_for_class(x509.SubjectAlternativeName)
|
|
builder = builder.add_extension(san.value, critical=False)
|
|
except x509.ExtensionNotFound:
|
|
pass
|
|
return builder.sign(ca_key, hashes.SHA256())
|