gitscope
← marzneshin / nightly / app/utils/crypto.py
https://dev.kronoz.win/r/marzneshin.git
app/utils/crypto.py · Python
Blame Raw
 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