2012-02-01 26 views
15

Estoy escribiendo una aplicación que requiere la instalación de un certificado en el navegador del cliente. Encontré esto en los documentos PyOpenSSL para el objeto "Contexto" pero no puedo ver nada sobre cómo se supone que la devolución de llamada valida el certificado, solo que de alguna manera debería hacerlo.Validación de certificados de cliente en PyOpenSSL

 
    set_verify(mode, callback) 
     Set the verification flags for this Context object to mode and 
     specify that callback should be used for verification callbacks. 
     mode should be one of VERIFY_NONE and VERIFY_PEER. If 
     VERIFY_PEER is used, mode can be OR:ed with 
     VERIFY_FAIL_IF_NO_PEER_CERT and VERIFY_CLIENT_ONCE to further 
     control the behaviour. callback should take five arguments: A 
     Connection object, an X509 object, and three integer variables, 
     which are in turn potential error number, error depth and return 
     code. callback should return true if verification passes and 
     false otherwise. 

estoy contando el objeto de contexto donde mi (auto firmado) teclas son (ver más abajo) así que supongo que no entiendo por qué eso no es suficiente para la biblioteca para comprobar si el certificado presentado por el cliente es válido ¿Qué debería uno hacer en esta función de devolución de llamada?

class SecureAJAXServer(PlainAJAXServer): 
    def __init__(self, server_address, HandlerClass): 
     BaseServer.__init__(self, server_address, HandlerClass) 
     ctx = SSL.Context(SSL.SSLv23_METHOD) 
     ctx.use_privatekey_file ('keys/server.key') 
     ctx.use_certificate_file('keys/server.crt') 
     ctx.set_session_id("My_experimental_AJAX_Server") 
     ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, callback_func) 
     self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type)) 
     self.server_bind() 
     self.server_activate() 

Advertencia: Codificación de diversión aquí, definitivamente no es un profesional por lo que si mi Q revela mi cojera total ingenuidad y/o la falta de comprensión fundamental a la hora de SSL por favor, no ser demasiado duro!

Gracias :)

Roger

Respuesta

6

En el OpenSSL documentation para set_verify(), la llave que lo que importa es el código de retorno :

de devolución de llamada debe tener cinco argumentos: Un Objeto de conexión, un objeto X509 y tres variables enteras, que a su vez son un error potencial número, profundidad de error y código de retorno. la devolución de llamada debe devolver verdadero si pasa la verificación y de lo contrario es falso.

Hay aa ejemplo de trabajo completo que muestre más o menos lo que quiere hacer: When are client certificates verified?

Esencialmente, usted puede pasar por alto los primeros 4 argumentos y simplemente comprobar el valor del código de retorno en el quinto argumento como por lo que:

from OpenSSL.SSL import Context, Connection, SSLv23_METHOD 
from OpenSSL.SSL import VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE 

class SecureAJAXServer(BaseServer): 
    def verify_callback(connection, x509, errnum, errdepth, ok): 
     if not ok: 
      print "Bad Certs" 
     else: 
      print "Certs are fine" 
     return ok 

    def __init__(self, server_address, HandlerClass): 
     BaseServer.__init__(self, server_address, HandlerClass) 
     ctx = Context(SSLv23_METHOD) 
     ctx.use_privatekey_file ('keys/server.key') 
     ctx.use_certificate_file('keys/server.crt') 
     ctx.set_session_id("My_experimental_AJAX_Server") 
     ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE, verify_callback) 
     self.socket = Connection(ctx, socket.socket(self.address_family, self.socket_type)) 
     self.server_bind() 
     self.server_activate() 

Nota: me hizo otro cambio que es from OpenSSL.SSL import ... para simplificar su código un poco mientras estaba probando así que usted no tiene el prefijo SSL. delante de cada símbolo de importación.

Cuestiones relacionadas