[Twisted-Python] client side cert?

glyph at divmod.com glyph at divmod.com
Wed May 2 01:15:18 EDT 2007


On 04:30 am, elicriffield at gmail.com wrote:
>I try to make the x590 object to feed to CertificateOptions from
>t.i.s.Certifcate.loadPEM() but it doesn't like it. I see nowhere in
>t.i.ssl to make a PKey object that t.i.s.CertificationOptions() wants.

>I've tried t.i.s.ContextFactory() but there is no options for
>requiring a client side cert.
>t.i.s.ClientContextFactory doesn't seem to have any options to tell it
>what cert to use on the client side either, or how to verify the
>server cert, I guess thats what t.i.s.CertificationOptions() is for
>but it doesn't seem to work as documented.

The "right" way to do this (and by "right" I mean the way I intended and 
used when I originally wrote this code, but never documented in any way) 
is by using the "PrivateCertificate" object, which represents a paired 
public/private key, and its (poorly named, and by the way did I mention 
it's undocumented) "options" method, which creates the 
CertificateOptions object for you.

I can see from your example that you're already expecting the key and 
certificate to be in the same PEM file (like everyone does) so it could 
be as easy as this:

    from twisted.internet.ssl import PrivateCertificate
    pc = PrivateCertificate.loadPEM(file('test.cert', r').read())
    ctxFactory = pc.options()

although if you want to verify client certificates, options() also 
takes, as varargs, a tuple of certificate authorities.  However, a 
private certificate can also fill the role of a public certificate, so 
you can do:

    ctxFactory = pc.options(pc)

to use a self-signed certificate as its own authority.

This context factory can be used either for client or server 
connections, as shown below.

If you are doing anything interesting with SSL, you might want to have a 
look at the source in the file twisted/internet/_sslverify.py, 
especially the other (undocumented) methods of PrivateCertificate, which 
implements a bit of CA functionality.
>Is there some great documentation out there about how to do this with
>twisted.internet.ssl that I'm missing?

Nope.  The documentation here is particularly thin, and to make matters 
work, there are certain operations that are unsupported due to bugs or 
non-wrapped functions in pyopenssl.

Please feel free to file a more specific documentation bug (and feel 
_double_ free to attach a patch) to add docstrings to _sslverify, and 
probably a separate bug to add an introductory document.

I'm a big fan of complete runnable examples, so here's something to get 
you started.  Hope that this helps:

--- cut here ---

from sys import stdout, argv

from twisted.python.filepath import FilePath
from twisted.python.log import startLogging

from twisted.internet.protocol import Protocol, Factory, ClientFactory

from twisted.internet import reactor
from twisted.internet.ssl import PrivateCertificate

class MyProto(Protocol):
    def connectionMade(self):
        self.transport.write(self.factory.stuff)
    def dataReceived(self, data):
        stdout.write('Received %r\n' % (data,))

theCert = PrivateCertificate.loadPEM(file('server.pem','r').read())
theOptions = theCert.options(theCert)

def server():
    f = Factory()
    f.stuff = 'hello, client'
    f.protocol = MyProto
    reactor.listenSSL(7080, f, theOptions)

def client():
    f = ClientFactory()
    f.stuff = 'hello, server'
    f.protocol = MyProto
    reactor.connectSSL('localhost', 7080, f, theOptions)

def main():
    startLogging(stdout)
    if argv[1] == 'server':
        server()
    else:
        client()
    reactor.run()

if __name__ == '__main__':
    main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20070502/0661da0e/attachment.htm 


More information about the Twisted-Python mailing list