[Twisted-Python] ssl.py patch + example client /w server certificate verify
Clark C. Evans
cce at clarkevans.com
Tue Mar 25 15:57:33 EST 2003
Howdy. Thanks to those who helped me get this bootstrapped, so that
others may find the task easier... here is an example of a client
which has its own certificate, and verifies a known client certificate.
from twisted.internet import reactor, protocol
from twisted.protocols import http
from twisted.internet import ssl
class Client(http.HTTPClient):
def connectionMade(self):
print 'Connected.'
self.sendCommand('GET', "/")
self.sendHeader('User-Agent', 'Twisted-Example')
self.endHeaders()
print 'Sent request.'
def handleResponse(self, data):
print 'Got response.'
#print data
def verifyCert(cert):
return ssl.dumpCertificate(cert) == file("server.crt").read()
def fetchURL():
print 'Connecting to.'
context = ssl.DefaultOpenSSLContextFactory(
"client.key","client.crt",
verifyCallback = verifyCert)
context.isClient = 1
factory = protocol.ClientFactory()
factory.protocol = Client
reactor.connectSSL('localhost', 8443, factory, context)
if __name__ == '__main__':
reactor.callLater(5,reactor.stop)
reactor.callLater(1,fetchURL)
reactor.run()
Anyway, it's not the prettiest... in particular, why is there a
separate class Default* ... could not this default behavior gone
into the shorter ssl.ContextFactory?
And... here is the patch to ssl.py
--- ssl.py.orig Tue Mar 25 13:44:40 2003
+++ ssl.py Tue Mar 25 15:32:15 2003
@@ -36,7 +36,7 @@
"""
# System imports
-from OpenSSL import SSL
+from OpenSSL import SSL, crypto
import socket
# sibling imports
@@ -55,20 +55,32 @@
"""Return a SSL.Context object. override in subclasses."""
raise NotImplementedError
+def dumpCertificate(cert, filetype = crypto.FILETYPE_PEM ):
+ ''' a helper to dump an incoming cert as a PEM '''
+ return crypto.dump_certificate(filetype, cert)
class DefaultOpenSSLContextFactory(ContextFactory):
def __init__(self, privateKeyFileName, certificateFileName,
- sslmethod=SSL.SSLv23_METHOD):
- self.privateKeyFileName = privateKeyFileName
+ sslmethod=SSL.SSLv23_METHOD, verifyCallback = None):
+ self.verifyCallback = (verifyCallback, )
+ self.privateKeyFileName = privateKeyFileName
self.certificateFileName = certificateFileName
self.sslmethod = sslmethod
self.cacheContext()
+
+ def verifyCertificate(self, conn, cert, errno, depth, retcode):
+ cb = self.verifyCallback[0]
+ if cb: return cb(cert)
+ return 1
+
def cacheContext(self):
ctx = SSL.Context(self.sslmethod)
ctx.use_certificate_file(self.certificateFileName)
ctx.use_privatekey_file(self.privateKeyFileName)
+ if self.verifyCallback[0]:
+ ctx.set_verify(SSL.VERIFY_PEER, self.verifyCertificate)
self._context = ctx
def __getstate__(self):
More information about the Twisted-Python
mailing list