python / cpython

The Python programming language
https://www.python.org
Other
63.21k stars 30.27k forks source link

ssl module fails to correctly match hostnames in match_hostname #106729

Open quanah opened 1 year ago

quanah commented 1 year ago

I'm using the ssl module in conjunction with the python-ldap3 library. I've found that when setting ssl.CERT_REQUIRED a valid cert fails the hostname check done by the function match_hostname.

The ldap3 code is here https://github.com/cannatag/ldap3/blob/dev/ldap3/core/tls.py#L317

In the error that comes back, we see:


ldap3.core.exceptions.LDAPCertificateError: certificate {'subject': ((('commonName', 'ldap-slave.nonprod.example.net'),),), 'issuer': ((('commonName', 'ca.ldap.internal'),),), 'version': 3, 'serialNumber': '3A0FBCB4DF309A72F574E4B07076376D2DEF78A5', 'notBefore': 'Jul 11 15:01:47 2023 GMT', 'notAfter': 'Jul  8 15:01:47 2033 GMT', 'subjectAltName': (('DNS', '*.nonprod.eu1.ldap-cp.example.net'), ('DNS', 'local.nonprod.eu1.ldap-cp.example.net'))} doesn't match any name in ['ldap-slave.nonprod.example.net']```

However, we can clearly see that 'ldap-slave.nonprod.example.net' is a valid name, stored as the commonName for the cert.  There is no issue validating this cert with OpenSSL.  It appears match_hostname is ONLY considering the subjectAltName values.
MelindaShore commented 1 year ago

It should probably check the common name in the interest of being less likely to be surprising in cases like this, but the CA/B Forum baseline requirements specify that the SAN extension must be present and it must contain a domain name that's had domain control validated by the issuer (see CA/B BRs section 7.1.2.7.12. That is to say, what you ran into with a locally-issued test cert is very unlikely to happen with a certificate issued by a publicly-trusted CA.

That said,people put together local-only certificates all the time, and I do think that in the interest of "be generous in what you accept" this should probably be checking the common name, as well.