From: Sebastian G. <seb...@gm...> - 2008-09-17 18:01:02
|
I'm building a ssl tcp server using the code below. However I'm unsure about how to actually verify the client's cert. 50 class SSLTCPServer(TCPServer): 51 keyFile = "sslcert/server.key" 52 certFile = "sslcert/server.crt" 53 def __init__(self, server_address, RequestHandlerClass): 54 ctx = SSL.Context(SSL.SSLv23_METHOD) 55 ctx.use_privatekey_file(self.keyFile) 56 ctx.use_certificate_file(self.certFile) 57 ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, self._verify) 58 ctx.set_verify_depth(10) 59 ctx.set_session_id('DFS') 60 61 self.server_address = server_address 62 self.RequestHandlerClass = RequestHandlerClass 63 self.socket = socket.socket(self.address_family, self.socket_type) 64 self.socket = SSL.Connection(ctx, self.socket) 65 self.socket.bind(self.server_address) 66 self.socket.listen(self.request_queue_size) 67 68 def _verify(self, conn, cert, errno, depth, retcode): 69 return not cert.has_expired() and cert.get_issuer().organizationName == 'DFS' Anyone got an idea about how to actually build the _verify method? Thanks in advance, Seb |
From: Jean-Paul C. <ex...@di...> - 2008-09-17 18:29:57
|
On Wed, 17 Sep 2008 20:01:30 +0200, Sebastian Greatful <seb...@gm...> wrote: >I'm building a ssl tcp server using the code below. However I'm unsure about >how to actually verify the client's cert. > >50 class SSLTCPServer(TCPServer): > > 51 keyFile = "sslcert/server.key" > > 52 certFile = "sslcert/server.crt" > > 53 def __init__(self, server_address, RequestHandlerClass): > > 54 ctx = SSL.Context(SSL.SSLv23_METHOD) > > 55 ctx.use_privatekey_file(self.keyFile) > > 56 ctx.use_certificate_file(self.certFile) > > 57 ctx.set_verify(SSL.VERIFY_PEER | >SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, self._verify) > > 58 ctx.set_verify_depth(10) > > 59 ctx.set_session_id('DFS') > > 60 > > 61 self.server_address = server_address > > 62 self.RequestHandlerClass = RequestHandlerClass > > 63 self.socket = socket.socket(self.address_family, >self.socket_type) > > 64 self.socket = SSL.Connection(ctx, self.socket) > > 65 self.socket.bind(self.server_address) > > 66 self.socket.listen(self.request_queue_size) > > 67 > > 68 def _verify(self, conn, cert, errno, depth, retcode): > > 69 return not cert.has_expired() and >cert.get_issuer().organizationName == 'DFS' > >Anyone got an idea about how to actually build the _verify method? > If you want to make sure the client's certificate is signed by a particular key which your server has, then you should specify that key's corresponding certificate as a trusted CA certificate (with a method of the context object, perhaps load_verify_locations, though there are a bunch of functions which do similar things, the correct one for you may depend on some other factors). Then, make sure you respect OpenSSL's decision in the verify callback. This is given by the `retcode` parameter. If the client's certificate is not signed by a certificate you told the context object to consider a trusted CA certificate, `retcode` will be false. You can add whatever additional checks you want on top of that (ie, for the subject's name or what have you) but if `retcode` is false, you should return false from the verify function. This includes things like expiration checking, so you don't need to do that. Jean-Paul |
From: Sebastian G. <seb...@gm...> - 2008-09-17 19:27:21
|
-----Oprindelig meddelelse----- Fra: pyo...@li... [mailto:pyo...@li...] På vegne af Jean-Paul Calderone Sendt: 17. september 2008 20:30 Til: pyo...@li... Emne: Re: [pyOpenSSL] How can I verify client that the client is signed by me? <snip /> >If you want to make sure the client's certificate is signed by a particular >key which your server has, then you should specify that key's corresponding >certificate as a trusted CA certificate (with a method of the context object, >perhaps load_verify_locations, though there are a bunch of functions which >do similar things, the correct one for you may depend on some other factors). > Thats exactly what I'm trying to do. However I can't make the load_verify_locations Function work. Executing the code below I get (<class exceptions.AttributeError at 0x2b891d0596b0>, <exceptions.AttributeError instance at 0x2b891ed9d758>, <traceback object at 0x2b891ed9d830>) 71 def _verify(self, conn, cert, errno, depth, retcode): 72 try: 73 cert.load_verify_locations(self.caFile) 74 except: 75 print sys.exc_info() >Then, make sure you respect OpenSSL's decision in the verify callback. This >is given by the `retcode` parameter. If the client's certificate is not >signed by a certificate you told the context object to consider a trusted CA >certificate, `retcode` will be false. You can add whatever additional >checks you want on top of that (ie, for the subject's name or what have you) >but if `retcode` is false, you should return false from the verify function. I'd very much like to do so :) But does that mean that I should set it to something or check it or what? Best regards, Seb |
From: Sebastian G. <seb...@gm...> - 2008-09-17 19:44:20
|
I now execute load_verify_locations on the Context object, instead... doh! However I'm still very unsure about how to handle the retcode... all hints appreciated :) Best regards, Seb |
From: Jean-Paul C. <ex...@di...> - 2008-09-17 19:53:58
|
On Wed, 17 Sep 2008 21:44:51 +0200, Sebastian Greatful <seb...@gm...> wrote: >I now execute load_verify_locations on the Context object, instead... doh! > >However I'm still very unsure about how to handle the retcode... all hints >appreciated :) If it's false, return false from your verify callback. If it's true, either return true, or do whatever extra checks you want and return the result of them. Jean-Paul |
From: Sebastian G. <seb...@gm...> - 2008-09-17 20:17:50
|
>-----Oprindelig meddelelse----- >Fra: pyo...@li... [mailto:pyo...@li...] På >vegne af Jean-Paul Calderone >Sendt: 17. september 2008 21:54 >Til: pyo...@li... >Emne: Re: [pyOpenSSL] How can I verify client that the client is signed by me? >On Wed, 17 Sep 2008 21:44:51 +0200, Sebastian Greatful <seb...@gm...> wrote: >>I now execute load_verify_locations on the Context object, instead... doh! >> >>However I'm still very unsure about how to handle the retcode... all hints >>appreciated :) >If it's false, return false from your verify callback. If it's true, either >return true, or do whatever extra checks you want and return the result of >them. So basically I should just return it? Since I at the moment dont want to verify on other parameters... I the code is as below and I have used the following guide http://www.impetus.us/~rjmooney/projects/misc/clientcertauth.html to generate the cert's. However the retcode remains false. Even though the client's certificate really should be signed with the file referred to by caFile. Any ideas on where I go wrong? 50 class SSLTCPServer(TCPServer): 51 keyFile = "sslcert/server.key" 52 certFile = "sslcert/server.crt" 53 caFile = "sslcert/ca.crt" 54 def __init__(self, server_address, RequestHandlerClass): 55 ctx = SSL.Context(SSL.SSLv23_METHOD) 56 ctx.use_privatekey_file(self.keyFile) 57 ctx.use_certificate_file(self.certFile) 58 ctx.load_verify_locations(self.caFile) 59 ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, self._verify) 60 ctx.set_verify_depth(10) 61 ctx.set_session_id('DFS') 62 63 self.server_address = server_address 64 self.RequestHandlerClass = RequestHandlerClass 65 self.socket = socket.socket(self.address_family, self.socket_type) 66 self.socket = SSL.Connection(ctx, self.socket) 67 self.socket.bind(self.server_address) 68 self.socket.listen(self.request_queue_size) 69 70 def _verify(self, conn, cert, errno, depth, retcode): 71 return retcode |
From: Jean-Paul C. <ex...@di...> - 2008-09-17 20:40:57
|
On Wed, 17 Sep 2008 22:18:22 +0200, Sebastian Greatful <seb...@gm...> wrote: > [snip] > >Any ideas on where I go wrong? > >50 class SSLTCPServer(TCPServer): > 51 keyFile = "sslcert/server.key" > 52 certFile = "sslcert/server.crt" > 53 caFile = "sslcert/ca.crt" > 54 def __init__(self, server_address, RequestHandlerClass): > 55 ctx = SSL.Context(SSL.SSLv23_METHOD) > 56 ctx.use_privatekey_file(self.keyFile) > 57 ctx.use_certificate_file(self.certFile) > 58 ctx.load_verify_locations(self.caFile) > 59 ctx.set_verify(SSL.VERIFY_PEER | >SSL.VERIFY_FAIL_IF_NO_PEER_CERT | SSL.VERIFY_CLIENT_ONCE, self._verify) > 60 ctx.set_verify_depth(10) > 61 ctx.set_session_id('DFS') > 62 > 63 self.server_address = server_address > 64 self.RequestHandlerClass = RequestHandlerClass > 65 self.socket = socket.socket(self.address_family, >self.socket_type) > 66 self.socket = SSL.Connection(ctx, self.socket) > 67 self.socket.bind(self.server_address) > 68 self.socket.listen(self.request_queue_size) > 69 > 70 def _verify(self, conn, cert, errno, depth, retcode): > 71 return retcode > This isn't a complete example (and the line numbers would make it annoying to actually run if it were ;). A complete, minimal reproduction of the problem would make it easier to diagnose. Jean-Paul |
From: Sebastian G. <seb...@gm...> - 2008-09-17 20:51:09
|
<snip /> >This isn't a complete example (and the line numbers would make it annoying >to actually run if it were ;). A complete, minimal reproduction of the >problem would make it easier to diagnose. Sorry, I'm just copy pasting from vim. Server: http://paste.pocoo.org/show/85562/ FileServer: http://paste.pocoo.org/show/85561/ HttpServer: http://paste.pocoo.org/show/85563/ Httplib: http://paste.pocoo.org/show/85564/ Is that better? Just let me know how you want it. The actual project is a distributed filesystem with a http interface. In order for the project to run you need a running pyro-ns (pyro name server) The SSL part is in the "Server" I really appreciate the your help, thanks a lot Best regards, Seb |
From: Jean-Paul C. <ex...@di...> - 2008-09-17 21:01:56
|
On Wed, 17 Sep 2008 22:51:40 +0200, Sebastian Greatful <seb...@gm...> wrote: ><snip /> >>This isn't a complete example (and the line numbers would make it annoying >>to actually run if it were ;). A complete, minimal reproduction of the >>problem would make it easier to diagnose. > >Sorry, I'm just copy pasting from vim. > >Server: http://paste.pocoo.org/show/85562/ >FileServer: http://paste.pocoo.org/show/85561/ >HttpServer: http://paste.pocoo.org/show/85563/ >Httplib: http://paste.pocoo.org/show/85564/ > > >Is that better? Just let me know how you want it. > The client code is important too (since it's the thing supplying the certificate), as are the keys and certificates (since they determine what the connection is actually verifying). The HTTP parts probably aren't important since the failure is happening at the SSL layer, so the HTTP code probably never gets involved. If you can provide a file containing a server and a file containing a client such that when run the client connects to the server and the server fails to decide that the client's certificate is valid, that'd be best (basically, make it possible for me to be really lazy, so that I am inclined to work on this instead of on real work ;). Jean-Paul |
From: Sebastian G. <seb...@gm...> - 2008-09-18 07:53:33
|
Thanks to Jean-Paul I now know that the problem wasnt my code but rather my certificates. So the lesson is, remember to verify those certificates before using them. Best regards, Seb -----Oprindelig meddelelse----- Fra: pyo...@li... [mailto:pyo...@li...] På vegne af Jean-Paul Calderone Sendt: 17. september 2008 23:02 Til: pyo...@li... Emne: Re: [pyOpenSSL] How can I verify client that the client is signed by me? On Wed, 17 Sep 2008 22:51:40 +0200, Sebastian Greatful <seb...@gm...> wrote: ><snip /> >>This isn't a complete example (and the line numbers would make it annoying >>to actually run if it were ;). A complete, minimal reproduction of the >>problem would make it easier to diagnose. > >Sorry, I'm just copy pasting from vim. > >Server: http://paste.pocoo.org/show/85562/ >FileServer: http://paste.pocoo.org/show/85561/ >HttpServer: http://paste.pocoo.org/show/85563/ >Httplib: http://paste.pocoo.org/show/85564/ > > >Is that better? Just let me know how you want it. > The client code is important too (since it's the thing supplying the certificate), as are the keys and certificates (since they determine what the connection is actually verifying). The HTTP parts probably aren't important since the failure is happening at the SSL layer, so the HTTP code probably never gets involved. If you can provide a file containing a server and a file containing a client such that when run the client connects to the server and the server fails to decide that the client's certificate is valid, that'd be best (basically, make it possible for me to be really lazy, so that I am inclined to work on this instead of on real work ;). Jean-Paul ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ pyopenssl-list mailing list pyo...@li... https://lists.sourceforge.net/lists/listinfo/pyopenssl-list |