`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:
- 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
). - Save the cert to
cert.pem
-
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.