2012-02-01 22 views
15

Sto scrivendo un'app che richiede l'installazione di un certificato nel browser client. Ho trovato questo nei documenti PyOpenSSL per l'oggetto "Contesto" ma non riesco a vedere nulla su come il callback dovrebbe convalidare il certificato, solo che dovrebbe, in qualche modo.Convalida dei certificati client in 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. 

sto dicendo l'oggetto contesto in cui la mia (auto firmato) chiavi sono (vedi sotto) quindi credo che non capisco il motivo per cui questo non è sufficiente per la libreria per verificare se il CERT presentato dal cliente è valido Cosa si dovrebbe fare in questa funzione di callback?

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() 

Caveat: Codifica per divertimento qui, def non un professionista, quindi se la mia Q rivela la mia zoppia totale, ingenuità e/o fondamentale mancanza di comprensione quando si tratta di SSL per favore non essere troppo ruvida!

Grazie :)

Roger

risposta

6

Nel OpenSSL documentation per set_verify(), la chiave che vi interessa è il codice di ritorno :

callback dovrebbe prendere cinque argomenti: A Oggetto Connection, un oggetto X509 e tre variabili integer, che sono a loro volta potenziali errori numero, profondità errore e codice di ritorno. la callback deve restituire true se la verifica passa e false altrimenti.

C'è aa esempio di lavoro completo che mostra più o meno quello che si vuole fare: When are client certificates verified?

In sostanza si può ignorare i primi 4 argomenti e basta controllare il valore del codice di ritorno nel quinto argomento come così:

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: ho fatto un altro cambiamento che è from OpenSSL.SSL import ... per semplificare il codice un po 'mentre stavo testando così non si ha il prefisso SSL. di fronte ad ogni simbolo di importazione.

Problemi correlati