2010-12-09 13 views
13

Necesito verificar que mi CA personalizada haya firmado un certificado. El uso de OpenSSL utilidades de línea de comandos que esto es fácil de hacer:¿Cómo verifico un certificado SSL en python?

# Custom CA file: ca-cert.pem 
# Cert signed by above CA: bob.cert 
$ openssl verify -CAfile test-ca-cert.pem bob.cert 
bob.cert: OK 

Pero tengo que hacer lo mismo en Python, y realmente no quieren llamar a utilidades de línea de comandos. Por lo que sé, M2Crypto es el contenedor de Python "más completo" para OpenSSL, ¡pero no puedo entender cómo lograr lo que hace la herramienta de línea de comandos!

Haciendo referencia a this question para saber cómo lograr esta misma tarea en código C, he podido llegar a la mitad. Los nombres de variable que elegí son los mismos que se usan en el código fuente para la utilidad de línea de comandos de verificación de openssl, vea openssl-xxx/apps/verify.c.

import M2Crypto as m2 
# Load the certificates 
cacert = m2.X509.load_cert('test-ca-cert.pem') # Create cert object from CA cert file 
bobcert = m2.X509.load_cert('bob.cert')  # Create cert object from Bob's cert file 
cert_ctx = m2.X509.X509_Store()    # Step 1 from referenced C code steps 
csc = m2.X509.X509_Store_Context(cert_ctx) # Step 2 & 5 
cert_ctx.add_cert(cacert)     # Step 3 
cert_ctx.add_cert(bobcert)     # ditto 
# Skip step 4 (no CRLs to add) 
# Step 5 is combined with step 2...I think. (X509_STORE_CTX_init: Python creates and 
# initialises an object in the same step) 
# Skip step 6? (can't find anything corresponding to 
# X509_STORE_CTX_set_purpose, not sure if we need to anyway???) 
# 
# It all falls apart at this point, as steps 7 and 8 don't have any corresponding 
# functions in M2Crypto -- I even grepped the entire source code of M2Crypto, and 
# neither of the following functions are present in it: 
# Step 7: X509_STORE_CTX_set_cert - Tell the context which certificate to validate. 
# Step 8: X509_verify_cert - Finally, validate it 

Así que estoy a mitad de camino, pero me parece que no puede conseguir realmente la validación hecho! ¿Me estoy perdiendo de algo? ¿Hay alguna otra función que debería usar de M2Crypto? ¿Debería estar buscando un contenedor de Python completamente diferente de OpenSSL? ¿Cómo puedo lograr esta tarea en Python?

Tenga en cuenta que estoy usando certificados para cifrar/descifrar ARCHIVOS, por lo que no estoy interesado en usar la verificación de certificado de par basado en la conexión SSL (que tiene already been answered), porque no tengo ninguna conexión SSL yendo.

+1

¿Hay alguna razón por la que no desee llamar a las utilidades de línea de comandos? Parece que podría ahorrarse un poco de dolor de cabeza ... – katrielalex

+2

Sí, esto es para software que se implementará en muchos sistemas operativos diferentes, nuevos y antiguos, grandes y pequeños, incluidos los sistemas potencialmente integrados (lo suficientemente grandes como para incluir Python en ellos)) Quiero la máxima portabilidad y el máximo rendimiento. No quiero hacer potencialmente miles de llamadas a la línea de comandos si es que puedo evitarlo.Un gran número de certificados están involucrados. – Nathan

+0

relacionado http://stackoverflow.com/q/2626792/4279 – jfs

Respuesta

-3

Como has dicho, OpenSSL requiere conexión

M2Crypto no tiene buena verificación

¿Qué hay de esta ingeniosa idea:

import os 
os.system('openssl verify -CAfile ../ca-cert.pem bob.cert') 

Su feo, pero funciona!

+3

Según la pregunta: "y realmente no quiero llamar a las utilidades de línea de comandos" –

-1

Puede utilizar el método desafortunadamente no documentado X509.verify para comprobar si el certificado se firmó con la clave privada de la CA. Como esto requiere OpenSSL de x509_verify en el fondo, estoy seguro de que esto también comprueba todos los parámetros (como vencimiento) correctamente:

from M2Crypto X509 

cert = X509.load_cert("certificate-filename") 

caCertificate = X509.load_cert("trusted-ca-filename") 
caPublic = caCertificate.get_pubkey() 

if cert.verify(caPublic) == 1: 
    # Certificate is okay! 
else: 
    # not okay 
+0

Usted está equivocado, consulte la fuente: http://goo.gl/ fRhou X509_verify comprueba solo la firma. – abbot

5

No se puede hacer esto con sencillo M2Crypto, ya que no se ajusta algunos de los requerida funciones. Una buena noticia es que si tiene SWIG instalado, puede envolverlo usted mismo y usarlo con el código M2Crypto. Hace algún tiempo, hice un módulo con algunas funciones adicionales y decidí publicarlo ahora, ya que realiza este tipo de validación. Puede verificarlo aquí: https://github.com/abbot/m2ext. Este es un ejemplo de cómo validar un certificado mediante este módulo:

import sys 
from m2ext import SSL 
from M2Crypto import X509 

print "Validating certificate %s using CApath %s" % (sys.argv[1], sys.argv[2]) 
cert = X509.load_cert(sys.argv[1]) 
ctx = SSL.Context() 
ctx.load_verify_locations(capath=sys.argv[2]) 
if ctx.validate_certificate(cert): 
    print "valid" 
else: 
    print "invalid" 

Desafortunadamente desarrollo M2Crypto parece ser estancadas (no hay problemas cerrados en seguimiento de errores en los últimos dos años) y el mantenedor fue haciendo caso omiso de mis errores y mensajes de correo electrónico con estos y algunos otros parches ...

+0

* Hay * problemas cerrados en el rastreador de errores en los últimos 2 años http://is.gd/iPhP6 (la URL de https://bugzilla.osafoundation.org es demasiado larga para el comentario). @Heikki Toivonen (el mantenedor) responde algunas preguntas sobre M2Crypto http://stackoverflow.com/questions/4403012/how-do-i-verify-an-ssl-certificate-in-python/4457189#4457189 – jfs

Cuestiones relacionadas