Python could use some better SSL certificate debugging feature.
import ssl, socket
host = 'discuss.python.org'
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_default_certs()
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)
conn.connect((host, 443))
print(conn.getpeercert())
Sometimes this works, sometimes this fails:
C:\> py cert_test.py
{'subject': ((('commonName', 'discuss.python.org'),),), 'issuer': ((('countryName', 'US'),), (('organizationName', "Let's Encrypt"),), (('commonName', 'R3'),)), 'version': 3, 'serialNumber': '0433C3C2F3865D6770D70DD7F61E9EAEAB67', 'notBefore': 'Sep 8 00:00:21 2022 GMT', 'notAfter': 'Dec 7 00:00:20 2022 GMT', 'subjectAltName': (('DNS', 'discuss.python.org'),), 'OCSP': ('http://r3.o.lencr.org',), 'caIssuers': ('http://r3.i.lencr.org/',)}
C:\> py cert_test.py
Traceback (most recent call last):
File "C:\cert_test.py", line 6, in <module>
conn.connect((host, 443))
File "C:\Python310\lib\ssl.py", line 1375, in connect
self._real_connect(addr, False)
File "C:\Python310\lib\ssl.py", line 1366, in _real_connect
self.do_handshake()
File "C:\Python310\lib\ssl.py", line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:997)
There’s apparently no way to see the rejected certificate, or why it was rejected.