[Twisted-Python] Determine TLS version from within request handler ? (twisted web)

I'm using twisted web for an https connection. At first I start with creating and configuring a ssl.DefaultOpenSSLContextFactory derived class that disables SSLv2 and SSLv3. So (basically we're left with TLS1.0 and up) and forces the use of a single strong (non RC4 but BEAST vulnerable) cipher.
Than I have a http.HTTPFactory derived class with a 'buildProtocol'that return a http.HTTPChannel derived object, that in turn returns a http.Request derived object.
Than reactor.listenSSL is invoked with both the SSL factory and the HTTP factory. Now my problem. I don't really understand how these two are connected once the request handler gets invoked.
What I would like to do is that I would want to allow TLS1.0 users to use the server, but only after explicitly agreeing that they understand the risks involved with using an old BEAST vulnerable browser.
Is there any way to retrieve info on what TLS version has been negotiated from within the HTTP request handler? I've been walking the 'self' object a bit, and self.transport.getHandle() seems to have some tls stuff like 'get_cipher_list' and 'get_peer_certificate', but the simple TLS version number does not seem to be available.
Is the twisted web API simply insuficient to retreive this information from within the request handler, or am I missing something here?
T.I.A,
Rob

On 11:43 am, rmeijer@xs4all.nl wrote:
I'm using twisted web for an https connection. At first I start with creating and configuring a ssl.DefaultOpenSSLContextFactory derived class that disables SSLv2 and SSLv3. So (basically we're left with TLS1.0 and up) and forces the use of a single strong (non RC4 but BEAST vulnerable) cipher.
Than I have a http.HTTPFactory derived class with a 'buildProtocol'that return a http.HTTPChannel derived object, that in turn returns a http.Request derived object.
Than reactor.listenSSL is invoked with both the SSL factory and the HTTP factory. Now my problem. I don't really understand how these two are connected once the request handler gets invoked.
What I would like to do is that I would want to allow TLS1.0 users to use the server, but only after explicitly agreeing that they understand the risks involved with using an old BEAST vulnerable browser.
Is there any way to retrieve info on what TLS version has been negotiated from within the HTTP request handler? I've been walking the 'self' object a bit, and self.transport.getHandle() seems to have some tls stuff like 'get_cipher_list' and 'get_peer_certificate', but the simple TLS version number does not seem to be available.
The object you get back from `self.transport.getHandle()` happens to be an object from pyOpenSSL - an instance of OpenSSL.SSL.Connection. While reading the following, though, bear in mind that `getHandle` doesn't make much of a promise about what it will return. Other transports may return something else and future versions of Twisted may change the result as well.
The API that OpenSSL appears to offer for determining what protocol version is in use appears to be SSL_get_version(). This returns a string like "SSLv2" or "TLSv1" (the documentation doesn't say anything about TLSv1.1 or TLSv1.2 but *presumably* if you have a version of OpenSSL that implements either of these protocols and one of them is negotiated on a connection then SSL_get_version() will identify them in its result).
pyOpenSSL, however, does not expose this method. So in order to get the information you need you may need to contribute a binding for this method to pyOpenSSL.
Jean-Paul
Is the twisted web API simply insuficient to retreive this information from within the request handler, or am I missing something here?
T.I.A,
Rob

On Wed, November 6, 2013 15:38, exarkun@twistedmatrix.com wrote:
On 11:43 am, rmeijer@xs4all.nl wrote:
I'm using twisted web for an https connection. At first I start with creating and configuring a ssl.DefaultOpenSSLContextFactory derived class that disables SSLv2 and SSLv3. So (basically we're left with TLS1.0 and up) and forces the use of a single strong (non RC4 but BEAST vulnerable) cipher.
Than I have a http.HTTPFactory derived class with a 'buildProtocol'that return a http.HTTPChannel derived object, that in turn returns a http.Request derived object.
Than reactor.listenSSL is invoked with both the SSL factory and the HTTP factory. Now my problem. I don't really understand how these two are connected once the request handler gets invoked.
What I would like to do is that I would want to allow TLS1.0 users to use the server, but only after explicitly agreeing that they understand the risks involved with using an old BEAST vulnerable browser.
Is there any way to retrieve info on what TLS version has been negotiated from within the HTTP request handler? I've been walking the 'self' object a bit, and self.transport.getHandle() seems to have some tls stuff like 'get_cipher_list' and 'get_peer_certificate', but the simple TLS version number does not seem to be available.
The object you get back from `self.transport.getHandle()` happens to be an object from pyOpenSSL - an instance of OpenSSL.SSL.Connection. While reading the following, though, bear in mind that `getHandle` doesn't make much of a promise about what it will return. Other transports may return something else and future versions of Twisted may change the result as well.
The API that OpenSSL appears to offer for determining what protocol version is in use appears to be SSL_get_version(). This returns a string like "SSLv2" or "TLSv1" (the documentation doesn't say anything about TLSv1.1 or TLSv1.2 but *presumably* if you have a version of OpenSSL that implements either of these protocols and one of them is negotiated on a connection then SSL_get_version() will identify them in its result).
pyOpenSSL, however, does not expose this method. So in order to get the information you need you may need to contribute a binding for this method to pyOpenSSL.
Jean-Paul
Hi Jean-Paul,
Tnx very much for your answer. I've now ended up with what I think is a bit of a hack. I've consulted the wikipedia page on TLS :
http://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers
and added some code that checks the browser version as reported un the user-agent header against the minimum version of major browsers that report to have TLS1.1 support both implemented and enabled by default. I'm not fully satisfied with this one, but unfortunately it seems to be the only viable option for my current project :-(
Tnx,
Rob

On 11/10/13 10:45 PM, Rob Meijer wrote:
On Wed, November 6, 2013 15:38, exarkun@twistedmatrix.com wrote:
On 11:43 am, rmeijer@xs4all.nl wrote:
I'm using twisted web for an https connection. At first I start with creating and configuring a ssl.DefaultOpenSSLContextFactory derived class that disables SSLv2 and SSLv3. So (basically we're left with TLS1.0 and up) and forces the use of a single strong (non RC4 but BEAST vulnerable) cipher.
Than I have a http.HTTPFactory derived class with a 'buildProtocol'that return a http.HTTPChannel derived object, that in turn returns a http.Request derived object.
Than reactor.listenSSL is invoked with both the SSL factory and the HTTP factory. Now my problem. I don't really understand how these two are connected once the request handler gets invoked.
What I would like to do is that I would want to allow TLS1.0 users to use the server, but only after explicitly agreeing that they understand the risks involved with using an old BEAST vulnerable browser.
Is there any way to retrieve info on what TLS version has been negotiated from within the HTTP request handler? I've been walking the 'self' object a bit, and self.transport.getHandle() seems to have some tls stuff like 'get_cipher_list' and 'get_peer_certificate', but the simple TLS version number does not seem to be available.
The object you get back from `self.transport.getHandle()` happens to be an object from pyOpenSSL - an instance of OpenSSL.SSL.Connection. While reading the following, though, bear in mind that `getHandle` doesn't make much of a promise about what it will return. Other transports may return something else and future versions of Twisted may change the result as well.
The API that OpenSSL appears to offer for determining what protocol version is in use appears to be SSL_get_version(). This returns a string like "SSLv2" or "TLSv1" (the documentation doesn't say anything about TLSv1.1 or TLSv1.2 but *presumably* if you have a version of OpenSSL that implements either of these protocols and one of them is negotiated on a connection then SSL_get_version() will identify them in its result).
pyOpenSSL, however, does not expose this method. So in order to get the information you need you may need to contribute a binding for this method to pyOpenSSL.
Jean-Paul
Hi Jean-Paul,
Tnx very much for your answer. I've now ended up with what I think is a bit of a hack. I've consulted the wikipedia page on TLS :
http://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers
and added some code that checks the browser version as reported un the user-agent header against the minimum version of major browsers that report to have TLS1.1 support both implemented and enabled by default. I'm not fully satisfied with this one, but unfortunately it seems to be the only viable option for my current project :-(
Hi Rob
Seeing that you are checking the UA header, I have a bit of information concerning UA detection code, which lead to me filing a bug report for nevow which stumbles over this problem
https://bugs.launchpad.net/nevow/+bug/1249946
As you can see from the link in bug report, IE11 is posing as many beasts, but in standard mode the UA string is
'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'
HTH, Werner

Hi everyone,
I wanted to share with you the yearlong project I have been working on, which led me to discover Twisted besides many other things. It’s using Twisted for all peer-to-peer network connections. This also has led me to produce a Qt5 reactor for Twisted (anyone needs this, I can send, MIT)
The app is here: http://www.getaether.net
Aether is a desktop application that provides its users anonymous public spaces for discussion. It’s pretty close to the archetypal form (reddit / slashdot) with votes and else.
The networking backend is Twisted (AMP). The way distribution works is this: If an user upvotes a post, the user’s computer will start to distribute that post. When an user receives a post, if the post received does not have at least ten (an arbitrary number) copies in computers around him, it will mark the post as under extinction danger, and start to distribute it.
The number of upvotes are the number of times an user sees the same post in other computers. The posts are then lined up according to their upvotes. That’s mostly all there is to it. Oh and it’s encrypted to teeth :). (TLS_RSA_WITH_AES_256_CBC_SHA, 2048 bit RSA keys)
The code is here:
https://github.com/nehbit/aether-public/
Since this is the first project I have built using Twisted (and the reason I discovered & learned it in the first place), I wanted to share it with you. I’d welcome all critique / comments—this is a long term project, and I’m just starting out. Critique on Twisted code, (which is all over the place) is especially welcomed.
I have sought help from some of you before, and all the reply I have received had been unfailingly kind. So this is a collective thank–you for this mailing list and for the general Twisted / Python community, without which Aether would not exist.
Best, Burak
On November 11, 2013 at 11:52:39 AM, Werner Thie (werner@thieprojects.ch) wrote:
On 11/10/13 10:45 PM, Rob Meijer wrote:
On Wed, November 6, 2013 15:38, exarkun@twistedmatrix.com wrote:
On 11:43 am, rmeijer@xs4all.nl wrote:
I'm using twisted web for an https connection. At first I start with creating and configuring a ssl.DefaultOpenSSLContextFactory derived class that disables SSLv2 and SSLv3. So (basically we're left with TLS1.0 and up) and forces the use of a single strong (non RC4 but BEAST vulnerable) cipher.
Than I have a http.HTTPFactory derived class with a 'buildProtocol'that return a http.HTTPChannel derived object, that in turn returns a http.Request derived object.
Than reactor.listenSSL is invoked with both the SSL factory and the HTTP factory. Now my problem. I don't really understand how these two are connected once the request handler gets invoked.
What I would like to do is that I would want to allow TLS1.0 users to use the server, but only after explicitly agreeing that they understand the risks involved with using an old BEAST vulnerable browser.
Is there any way to retrieve info on what TLS version has been negotiated from within the HTTP request handler? I've been walking the 'self' object a bit, and self.transport.getHandle() seems to have some tls stuff like 'get_cipher_list' and 'get_peer_certificate', but the simple TLS version number does not seem to be available.
The object you get back from `self.transport.getHandle()` happens to be an object from pyOpenSSL - an instance of OpenSSL.SSL.Connection. While reading the following, though, bear in mind that `getHandle` doesn't make much of a promise about what it will return. Other transports may return something else and future versions of Twisted may change the result as well.
The API that OpenSSL appears to offer for determining what protocol version is in use appears to be SSL_get_version(). This returns a string like "SSLv2" or "TLSv1" (the documentation doesn't say anything about TLSv1.1 or TLSv1.2 but *presumably* if you have a version of OpenSSL that implements either of these protocols and one of them is negotiated on a connection then SSL_get_version() will identify them in its result).
pyOpenSSL, however, does not expose this method. So in order to get the information you need you may need to contribute a binding for this method to pyOpenSSL.
Jean-Paul
Hi Jean-Paul,
Tnx very much for your answer. I've now ended up with what I think is a bit of a hack. I've consulted the wikipedia page on TLS :
http://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers
and added some code that checks the browser version as reported un the user-agent header against the minimum version of major browsers that report to have TLS1.1 support both implemented and enabled by default. I'm not fully satisfied with this one, but unfortunately it seems to be the only viable option for my current project :-(
Hi Rob
Seeing that you are checking the UA header, I have a bit of information concerning UA detection code, which lead to me filing a bug report for nevow which stumbles over this problem
https://bugs.launchpad.net/nevow/+bug/1249946
As you can see from the link in bug report, IE11 is posing as many beasts, but in standard mode the UA string is
'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'
HTH, Werner
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

On Nov 11, 2013, at 11:49 AM, Burak Nehbit burak@nehbit.net wrote:
Hi everyone,
I wanted to share with you the yearlong project I have been working on, which led me to discover Twisted besides many other things. It’s using Twisted for all peer-to-peer network connections. This also has led me to produce a Qt5 reactor for Twisted (anyone needs this, I can send, MIT)
Hi Burak,
Thanks very much for choosing to use Twisted for this project! It looks interesting :). And thanks again for your kind words about the community :).
It looks like this is definitely making some significant and interesting security-related claims. Do you have plans for getting it audited?
-glyph

Hi Glyph,
It looks like this is definitely making some significant and interesting security-related claims. Do you have plans for getting it audited?
I’m making more of anonymity claims and less of security. It is secure only in peer–to–peer connections, in that the connection between peers are encrypted. But all data that is distributed on Aether is public, so there is no secrecy, at all. I do not authenticate people either. The only reason the connection between peers are encrypted is it being a defence against a global passive adversary. So the the example goes, I do protect my users from the eye of Mordor (dragnet surveillance) but if Nazguls are in your home (your computer is seized), I can’t save you from that. I do in fact offer some protection for the latter case, too, but I’m less sure of its extent, so I am not touting it until I’m more confident.
Protection against a dragnet is rather obvious: encrypt everything. Unless you’re a special target, you’ll be safe.
Protection against seizure is a little bit more complex: I am not committing any information into the database* that can reduce your plausible deniability. So at the point you post an item, you’re no different than another sharer of that item both to the network and to your computer.
* I actually do commit one piece of information: If a post is created by the local user, it will have a flag describing it to be so, so the user’s client can notify the user of replies to that post. I am planning to convert this feature to ‘subscribe to posts or threads’ and remove the flag. So even the local computer won’t have any information about whether the post was received from the network or created locally, but the user will still continue to receive replies as he is subscribed to that post.
Audit— I would love to. I was talking to Laurens about this a few weeks ago for the security, but there hasn’t been a formal audit. I don’t have the resources to pay for that, unfortunately. If anyone wants to do it, I’d be glad to help.
Best, Burak
On November 11, 2013 at 7:16:00 PM, Glyph (glyph@twistedmatrix.com) wrote:
On Nov 11, 2013, at 11:49 AM, Burak Nehbit burak@nehbit.net wrote:
Hi everyone,
I wanted to share with you the yearlong project I have been working on, which led me to discover Twisted besides many other things. It’s using Twisted for all peer-to-peer network connections. This also has led me to produce a Qt5 reactor for Twisted (anyone needs this, I can send, MIT)
Hi Burak,
Thanks very much for choosing to use Twisted for this project! It looks interesting :). And thanks again for your kind words about the community :).
It looks like this is definitely making some significant and interesting security-related claims. Do you have plans for getting it audited?
-glyph
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
participants (5)
-
Burak Nehbit
-
exarkun@twistedmatrix.com
-
Glyph
-
Rob Meijer
-
Werner Thie