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