pyca/pyopenssl

`X509Extension.get_short_name` does not handle error case of `OBJ_nid2sn`

huwcbjones opened this issue · 2 comments

As per the 1.1.1 man pages (the 3.x man pages are the same), OBJ_nid2sn can return NULL if an error occurred.

In OpenSSL versions prior to 3.1, calling OBJ_nid2sn on an unknown OID resulted in "UNDEF". In version 3.1 (and I'm assuming later), you get NULL returned. Obviously NULL can't be used to create a string which results in get_short_name erroring with builtins.RuntimeError: cannot use string() on <cdata 'char *' NULL>.

To reproduce:

  1. Generate a certificate with a non-standard extension (i.e.: from MS Active Directory Cert Services, 1.3.6.1.4.1.311.20.2).
  2. Save the cert to cert.pem
  3. from OpenSSL import crypto
    with open("cert.pem", r") as cert_f:
       cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_f.read())
    exts = [cert.get_extension(i) for i in range(cert.get_extension_count())]
    for i, ext in enumerate(exts):
       print(i, ext.get_short_name())

cryptography seems to cope with this:

from cryptography import x509
with open("cert.pem", "rb") as cert_f:
    cert = x509.load_pem_x509_certificate(cert_f.read())
print(cert.extensions[$unknownOID])

results in
<Extension(oid=<ObjectIdentifier(oid=1.3.6.1.4.1.311.20.2, name=Unknown OID)>, critical=False, value=<UnrecognizedExtension(oid=<ObjectIdentifier(oid=1.3.6.1.4.1.311.20.2, name=Unknown OID)>, value=b"...")>)>

However, this was found when a buildbot worker (which uses Twisted's PB, which uses PyOpenSSL/service_identity) was upgraded from cryptography 39 to 40 (OpenSSL 3.0 to 3.1) and then tried to dial back to the buildbot master which has a certificate issued from MS ADCS with unknown X509 extensions.

Well, no sooner than I post this issue, openssl/openssl@908ba3e went in yesterday...
However, there are still versions of cryptography in the wild that vendor the dodgy version to cause this breakage.

We've put a workaround into 23.1.1 for this since 3.1.0 will continue to exist for some time.