[Twisted-Python] TCP startTLS() negotiation

Kyle George kgeorge at tcpsoft.com
Sat Aug 15 10:49:19 MDT 2009


I've noticed some behavior when negotiating TLS using startTLS().  I'm 
starting TLS on both sides of the connection at the same time to validate 
peer certificates using a custom callback.  If I call startTLS() without 
any subsequent writes to the socket the negotiation never completes. 
However, if I write data immediately post startTLS() the negotiation (and 
the callback to the OpenSSL verify callback) is successful.  But I don't 
want to do this because I want to wait until verification to proceed with 
communicating on the channel.  So I traced through tcp.py and noticed that 
in Connection.startTLS() reads and writes are stopped while the 
negotiation is taking place.  However, only reading is reenabled 
afterwards.  I suppose this is why doing a write unblocks the connection. 
When I do something like this in my code I don't have to make a write:

self.transport.startTLS(SSLContextFactory(...))
self.transport.startWriting()

The context factory makes its own SSL.Context very similar to _sslverify, 
but with a callback I can hook for verification.

So the question is, why is reading reenabled but not writing?  When I 
apply the patch below it works.

This is on Python 2.6.2, Twisted 8.2.0, pyOpenSSL-0.9-py2.6, win32.

Index: twisted/internet/tcp.py
===================================================================
--- twisted/internet/tcp.py     (revision 27226)
+++ twisted/internet/tcp.py     (working copy)
@@ -401,6 +401,7 @@
              self._startTLS()
              self.socket = SSL.Connection(ctx.getContext(), self.socket)
              self.fileno = self.socket.fileno
+            self.startWriting()
              self.startReading()
              return True

-- 
Kyle George




More information about the Twisted-Python mailing list