[Twisted-Python] Re: SSL + AMP

Nathan nathan.stocks at gmail.com
Mon Mar 24 16:53:05 EDT 2008


On Fri, Mar 21, 2008 at 2:56 PM, David Bolen <db3l.net at gmail.com> wrote:
>  I posted a while back a small sample of how to handle that for a
>  general Twisted protocol that might be of some help, or point you in
>  the right direction as well.
>
>  http://twistedmatrix.com/pipermail/twisted-python/2007-August/015935.html
>
>  (Note the followup messages that clarify an erroneous "False" left in
>  the original posted code)
>
>  This works fine with just normal CA/server/client certificates created
>  through the standard OpenSSL process and tools.

I've generated a CA file, some private keys (and their corresponding
CSR's and certificates), and incorporated chunks of code from the post
you linked to above (and fixed the "returning ok" bit), but I'm
running into the following error:

[('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert certificate
unknown'), ('SSL routines', 'SSL3_READ_BYTES', 'ssl handshake
failure')]

So close!  I wonder if this has something to do with the fact that my
two endpoints are both on localhost, and not on some domain name?
Just a stab in the dark.

Anyway, here's the debugging print statement info from the client side
(I scrubbed out personal info):

_verify (ok=1):
  subject: <X509Name object '/CN=MyCompany
CA/C=US/ST=Utah/L=MyCity/O=mycompany.com/emailAddress=operations at mycompany.com'>
  issuer: <X509Name object '/CN=MyCompany
CA/C=US/ST=Utah/L=MyCity/O=mycompany.com/emailAddress=operations at mycompany.com'>
  errnum 0, errdepth 1

_verify (ok=1):
  subject: <X509Name object
'/C=US/ST=Utah/O=mycompany.com/CN=controller/emailAddress=operations at mycompany.com'>
  issuer: <X509Name object '/CN=MyCompany
CA/C=US/ST=Utah/L=MyCity/O=mycompany.com/emailAddress=operations at mycompany.com'>
  errnum 0, errdepth 0

And here's the ssl code from the client (the only significant change I
made was the filenames):

class ClientContextFactory(ssl.ClientContextFactory):

   def _verify(self, connection, x509, errnum, errdepth, ok):
      print '_verify (ok=%d):' % ok
      print '  subject:', x509.get_subject()
      print '  issuer:', x509.get_issuer()
      print '  errnum %s, errdepth %d' % (errnum, errdepth)
      return ok

   def getContext(self):
      ctx = ssl.ClientContextFactory.getContext(self)
      ctx.use_certificate_file('ssl/private/nathanmonitor.cert')
      ctx.use_privatekey_file('ssl/private/nathanmonitor.key')
      ctx.load_verify_locations('ssl/ca-cert.pem')
      ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
                     self._verify)
      return ctx

ClientCreator(reactor, MonitorClientProtocol).connectSSL(
  'localhost', MONITOR_PORT, ClientContextFactory()).addCallback(
                        monitor_window.install_amp_client)


nathanmonitor.key is the private ssl key of my "monitor" client

ca-cert.pem is the custom CA certificate I made by following
http://sial.org/howto/openssl/ca/

nathanmonitor.cert is the ssl certificate of my "monitor" client
generated with my custom CA and a .csr of nathanmonitor.key


On the server side, the error output is pretty quiet:

_verify (ok=1):
subject:<X509Name object '/CN=MyCompany
CA/C=US/ST=Utah/L=MyCity/O=mycompany.com/emailAddress=operations at mycompany.com'>

...here's my server code (again, pretty much the same except for cert files)

class ServerContextFactory:
   def _verify(self, connection, x509, errnum, errdepth, ok):
      logging.info('_verify (ok=%d):' % ok)
      logging.info('  subject:%s' % x509.get_subject())
      logging.info('  issuer:', x509.get_issuer())
      logging.info('  errnum %s, errdepth %d' % (errnum, errdepth))
      return ok

   def getContext(self):
      """Create an SSL context."""
      ctx = SSL.Context(SSL.SSLv23_METHOD)
      ctx.use_certificate_file('ssl/private/controller.cert')
      ctx.use_privatekey_file('ssl/private/controller.key')
      ctx.load_client_ca('ssl/ca-cert.pem')
      ctx.load_verify_locations('ssl/ca-cert.pem')
      ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
                     self._verify)
      ctx.set_verify_depth(10)
      return ctx

reactor.listenSSL(MONITOR_PORT, monitor_factory, ServerContextFactory())


controller.key is the private ssl key of the "server"

ca-cert.pem is the same custom CA certificate file as used in the client.

controller.cert is the ssl certificate of the "server" generated with
my custom CA and a .csr of controller.key




More information about the Twisted-Python mailing list