Em Python como em outras linguagens, todo meio de comunicação via rede utiliza basicamente socket em seu nível mais baixo para prover essa comunicação, seja o meio de comunicação SOAP, rpc, http, etc.
Algumas vezes estes serviços externos fornecem a possibilidade de utilização de canais seguros para comunicação (ssl). Em alguns casos o serviço a ser utilizado pode até mesmo obrigar o uso de comunicação segura, para isso precisamos utilizar socket + ssl. Dependendo da necessidade do projeto pode ser necessário utilizar também um certificado digital juntamente com a conexão ssl como forma de autenticação.
Para utilizar comunicação segura o módulo 'socket' prove a função 'ssl', que de maneira simples executa a comunicação com o serviço desejado via ssl. Essa função também pode receber dois parâmetros , 'key_file' e 'cert_file' respectivamente o 'path' do arquivo PEM para a chave privada e o 'path' para o arquivo PEM do certificado.
Uma assinatura digital geralmente é um arquivo binário no formato 'pkcs12' com a extensão '.pfx', sendo assim precisamos abrir esse arquivo e retirar as duas informações que o 'ssl' precisa (key_file, cer_file) e salvar nos arquivos com o formato PEM. Para isso utilizamos openssl e pyopenssl, 'bindings' para python da 'lib' 'openssl'.
Com os módulos instalados, vamos abrir o certificado no formato binário, transformar no objeto 'pkcs12' e então retirar as informações do certificado e da chave privada para em seguida salvar cada um em arquivo separado.
Alguns certificados podem estar codificados sendo necessário informar a frase para decodificação, para tal temos o parâmetro 'passphrase', se não for preciso é só não informar o parâmetro como no exemplo abaixo.
from OpenSSL import crypto
# Lendo o arquivo pfx no formato pkcs12 como binario
pkcs12 = crypto.load_pkcs12(open('certificado.pfx', 'rb').read(), 'passphrase')
# Retorna a string decodificado do certificado
cert_str = crypto.dump_certificate(crypto.FILETYPE_PEM, pkcs12.get_certificate())
# Retorna a string decodificado da chave privada
key_str = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkcs12.get_privatekey())
# Gravando a string no dicso
open('cert.pem', 'wb').write(cert_str)
# Gravando a string no dicso
open('key.ptm', 'wb').write(key_str)
Agora para finalizar basta efetuar a comunicação com o serviço desejado utilizando o modulo 'socket' e a função 'ssl' passando os parâmetros de chave e certificado:
proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxy.connect(('www.lzt.com.br', 80))
proxy_ssl = socket.ssl(proxy, 'key.pem', 'cert.pem')
Pronto! Com o objeto 'proxy' podemos fazer requisições a serviços que utilizem conexão 'ssl' com certificados digitais.