2012-02-01 14 views
15

Piszę aplikację, która wymaga zainstalowania certyfikatu w przeglądarce klienta. Znalazłem to w dokumentach PyOpenSSL dla obiektu "Context", ale nie widzę nic o tym, w jaki sposób wywołanie zwrotne ma potwierdzić certyfikat, tylko że powinno, jakoś.Sprawdzanie poprawności certyfikatów klienta w 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. 

Mówię obiektu Context gdzie mój (self signed) klawisze (patrz poniżej), więc myślę, że nie rozumiem, dlaczego to nie wystarczy do biblioteki, aby sprawdzić, czy cert przedstawiony przez klienta jest poprawny. Co należy zrobić w tej funkcji zwrotnej?

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

Zastrzeżenie: Kodowanie dla zabawy tutaj, def nie pro więc jeśli mój Q ujawnia moje całkowite kalectwo, naiwności i/lub fundamentalny brak zrozumienia, jeśli chodzi o SSL proszę nie być zbyt niebezpieczne!

Dzięki :)

Roger

Odpowiedz

6

W OpenSSL documentation dla set_verify(), klucz, które dbają o to kod powrót:

zwrotna powinna trwać pięć argumentów: a Obiekt połączenia, obiekt X509 i trzy zmienne całkowite, które z kolei są potencjalnym błędemNumer, głębokość błędu i kod powrotu. oddzwonienie powinno zwrócić true , jeśli weryfikacja minie, a false w przeciwnym wypadku.

Jest aa pełny przykład roboczych, które pokazuje mniej więcej to, co chcesz zrobić: When are client certificates verified?

Zasadniczo można zignorować pierwsze 4 argumenty i po prostu sprawdzić wartość kodu powrotu w piątym argumentem jak tak:

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

Uwaga: zrobiłem jeszcze jedną zmianę, która jest from OpenSSL.SSL import ... uproszczenie kodu nieco podczas gdy ja testowałem go, więc nie mają SSL. prefiks przed każdym symbolem importu.

Powiązane problemy