Leggere un certificato peer TLS attraverso un proxy HTTP in Python
Usate il supporto tunnel di HTTPConnection di Python prima di avvolgere il socket in un contesto SSL che convalida.
ssl.get_server_certificate non negozia un proxy HTTP. Stabilite prima il tunnel, poi eseguite TLS con il nome host di destinazione e ottenete il certificato peer.
Per un proxy HTTP senza autenticazione, usando host e porta di un candidato dall'elenco di proxy HTTP:
from contextlib import closing
import http.client
import ssl
hostname = "example.com"
context = ssl.create_default_context()
with closing(http.client.HTTPConnection(
"proxy.example.net", 8080, timeout=10
)) as connection:
connection.set_tunnel(hostname, 443)
connection.connect()
with context.wrap_socket(
connection.sock, server_hostname=hostname
) as tls:
certificate_der = tls.getpeercert(binary_form=True)
certificate_pem = ssl.DER_cert_to_PEM_cert(certificate_der)
HTTPConnection gestisce la richiesta CONNECT e la sua risposta. Il contesto SSL verifica poi la catena e l'identità della destinazione prima che il certificato venga restituito. Per questo handshake non serve alcuna HTTP GET verso la destinazione.
Se l'ambiente usa una CA privata approvata, caricate quella CA nel contesto invece di disattivare la verifica. Una catena rifiutata fa fallire l'handshake mostrato.
getpeercert restituisce il certificato foglia del peer, non una catena completa esportata automaticamente. Con un'intercettazione TLS attendibile, il certificato peer può essere il certificato generato dall'intermediario per questo nome host. Conservate questa distinzione quando lo confrontate con un certificato osservato attraverso un'altra rotta.