ssl.get_server_certificate nu negociază un proxy HTTP. Stabiliți mai întâi tunelul, apoi efectuați TLS cu numele de gazdă al destinației și obțineți certificatul de peer.

Pentru un proxy HTTP fără autentificare, folosind gazda și portul unui candidat din lista de proxy-uri 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 gestionează cererea CONNECT și răspunsul acesteia. Apoi contextul SSL verifică lanțul și identitatea destinației înainte ca certificatul să fie returnat. Nu este necesar niciun HTTP GET către destinație pentru acest handshake.

Dacă mediul folosește o CA privată aprobată, încărcați acea CA în context în loc să dezactivați verificarea. Un lanț respins face ca handshake-ul afișat să eșueze.

getpeercert returnează certificatul frunză al peer-ului, nu un lanț complet exportat automat. Cu interceptare TLS de încredere, certificatul de peer poate fi certificatul generat de intermediar pentru acest nume de gazdă. Păstrați această distincție când îl comparați cu un certificat observat pe o altă rută.

Articole similare