Skip to content

Instantly share code, notes, and snippets.

@kaedenbrinkman
Created August 7, 2023 23:45
Show Gist options
  • Save kaedenbrinkman/c5f2b7d05034999cd55821a4f3403720 to your computer and use it in GitHub Desktop.
Save kaedenbrinkman/c5f2b7d05034999cd55821a4f3403720 to your computer and use it in GitHub Desktop.
PyOpenSSL X.509 Store Order
import datetime
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509.oid import NameOID
from OpenSSL import crypto
from cryptography.hazmat.primitives import serialization
def generate_chain():
# ROOT CA
root_private_key = ec.generate_private_key(ec.SECP256R1())
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u'Root CA'),
])
now = datetime.datetime.utcnow()
not_valid_before = now - datetime.timedelta(days=1)
not_valid_after = not_valid_before + datetime.timedelta(days=364)
root_cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(issuer)
.public_key(root_private_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(not_valid_before)
.not_valid_after(not_valid_after)
.add_extension(
x509.BasicConstraints(ca=True, path_length=None), critical=True,
)
.sign(root_private_key, hashes.SHA256())
)
# INTERMEDIATE CA
intermediate_private_key = ec.generate_private_key(ec.SECP256R1())
subject = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u'Intermediate CA'),
])
intermediate_cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(root_cert.subject)
.public_key(intermediate_private_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(not_valid_before)
.not_valid_after(not_valid_after)
.add_extension(
x509.BasicConstraints(ca=True, path_length=None), critical=True,
)
.sign(root_private_key, hashes.SHA256())
)
# LEAF CERT
leaf_private_key = ec.generate_private_key(ec.SECP256R1())
subject = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, u'Leaf CA'),
])
leaf_cert = (
x509.CertificateBuilder()
.subject_name(subject)
.issuer_name(intermediate_cert.subject)
.public_key(leaf_private_key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(not_valid_before)
.not_valid_after(not_valid_after)
.add_extension(
x509.SubjectAlternativeName([
x509.DNSName(u'example.com'),
]),
critical=False,
)
.sign(intermediate_private_key, hashes.SHA256())
)
return root_cert, intermediate_cert, leaf_cert
def validate_chain(leaf, intermediates, root):
try:
store = crypto.X509Store()
for cert in intermediates:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert.public_bytes(serialization.Encoding.PEM).decode('utf-8'))
store.add_cert(cert)
cert = crypto.load_certificate(crypto.FILETYPE_PEM, root.public_bytes(serialization.Encoding.PEM).decode('utf-8'))
store.add_cert(cert)
cert = crypto.load_certificate(crypto.FILETYPE_PEM, leaf.public_bytes(serialization.Encoding.PEM).decode('utf-8'))
store_ctx = crypto.X509StoreContext(store, cert)
store_ctx.verify_certificate()
return True
except Exception as e:
# print(e)
return False
root_1, chain_1, leaf_1 = generate_chain()
root_2, chain_2, leaf_2 = generate_chain()
r0 = validate_chain(leaf_1, [chain_1], root_1)
r1 = validate_chain(leaf_1, [chain_1, chain_2], root_1)
r2 = validate_chain(leaf_1, [chain_2, chain_1], root_1)
print(r0, r1, r2) # True True False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment