Obtain Ceritificate Information from Invalid or Self-Signed Certificate in Python

Kenneth Buckler kenneth.buckler at gmail.com
Mon Apr 3 09:49:45 EDT 2017


I'm working on a Python 2.7.13 (Win x64) script to verify SSL certificates,
and alert for problems. Specifically, I'm looking to return the date the
cert expires or did expire. However, I'm running into an issue where the
script will return information only if the certificate is valid.

If the certificate is invalid, I receive a CERTIFICATE_VERIFY_FAILED SSL
error. Normally I would simply use a try/catch when the error is raised and
just alert that the cert is invalid, but the issue here is that the I need
the actual date the certificate expired, or in some cases the cert will be
a self-signed cert, which will be acceptable UNLESS the cert is expired.
I'm dealing with an organization that has thousands of certs, so adding
every single self signed cert to the cert store locally won't be an option.

Per https://docs.python.org/2/library/ssl.html I tried to use
conn._https_verify_certificates(enable=False) to disable certificate
validation, but get an error that the attribute _https_verify_certificates
doesn't exist.

Here is my code so far. I'm sure I'm missing something obvious. Surely
Python can pull the SSL certificate without validating it, right?

import socketimport ssl
def ssl_expiry_datetime(hostname):
    ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'

    context = ssl.create_default_context()
    conn = context.wrap_socket(
        socket.socket(socket.AF_INET),
        server_hostname=hostname,
    )
    # 3 second timeout because Lambda has runtime limitations
    conn.settimeout(3.0)
    #conn._https_verify_certificates(enable=False)
    conn.connect((hostname, 443))
    ssl_info = conn.getpeercert()
    # parse the string from the certificate into a Python datetime object
    return ['notAfter']

myhost = 'www.google.com'
print ssl_expiry_datetime(myhost)

Thanks!

Ken


More information about the Python-list mailing list