Search code examples
pythonx509asn.1pyasn1

How do I remove CT extensions from an x.509 certificate in Python?


I'm working on a Python script in which I need to determine if a precertificate and leaf certificate match.

To do this, I need to compare the TBS cert of the precert and leaf cert, after removing the SCT(1.3.6.1.4.1.11129.2.4.2) and Precert Poison(1.3.6.1.4.1.11129.2.4.3) extensions.

Using the python cryptography module, it's easy to get the TBS cert:

from cryptography import x509
from cryptography.hazmat.backends import default_backend

cert = x509.load_pem_x509_certificate(cert_data_pem, default_backend())

print(cert.tbs_certificate_bytes)

However I've not been able to figure out how to remove those extensions. It kind of looks like asn1crypto could do it, but there seems to be very little documentation available.

What's the neatest way to remove these extensions? I'm happy to depend on openssl if that works, as I'm already using it in the script.


Solution

  • Well the pyasn1 library was what eventually worked. This snippet decodes the TBS cert and removes the two extensions, then re-encodes it:

    from pyasn1.codec.der.decoder import decode as asn1_decode
    from pyasn1.codec.der.encoder import encode as asn1_encode
    from pyasn1_modules import rfc5280
    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    
    cert = asn1_decode(x509.load_pem_x509_certificate(cert_data_pem, default_backend()).tbs_certificate_bytes, asn1Spec=rfc5280.TBSCertificate())[0]
    
    newExts = [ext for ext in cert["extensions"] if str(ext["extnID"]) not in ("1.3.6.1.4.1.11129.2.4.2", "1.3.6.1.4.1.11129.2.4.3")]
    cert["extensions"].clear()
    cert["extensions"].extend(newExts)
    
    print(asn1_encode(cert))