[Twisted-Python] client side cert?
glyph at divmod.com
glyph at divmod.com
Tue May 1 23:15:18 MDT 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: </pipermail/twisted-python/attachments/20070502/0661da0e/attachment.html>
More information about the Twisted-Python
mailing list