7

I want to choose the transport layer protocol used for opening https links using urllib2.urlopen() in Python 2.7

Similar to what we can do using openssl utility:

openssl s_client -connect www.google.com:443 -ssl2
openssl s_client -connect www.google.com:443 -ssl3
openssl s_client -connect www.google.com:443 -tls1

The motive is to not use ssl2 protocol that leads to handshake problems in most of the servers. urllib2 seems to use SSLv23 protocol that uses SSLv2 or SSLv3 with some kind of fall of mechanism. There are cases where this leads to handshake issues

attaboyabhipro
  • 1,450
  • 1
  • 17
  • 33
  • In C with OpenSSL, we usually use TLS 1.0 and above (for those who pay attention to these sorts of things). To get the old handshake with the newer protocols, use the `SSLv23_method` and then set the two context options `SSL_OP_NO_SSLv2` and `SSL_OP_NO_SSLv3`. Not sure how to do it in Python, though. Also, there's usually no need for fallback. If you have to fallback, you dealing with an ancient or broken server (both are rare now a days). If that's the case, just fail and move on... – jww Mar 26 '14 at 10:40

1 Answers1

10

Update: Since Python 2.7.9 you could pass SSLContext that specifies TLS protocol to urlopen() function:

import ssl
import urllib2

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
# other settings (see ssl.create_default_context() implementation)
urllib2.urlopen('https://example.com', context=context).close()

old answer:

httplib.HTTPSConnection and urllib2.HTTPSHandler do not allow to change ssl version but ssl.wrap_socket() does.

You could define your own HTTPSHandler that would allow you to pass arbitrary arguments to ssl.wrap_socket() e.g., urllib2_ssl.py:

>>> import ssl
>>> import urllib2
>>> import urllib2_ssl # https://gist.github.com/zed/1347055
>>> opener = urllib2.build_opener(urllib2_ssl.HTTPSHandler(
...     ssl_version=ssl.PROTOCOL_TLSv1, #XXX you need to modify urllib2_ssl
...     ca_certs='cacert.pem')) # http://curl.haxx.se/ca/cacert.pem.bz2
>>> opener.open('https://example.com/').read()
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670