[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