2010-04-13 9 views
5

Estoy tratando de usar HTTPSConnection de httplib para la validación del cliente, utilizando un certificado PKCS # 12. Sé que el certificado es bueno, ya que puedo conectarme al servidor usándolo en MSIE y Firefox.Error al utilizar HTTPSConnection de httlib con el certificado PKCS # 12

Aquí está mi función de conexión (el certificado incluye la clave privada). He Pared hacia abajo a lo básico:

def connect(self, cert_file, host, usrname, passwd): 
    self.cert_file = cert_file 
    self.host = host 

    self.conn = httplib.HTTPSConnection(host=self.host, port=self.port, key_file=cert_file, cert_file=cert_file) 

    self.conn.putrequest('GET', 'pathnet/,DanaInfo=200.222.1.1+') 
    self.conn.endheaders() 
    retCreateCon = self.conn.getresponse() 

    if is_verbose: 
     print "Create HTTPS connection, " + retCreateCon.read() 

(Nota: No hay comentarios en la ruta no modificable, por favor - estoy tratando de conseguir que esto funcione en primer lugar; Voy a hacer que sea muy tarde El camino codificado es correcto, ya que me conecté a él en MSIE y Firefox. Cambié la dirección IP de la publicación.

Cuando trato de ejecutar esto usando un certificado PKCS # 12 (un archivo .pfx), Recibo lo que parece ser un error de openSSL. Aquí está todo el rastreo de error:

 
    File "Usinghttplib_Test.py", line 175, in 
    t.connect(cert_file=opts["-keys"], host=host_name, usrname=opts["-username"], passwd=opts["-password"]) 
    File "Usinghttplib_Test.py", line 40, in connect 
    self.conn.endheaders() 
    File "c:\python26\lib\httplib.py", line 904, in endheaders 
    self._send_output() 
    File "c:\python26\lib\httplib.py", line 776, in _send_output 
    self.send(msg) 
    File "c:\python26\lib\httplib.py", line 735, in send 
    self.connect() 
    File "c:\python26\lib\httplib.py", line 1112, in connect 
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) 
    File "c:\python26\lib\ssl.py", line 350, in wrap_socket 
    suppress_ragged_eofs=suppress_ragged_eofs) 
    File "c:\python26\lib\ssl.py", line 113, in __init__ 
    cert_reqs, ssl_version, ca_certs) ssl.SSLError: [Errno 336265225] _ssl.c:337: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib 

Aviso, el error openSSL (la última entrada en la lista) señala "PEM lib", que me pareció extraño, ya que no estoy tratando de utilizar un certificado PEM.

Para las patadas, convertí el certificado PKCS # 12 a un certificado PEM, y ejecuté el mismo código usando que. En ese caso, no recibí ningún error, se me solicitó ingresar la frase de contraseña de PEM y el código intentó llegar al servidor. (Recibí la respuesta "El servicio no está disponible. Vuelva a intentarlo más tarde", pero creo que eso se debe a que el servidor no acepta el certificado PEM. No puedo conectar Firefox al servidor con el certificado PEM cualquiera.)

¿Se supone que HTTPSConnection de httplib es compatible con los certificados PCKS # 12? (Es decir, archivos pfx). Si es así, ¿por qué parece que openSSL está intentando cargarlo dentro de la lib de PEM? ¿Estoy haciendo todo mal?

Cualquier consejo es bienvenido.

EDIT: el archivo de certificado contiene tanto el certificado como la clave privada, por lo que proporciono el mismo nombre de archivo para los parámetros key_file y cert_file de HTTPSConnection.

Respuesta

4

En la lista de correo de openSSL, conversé con Mounir Idrassi. Señaló que openSSL admite archivos PKCS # 12 y, en función del mensaje de error que estoy recibiendo, parece que httplib llama a la función incorrecta para cargar la clave.

En sus palabras:.

"En cuanto al error que está recibiendo, parece que el módulo Phython que está utilizando está llamando SSL_CTX_use_PrivateKey_file dándole el PKCS # 12 nombre de archivo Esto no hace porque SSL_CTX_use_PrivateKey_file sólo acepta dos formatos: SSL_FILETYPE_PEM y SSL_FILETYPE_ASN1. "

(estoy dando httplib el nombre del archivo PKCS # 12 como archivo de claves, ya que este formato de archivo incluye tanto el certificado y la clave privada en el mismo archivo.)

"Con el fin de corregir esto, tener dos soluciones: - Alimente el módulo python con la clave privada en un archivo PEM - O modifique el código fuente de este módulo python para usar las funciones PKCS # 12 que mencioné anteriormente para extraer la clave privada como un EVP_PKEY y luego llame a SSL_use_PrivateKey en lugar de SSL_CTX_use_PrivateKey_file, junto con SSL_use_certificate para configurar el certificado asociado."

(probé la primera y no era capaz de conseguir que funcione no significa necesariamente que no va a funcionar;. Sólo que yo no era capaz de hacerlo.)

4

Esto no es sorprendente . Los documentos de referencia de la biblioteca de Python son bastante claras sobre esto de http://docs.python.org/library/httplib.html:.

clase httplib HTTPSConnection (host [, el puerto [, key_file [, cert_file [, estricta [, tiempo de espera [, source_address]]]. ]]])

Una subclase de HTTPConnection que usa SSL para la comunicación con servidores seguros. El puerto predeterminado es 443. key_file es el nombre de un archivo PEM formateado que contiene su clave privada. cert_file es un PEM formateado archivo de cadena de certificado.

+0

+1 para RTFM. ¿Dónde estabas el año pasado cuando estaba trabajando en esto? :) –

+0

Hola Remi, estuve un poco lento ;-) - Soy bastante nuevo en SO. Acabo de encontrar su publicación buscando en una cadena de error similar. Resulta que acababa de destrozar el orden de los argumentos en algún punto a lo largo de la cadena de llamadas y nunca pasó la ruta de la clave en httplib. – Blairo

Cuestiones relacionadas