Question

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

Was it helpful?

Solution

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()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top