Is it possible to retrieve an invalid certificate chain (specifically, one which terminates in a never-before-seen root certificate) with just the Python 3.10 standard library?
I modified the code from this answer incorporating the answers to this question, but I'm still getting an empty result to .getpeercert()
.
import socket
from contextlib import closing
from ssl import SSLContext # Modern SSL?
from ssl import HAS_SNI # Has SNI?
from ssl import PROTOCOL_TLS_CLIENT, CERT_NONE, CERT_REQUIRED
from pprint import pprint
def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
ca_certs=None, server_hostname=None, check_hostname=True,
ssl_version=None):
context = SSLContext(ssl_version)
context.check_hostname = check_hostname
context.verify_mode = cert_reqs
if ca_certs:
try:
context.load_verify_locations(ca_certs)
# Py32 raises IOError
# Py33 raises FileNotFoundError
except Exception as e: # Reraise as SSLError
raise ssl.SSLError(e)
if certfile:
# FIXME: This block needs a test.
context.load_cert_chain(certfile, keyfile)
if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI
return context.wrap_socket(sock, server_hostname=server_hostname)
return context.wrap_socket(sock)
def __main__(hostname):
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
s.connect((hostname, 443))
sslSocket = ssl_wrap_socket(s,
ssl_version=PROTOCOL_TLS_CLIENT,
cert_reqs=CERT_NONE, # https://stackoverflow.com/q/43122033/1874170
check_hostname=False,
server_hostname=hostname)
return sslSocket.getpeercert()
if __name__ == "__main__":
import sys
pprint(__main__(*(sys.argv[1:] or ['python.neverssl.com'])))
What am I missing?
Is it possible for Python to retrieve this information without external native code such as OpenSSL?
If there are any 3rd-party libraries that are capable of retrieving this information and don't require native code, how do they do it?