ssl.get_server_certificate não negocia um proxy HTTP. Estabeleça primeiro o túnel, depois execute TLS com o nome de host de destino e obtenha o certificado do par.

Para um proxy HTTP sem autenticação, usando o host e a porta de um candidato da lista de proxies 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 trata o pedido CONNECT e a sua resposta. O contexto SSL verifica depois a cadeia e a identidade do destino antes de o certificado ser devolvido. Não é necessário qualquer HTTP GET ao destino para este handshake.

Se o ambiente usar uma AC privada aprovada, carregue essa AC no contexto em vez de desativar a verificação. Uma cadeia rejeitada faz falhar o handshake mostrado.

getpeercert devolve o certificado folha do par, não uma cadeia completa exportada automaticamente. Com interceção TLS de confiança, o certificado do par pode ser o certificado gerado pelo intermediário para este nome de host. Preserve essa distinção ao compará-lo com um certificado observado por outra rota.

Artigos relacionados