r1 - 29 Nov 2004 - 11:10:42 - HeikkiToivonenYou are here: OSAF >  Journal Web  >  ContributorNotes > HeikkiToivonenNotes > HeikkiToivonen20041129

Twisted + M2Crypto Proof of concept

Over the Thanksgiving weekend I gave some more thought to doing SSL in memory with OpenSSL and letting Twisted take care of the networking. I posted a question to openssl-users, and got a reply which pointed me to the right direction (best example is ssltest.c). Basically I need to make a new BIO pair with an SSL filter BIO, and whenever Twisted wants to send data over the network, I feed it to the SSL filter BIO, read it from the "network" end BIO, and pass it on to Twisted. And do the reverse when Twisted gives me the encrypted data from the network. So something like this:

class MyProtocolWrapper(ProtocolWrapper):
    def __init__(self, factory, wrappedProtocol):
        ProtocolWrapper.__init__(self, factory, wrappedProtocol)

        # wrappedProtocol == client instance
        # factory.wrappedFactory == client factory

        # bio pair
        self.ibio = m2.bio_new(m2.bio_s_bio())
        m2.bio_set_write_buf_size(self.ibio, 4096)
        self.nbio = m2.bio_new(m2.bio_s_bio())
        m2.bio_set_write_buf_size(self.nbio, 4096)
        m2.bio_make_bio_pair(self.ibio, self.nbio)

        # SSL filter
        self.sslbio = m2.bio_new(m2.bio_f_ssl())
        
        # XXX need to get context from client or client factory
        self.ctx = Context()
        self.ssl = m2.ssl_new(self.ctx.ctx)

        # XXX need to do this later        
        m2.ssl_set_connect_state(self.ssl)#client
        m2.ssl_set_bio(self.ssl, self.ibio, self.ibio)
        m2.bio_set_ssl(self.sslbio, self.ssl, 1)

    def write(self, data):
        m2.bio_write(self.sslbio, data)
        pending = m2.bio_ctrl_pending(self.nbio)
        sdata = m2.bio_read(self.nbio, pending)
        ProtocolWrapper.write(self, sdata)

    def dataReceived(self, data):
        m2.bio_write(self.nbio, data)
        pending = m2.bio_ctrl_pending(self.sslbio)
        cdata = m2.bio_read(self.sslbio, pending)
        ProtocolWrapper.dataReceived(self, cdata)

Now, the above example won't work exactly like that, because reads and writes may return a value that indicates you should retry the operation, and you may need to do writes during dataReceived etc., but that is the basic principle. What remains to be done is the robust framework to work around this complexity.

Breaking the connection, dealing with SSL errors are also to do items.

-- HeikkiToivonen - 29 Nov 2004

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r1 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.