[Twisted-Python] Detect SSL transport and get remote peer certificate in tcp.Server

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Wed Jun 13 09:13:35 EDT 2012

On 12:44 pm, adi at roiban.ro wrote:
>On 13 June 2012 14:15,  <exarkun at twistedmatrix.com> wrote:
>>On 10:39 am, adi at roiban.ro wrote:
>>>I work at an experimental FTPS implementation for 
>>>I use the following code for checking that the transport has TLS
>>>started and to get the client certificate for certificate based
>>>   @property
>>>   def is_ftps_command_active(self):
>>>       '''Return `True` if current command connection is using 
>>>       return isinstance(self.transport.socket, SSL.Connection)
>>Instead, check `ISSLTransport.providedBy(self.transport)`.
>>`ISSLTransport` comes from `twisted.internet.interfaces`.
>I can get the peer certificate, but
>ISSLTransport.providedBy(self.transport) returns False.

That sounds like a bug in the new TLS implementation, then. :/  Can you 
file a bug report?  Be sure to include how you set up the connection 
(connectSSL or startTLS or whatever).
>I am still new to Twisted. For me the transport looks like it has some
>kind sorcery attached since getPeerCertificate is not listed by
>Not sure what I got here :)

Yea.  There's some method proxying going on.

>(Pdb) self.transport.getPeerCertificate()
><X509 object at 0x9fc5af0>
>(Pdb) ISSLTransport.providedBy(self.transport)
>(Pdb) dir(self.transport)
>['__doc__', '__getattr__', '__implemented__', '__init__',
>'__module__', '__providedBy__', '__provides__', 'connected',
>'connectionLost', 'connectionMade', 'dataReceived', 'disconnecting',
>'factory', 'getHost', 'getPeer', 'logPrefix', 'loseConnection',
>'makeConnection', 'registerProducer', 'stopConsuming', 'transport',
>'unregisterProducer', 'wrappedProtocol', 'write', 'writeSequence']
>>>   def getPeerCertificate(self):
>>>       '''Return the peer certificate if remote peer is on a SSL
>>>       and has sent us a certificate.
>>>       Return `None` otherwise.
>>>       '''
>>>       if not hasattr(self.transport, 'socket'):
>>>           return None
>>>       if not self.is_ftps_command_active:
>>>           return None
>>>       return self.transport.socket.get_peer_certificate()
>>Heh. :)  Instead, use `transport.getPeerCertificate()`.
>>`getPeerCertificate` is a method specified by `ISSLTransport`.
>Thanks! :)
>I was able to get the peer certificate.
>The full code is here: 
>It uses twisted.internet.tcp.Server for FTP command channel and
>TLSMemoryBIOProtocol for data channel.
>Phil, you can take a look at how the context is configured.
>The context is defined here:
>Adi Roiban
>Twisted-Python mailing list
>Twisted-Python at twistedmatrix.com

More information about the Twisted-Python mailing list