1import ssl
2from datetime import datetime, timedelta
3
4from cryptography import x509
5from cryptography.hazmat.backends import default_backend
6from cryptography.hazmat.primitives import hashes, serialization
7from cryptography.hazmat.primitives.asymmetric import ec
8from cryptography.x509.oid import ExtendedKeyUsageOID
9
10
11def get_cert_SANs(cert: bytes):
12 cert = x509.load_pem_x509_certificate(cert, default_backend())
13 san_list = []
14 for extension in cert.extensions:
15 if isinstance(extension.value, x509.SubjectAlternativeName):
16 san = extension.value
17 for name in san:
18 san_list.append(name.value)
19 return san_list
20
21
22def generate_certificate():
23 key = ec.generate_private_key(ec.SECP256R1())
24
25 subject = issuer = x509.Name([])
26
27 subject_key_id = x509.SubjectKeyIdentifier.from_public_key(
28 key.public_key()
29 )
30
31 cert = (
32 x509.CertificateBuilder()
33 .subject_name(subject)
34 .issuer_name(issuer)
35 .public_key(key.public_key())
36 .serial_number(x509.random_serial_number())
37 .not_valid_before(datetime.utcnow())
38 .not_valid_after(datetime.utcnow() + timedelta(days=3650))
39 .add_extension(
40 x509.BasicConstraints(ca=False, path_length=None), critical=True
41 )
42 .add_extension(
43 x509.KeyUsage(
44 digital_signature=True,
45 content_commitment=False,
46 key_encipherment=True,
47 data_encipherment=False,
48 key_agreement=False,
49 key_cert_sign=False,
50 crl_sign=False,
51 encipher_only=False,
52 decipher_only=False,
53 ),
54 critical=False,
55 )
56 .add_extension(subject_key_id, critical=False)
57 .add_extension(
58 x509.ExtendedKeyUsage(
59 [
60 ExtendedKeyUsageOID.SERVER_AUTH,
61 ExtendedKeyUsageOID.CLIENT_AUTH,
62 ]
63 ),
64 critical=False,
65 )
66 .sign(private_key=key, algorithm=hashes.SHA256())
67 )
68
69 return {
70 "cert": cert.public_bytes(serialization.Encoding.PEM).decode(),
71 "key": key.private_bytes(
72 encoding=serialization.Encoding.PEM,
73 format=serialization.PrivateFormat.TraditionalOpenSSL,
74 encryption_algorithm=serialization.NoEncryption(),
75 ).decode(),
76 }
77
78
79def create_secure_context(
80 client_cert: str,
81 client_key: str,
82 trusted: str,
83) -> ssl.SSLContext:
84 ctx = ssl.create_default_context(cafile=trusted)
85 ctx.load_cert_chain(client_cert, client_key)
86 ctx.set_ciphers("ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20")
87 ctx.set_alpn_protocols(["h2"])
88 ctx.check_hostname = False
89 ctx.verify_mode = ssl.CERT_NONE
90 return ctx