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

Adi Roiban adi at roiban.ro
Wed Jun 13 08:44:22 EDT 2012


On 13 June 2012 14:15,  <exarkun at twistedmatrix.com> wrote:
> On 10:39 am, adi at roiban.ro wrote:
>>Hi,
>>
>>I work at an experimental FTPS implementation for twisted.protocol.ftp
>>
>>I use the following code for checking that the transport has TLS
>>started and to get the client certificate for certificate based
>>authentication:
>>
>>    @property
>>    def is_ftps_command_active(self):
>>        '''Return `True` if current command connection is using SSL.'''
>>        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.

I am still new to Twisted. For me the transport looks like it has some
kind sorcery attached since getPeerCertificate is not listed by
dir(self.transport)

Not sure what I got here :)

(Pdb) self.transport.getPeerCertificate()
<X509 object at 0x9fc5af0>
(Pdb) ISSLTransport.providedBy(self.transport)
False
(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
>>connection
>>        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: https://github.com/chevah/txftps/tree/master/txftps
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:
https://github.com/chevah/txftps/blob/master/txftps/ssl.py


-- 
Adi Roiban



More information about the Twisted-Python mailing list