Python tricks

Posted on 2018-10-03 in Trucs et astuces

Inspect TLS certificates with requests

Use the snippet below to capture and inspect the certificates of a distant site and its chain with requests.

import requests

HTTPResponse = requests.packages.urllib3.response.HTTPResponse
orig_HTTPResponse__init__ = HTTPResponse.__init__
def new_HTTPResponse__init__(self, *args, **kwargs):
    orig_HTTPResponse__init__(self, *args, **kwargs)
    try:
        self.peer_certificate = self._connection.peer_certificate
        self.peer_cert_chain = self._connection.peer_cert_chain
    except AttributeError:
        pass
HTTPResponse.__init__ = new_HTTPResponse__init__

HTTPAdapter = requests.adapters.HTTPAdapter
orig_HTTPAdapter_build_response = HTTPAdapter.build_response
def new_HTTPAdapter_build_response(self, request, resp):
    response = orig_HTTPAdapter_build_response(self, request, resp)
    try:
        response.peer_certificate = resp.peer_certificate
        response.peer_cert_chain = resp.peer_cert_chain
    except AttributeError:
        pass
    return response
HTTPAdapter.build_response = new_HTTPAdapter_build_response

HTTPSConnection = requests.packages.urllib3.connection.HTTPSConnection
orig_HTTPSConnection_connect = HTTPSConnection.connect
def new_HTTPSConnection_connect(self):
    orig_HTTPSConnection_connect(self)
    try:
        self.peer_certificate = self.sock.connection.get_peer_certificate()
        self.peer_cert_chain = self.sock.connection.get_peer_cert_chain()
    except AttributeError:
        pass
HTTPSConnection.connect = new_HTTPSConnection_connect


response = requests.get('https://www.jujens.eu')
response.peer_certificate.get_subject()
response.peer_cert_chain

response.peer_cert_chain[0].get_subject()

Sources: https://stackoverflow.com/a/52072170 and https://stackoverflow.com/a/47931103