Getting certificate chain with Python 3.3 SSL module

后端 未结 3 867
萌比男神i
萌比男神i 2021-01-12 04:53

I can get the standard certificate information for an SSL connection in Python 3.3 via the getpeercert() method on the SSL socket. However, it doesn\'t seem to provide the c

3条回答
  •  孤街浪徒
    2021-01-12 05:46

    Thanks to the contributing answer by Aleksi, I found a bug/feature request that already requested this very thing: http://bugs.python.org/issue18233. Though the changes haven't been finalized, yet, they do have a patch that makes this available:

    This is the test code which I've stolen from some forgotten source and reassembled:

    import socket
    
    from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23
    from ssl import SSLContext  # Modern SSL?
    from ssl import HAS_SNI  # Has SNI?
    
    from pprint import pprint
    
    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                        ca_certs=None, server_hostname=None,
                        ssl_version=None):
        context = SSLContext(ssl_version)
        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 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, context.wrap_socket(sock, server_hostname=server_hostname))
    
        return (context, context.wrap_socket(sock))
    
    hostname = 'www.google.com'
    print("Hostname: %s" % (hostname))
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((hostname, 443))
    
    (context, ssl_socket) = ssl_wrap_socket(s,
                                           ssl_version=2, 
                                           cert_reqs=2, 
                                           ca_certs='/usr/local/lib/python3.3/dist-packages/requests/cacert.pem', 
                                           server_hostname=hostname)
    
    pprint(ssl_socket.getpeercertchain())
    
    s.close()
    

    Output:

    Hostname: www.google.com
    ({'issuer': ((('countryName', 'US'),),
                 (('organizationName', 'Google Inc'),),
                 (('commonName', 'Google Internet Authority G2'),)),
      'notAfter': 'Sep 11 11:04:38 2014 GMT',
      'notBefore': 'Sep 11 11:04:38 2013 GMT',
      'serialNumber': '50C71E48BCC50676',
      'subject': ((('countryName', 'US'),),
                  (('stateOrProvinceName', 'California'),),
                  (('localityName', 'Mountain View'),),
                  (('organizationName', 'Google Inc'),),
                  (('commonName', 'www.google.com'),)),
      'subjectAltName': (('DNS', 'www.google.com'),),
      'version': 3},
     {'issuer': ((('countryName', 'US'),),
                 (('organizationName', 'GeoTrust Inc.'),),
                 (('commonName', 'GeoTrust Global CA'),)),
      'notAfter': 'Apr  4 15:15:55 2015 GMT',
      'notBefore': 'Apr  5 15:15:55 2013 GMT',
      'serialNumber': '023A69',
      'subject': ((('countryName', 'US'),),
                  (('organizationName', 'Google Inc'),),
                  (('commonName', 'Google Internet Authority G2'),)),
      'version': 3},
     {'issuer': ((('countryName', 'US'),),
                 (('organizationName', 'Equifax'),),
                 (('organizationalUnitName',
                   'Equifax Secure Certificate Authority'),)),
      'notAfter': 'Aug 21 04:00:00 2018 GMT',
      'notBefore': 'May 21 04:00:00 2002 GMT',
      'serialNumber': '12BBE6',
      'subject': ((('countryName', 'US'),),
                  (('organizationName', 'GeoTrust Inc.'),),
                  (('commonName', 'GeoTrust Global CA'),)),
      'version': 3},
     {'issuer': ((('countryName', 'US'),),
                 (('organizationName', 'Equifax'),),
                 (('organizationalUnitName',
                   'Equifax Secure Certificate Authority'),)),
      'notAfter': 'Aug 22 16:41:51 2018 GMT',
      'notBefore': 'Aug 22 16:41:51 1998 GMT',
      'serialNumber': '35DEF4CF',
      'subject': ((('countryName', 'US'),),
                  (('organizationName', 'Equifax'),),
                  (('organizationalUnitName',
                    'Equifax Secure Certificate Authority'),)),
      'version': 3})
    

提交回复
热议问题