[Twisted-Python] ssl.py patch + example client /w server certificate verify
    Clark C. Evans 
    cce at clarkevans.com
       
    Tue Mar 25 16:04:10 MST 2003
    
    
  
With some help from etrepum (Bob Ippolito), the example is smaller,
and it even includes using POST.   Thanks Bob.
    from twisted.internet import reactor, ssl
    from twisted.web import client
    import urllib
    
    HOST = 'localhost'; PORT = 8443
    serverCertificate = file("server.crt").read()
    
    def verifyCert(cert):
        return ssl.dumpCertificate(cert) == serverCertificate
    
    def getdata():
        postdata = urllib.urlencode({'some': 'argument', 'another': 'arg'})
        headers  = {"Content-type":"application/x-www-form-urlencoded"}
        context  = ssl.DefaultOpenSSLContextFactory(
                      "client.key","client.crt",
                      verifyCallback = verifyCert)
        factory = client.HTTPClientFactory(HOST, "/some/path", "POST",
                                    postdata,  headers )
        reactor.connectSSL(HOST, PORT, factory, context)
        return factory.deferred
    
    def result(data): print data
    
    if __name__ == '__main__':
        reactor.callLater(5, reactor.stop)
        deferred = getdata()
        deferred.addCallback(result)
        reactor.run()
Ooh, this still requires the following patch to twisted.internet.ssl
--- 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