TLS-vastapuolen varmenteen lukeminen HTTP-välityspalvelimen kautta Pythonissa
Käytä Pythonin HTTPConnectionin tunnelitukea ennen kuin käärit socketin validoivaan SSL-kontekstiin.
ssl.get_server_certificate ei neuvottele HTTP-välityspalvelimen kanssa. Muodosta ensin tunneli, tee sitten TLS kohdeisäntänimellä ja hae vastapuolen varmenne.
Todentamattomalle HTTP-välityspalvelimelle käyttäen HTTP-välityspalvelinluettelon ehdokkaan isäntää ja porttia:
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 hoitaa CONNECT-pyynnön ja sen vastauksen. Sen jälkeen SSL-konteksti tarkistaa ketjun ja kohteen identiteetin ennen varmenteen palauttamista. Tähän kättelyyn ei tarvita HTTP GET -pyyntöä kohteeseen.
Jos ympäristö käyttää hyväksyttyä yksityistä CA:ta, lataa se kontekstiin sen sijaan, että poistaisit tarkistuksen käytöstä. Hylätty ketju saa näytetyn kättelyn epäonnistumaan.
getpeercert palauttaa vastapuolen lehtivarmenteen, ei automaattisesti vietyä täydellistä ketjua. Luotetussa TLS-salakuuntelussa vastapuolen varmenne voi olla välittäjän tälle isäntänimelle luoma varmenne. Säilytä tämä ero, kun vertaat sitä toista reittiä havaittuun varmenteeseen.