We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
PyOpenSSL support doesn't work with TLSv1.1 and TLSv1.2
`docker-py` tries to use latest protocol version in the ssl module, so use ssl.PROTOCOL_TLSv1_2. Unfortunately urllib3.contrib.pyopenssl only has SSLv2_3 and TLSv1 so it breaks:

https://github.com/shazow/urllib3/blob/master/urllib3/contrib/pyopenssl.py#L68


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `urllib3/contrib/pyopenssl.py`
Content:
```
1 '''SSL with SNI_-support for Python 2. Follow these instructions if you would
2 like to verify SSL certificates in Python 2. Note, the default libraries do
3 *not* do certificate checking; you need to do additional work to validate
4 certificates yourself.
5 
6 This needs the following packages installed:
7 
8 * pyOpenSSL (tested with 0.13)
9 * ndg-httpsclient (tested with 0.3.2)
10 * pyasn1 (tested with 0.1.6)
11 
12 You can install them with the following command:
13 
14     pip install pyopenssl ndg-httpsclient pyasn1
15 
16 To activate certificate checking, call
17 :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
18 before you begin making HTTP requests. This can be done in a ``sitecustomize``
19 module, or at any other time before your application begins using ``urllib3``,
20 like this::
21 
22     try:
23         import urllib3.contrib.pyopenssl
24         urllib3.contrib.pyopenssl.inject_into_urllib3()
25     except ImportError:
26         pass
27 
28 Now you can use :mod:`urllib3` as you normally would, and it will support SNI
29 when the required modules are installed.
30 
31 Activating this module also has the positive side effect of disabling SSL/TLS
32 compression in Python 2 (see `CRIME attack`_).
33 
34 If you want to configure the default list of supported cipher suites, you can
35 set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.
36 
37 Module Variables
38 ----------------
39 
40 :var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites.
41 
42 .. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
43 .. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
44 
45 '''
46 
47 try:
48     from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT
49     from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName
50 except SyntaxError as e:
51     raise ImportError(e)
52 
53 import OpenSSL.SSL
54 from pyasn1.codec.der import decoder as der_decoder
55 from pyasn1.type import univ, constraint
56 from socket import _fileobject, timeout
57 import ssl
58 import select
59 
60 from .. import connection
61 from .. import util
62 
63 __all__ = ['inject_into_urllib3', 'extract_from_urllib3']
64 
65 # SNI only *really* works if we can read the subjectAltName of certificates.
66 HAS_SNI = SUBJ_ALT_NAME_SUPPORT
67 
68 # Map from urllib3 to PyOpenSSL compatible parameter-values.
69 _openssl_versions = {
70     ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,
71     ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
72 }
73 
74 try:
75     _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})
76 except AttributeError:
77     pass
78 
79 _openssl_verify = {
80     ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
81     ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
82     ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER
83                        + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
84 }
85 
86 DEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS
87 
88 # OpenSSL will only write 16K at a time
89 SSL_WRITE_BLOCKSIZE = 16384
90 
91 try:
92     _ = memoryview
93     has_memoryview = True
94 except NameError:
95     has_memoryview = False
96 
97 orig_util_HAS_SNI = util.HAS_SNI
98 orig_connection_ssl_wrap_socket = connection.ssl_wrap_socket
99 
100 
101 def inject_into_urllib3():
102     'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'
103 
104     connection.ssl_wrap_socket = ssl_wrap_socket
105     util.HAS_SNI = HAS_SNI
106 
107 
108 def extract_from_urllib3():
109     'Undo monkey-patching by :func:`inject_into_urllib3`.'
110 
111     connection.ssl_wrap_socket = orig_connection_ssl_wrap_socket
112     util.HAS_SNI = orig_util_HAS_SNI
113 
114 
115 ### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.
116 class SubjectAltName(BaseSubjectAltName):
117     '''ASN.1 implementation for subjectAltNames support'''
118 
119     # There is no limit to how many SAN certificates a certificate may have,
120     #   however this needs to have some limit so we'll set an arbitrarily high
121     #   limit.
122     sizeSpec = univ.SequenceOf.sizeSpec + \
123         constraint.ValueSizeConstraint(1, 1024)
124 
125 
126 ### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.
127 def get_subj_alt_name(peer_cert):
128     # Search through extensions
129     dns_name = []
130     if not SUBJ_ALT_NAME_SUPPORT:
131         return dns_name
132 
133     general_names = SubjectAltName()
134     for i in range(peer_cert.get_extension_count()):
135         ext = peer_cert.get_extension(i)
136         ext_name = ext.get_short_name()
137         if ext_name != 'subjectAltName':
138             continue
139 
140         # PyOpenSSL returns extension data in ASN.1 encoded form
141         ext_dat = ext.get_data()
142         decoded_dat = der_decoder.decode(ext_dat,
143                                          asn1Spec=general_names)
144 
145         for name in decoded_dat:
146             if not isinstance(name, SubjectAltName):
147                 continue
148             for entry in range(len(name)):
149                 component = name.getComponentByPosition(entry)
150                 if component.getName() != 'dNSName':
151                     continue
152                 dns_name.append(str(component.getComponent()))
153 
154     return dns_name
155 
156 
157 class WrappedSocket(object):
158     '''API-compatibility wrapper for Python OpenSSL's Connection-class.
159 
160     Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
161     collector of pypy.
162     '''
163 
164     def __init__(self, connection, socket, suppress_ragged_eofs=True):
165         self.connection = connection
166         self.socket = socket
167         self.suppress_ragged_eofs = suppress_ragged_eofs
168         self._makefile_refs = 0
169 
170     def fileno(self):
171         return self.socket.fileno()
172 
173     def makefile(self, mode, bufsize=-1):
174         self._makefile_refs += 1
175         return _fileobject(self, mode, bufsize, close=True)
176 
177     def recv(self, *args, **kwargs):
178         try:
179             data = self.connection.recv(*args, **kwargs)
180         except OpenSSL.SSL.SysCallError as e:
181             if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):
182                 return b''
183             else:
184                 raise
185         except OpenSSL.SSL.ZeroReturnError as e:
186             if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
187                 return b''
188             else:
189                 raise
190         except OpenSSL.SSL.WantReadError:
191             rd, wd, ed = select.select(
192                 [self.socket], [], [], self.socket.gettimeout())
193             if not rd:
194                 raise timeout('The read operation timed out')
195             else:
196                 return self.recv(*args, **kwargs)
197         else:
198             return data
199 
200     def settimeout(self, timeout):
201         return self.socket.settimeout(timeout)
202 
203     def _send_until_done(self, data):
204         while True:
205             try:
206                 return self.connection.send(data)
207             except OpenSSL.SSL.WantWriteError:
208                 _, wlist, _ = select.select([], [self.socket], [],
209                                             self.socket.gettimeout())
210                 if not wlist:
211                     raise timeout()
212                 continue
213 
214     def sendall(self, data):
215         if has_memoryview and not isinstance(data, memoryview):
216             data = memoryview(data)
217 
218         total_sent = 0
219         while total_sent < len(data):
220             sent = self._send_until_done(data[total_sent:total_sent+SSL_WRITE_BLOCKSIZE])
221             total_sent += sent
222 
223     def shutdown(self):
224         # FIXME rethrow compatible exceptions should we ever use this
225         self.connection.shutdown()
226 
227     def close(self):
228         if self._makefile_refs < 1:
229             return self.connection.close()
230         else:
231             self._makefile_refs -= 1
232 
233     def getpeercert(self, binary_form=False):
234         x509 = self.connection.get_peer_certificate()
235 
236         if not x509:
237             return x509
238 
239         if binary_form:
240             return OpenSSL.crypto.dump_certificate(
241                 OpenSSL.crypto.FILETYPE_ASN1,
242                 x509)
243 
244         return {
245             'subject': (
246                 (('commonName', x509.get_subject().CN),),
247             ),
248             'subjectAltName': [
249                 ('DNS', value)
250                 for value in get_subj_alt_name(x509)
251             ]
252         }
253 
254     def _reuse(self):
255         self._makefile_refs += 1
256 
257     def _drop(self):
258         if self._makefile_refs < 1:
259             self.close()
260         else:
261             self._makefile_refs -= 1
262 
263 
264 def _verify_callback(cnx, x509, err_no, err_depth, return_code):
265     return err_no == 0
266 
267 
268 def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
269                     ca_certs=None, server_hostname=None,
270                     ssl_version=None):
271     ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version])
272     if certfile:
273         keyfile = keyfile or certfile  # Match behaviour of the normal python ssl library
274         ctx.use_certificate_file(certfile)
275     if keyfile:
276         ctx.use_privatekey_file(keyfile)
277     if cert_reqs != ssl.CERT_NONE:
278         ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback)
279     if ca_certs:
280         try:
281             ctx.load_verify_locations(ca_certs, None)
282         except OpenSSL.SSL.Error as e:
283             raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e)
284     else:
285         ctx.set_default_verify_paths()
286 
287     # Disable TLS compression to migitate CRIME attack (issue #309)
288     OP_NO_COMPRESSION = 0x20000
289     ctx.set_options(OP_NO_COMPRESSION)
290 
291     # Set list of supported ciphersuites.
292     ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)
293 
294     cnx = OpenSSL.SSL.Connection(ctx, sock)
295     cnx.set_tlsext_host_name(server_hostname)
296     cnx.set_connect_state()
297     while True:
298         try:
299             cnx.do_handshake()
300         except OpenSSL.SSL.WantReadError:
301             rd, _, _ = select.select([sock], [], [], sock.gettimeout())
302             if not rd:
303                 raise timeout('select timed out')
304             continue
305         except OpenSSL.SSL.Error as e:
306             raise ssl.SSLError('bad handshake: %r' % e)
307         break
308 
309     return WrappedSocket(cnx, sock)
310
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/urllib3/contrib/pyopenssl.py b/urllib3/contrib/pyopenssl.py
--- a/urllib3/contrib/pyopenssl.py
+++ b/urllib3/contrib/pyopenssl.py
@@ -71,6 +71,12 @@
     ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
 }
 
+if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):
+    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
+
+if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
+    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
+
 try:
     _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})
 except AttributeError:

{"golden_diff": "diff --git a/urllib3/contrib/pyopenssl.py b/urllib3/contrib/pyopenssl.py\n--- a/urllib3/contrib/pyopenssl.py\n+++ b/urllib3/contrib/pyopenssl.py\n@@ -71,6 +71,12 @@\n     ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,\n }\n \n+if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):\n+    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD\n+\n+if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):\n+    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD\n+\n try:\n     _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})\n except AttributeError:\n", "issue": "PyOpenSSL support doesn't work with TLSv1.1 and TLSv1.2\n`docker-py` tries to use latest protocol version in the ssl module, so use ssl.PROTOCOL_TLSv1_2. Unfortunately urllib3.contrib.pyopenssl only has SSLv2_3 and TLSv1 so it breaks:\n\nhttps://github.com/shazow/urllib3/blob/master/urllib3/contrib/pyopenssl.py#L68\n\n", "before_files": [{"content": "'''SSL with SNI_-support for Python 2. Follow these instructions if you would\nlike to verify SSL certificates in Python 2. Note, the default libraries do\n*not* do certificate checking; you need to do additional work to validate\ncertificates yourself.\n\nThis needs the following packages installed:\n\n* pyOpenSSL (tested with 0.13)\n* ndg-httpsclient (tested with 0.3.2)\n* pyasn1 (tested with 0.1.6)\n\nYou can install them with the following command:\n\n    pip install pyopenssl ndg-httpsclient pyasn1\n\nTo activate certificate checking, call\n:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code\nbefore you begin making HTTP requests. This can be done in a ``sitecustomize``\nmodule, or at any other time before your application begins using ``urllib3``,\nlike this::\n\n    try:\n        import urllib3.contrib.pyopenssl\n        urllib3.contrib.pyopenssl.inject_into_urllib3()\n    except ImportError:\n        pass\n\nNow you can use :mod:`urllib3` as you normally would, and it will support SNI\nwhen the required modules are installed.\n\nActivating this module also has the positive side effect of disabling SSL/TLS\ncompression in Python 2 (see `CRIME attack`_).\n\nIf you want to configure the default list of supported cipher suites, you can\nset the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.\n\nModule Variables\n----------------\n\n:var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites.\n\n.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication\n.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)\n\n'''\n\ntry:\n    from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT\n    from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName\nexcept SyntaxError as e:\n    raise ImportError(e)\n\nimport OpenSSL.SSL\nfrom pyasn1.codec.der import decoder as der_decoder\nfrom pyasn1.type import univ, constraint\nfrom socket import _fileobject, timeout\nimport ssl\nimport select\n\nfrom .. import connection\nfrom .. import util\n\n__all__ = ['inject_into_urllib3', 'extract_from_urllib3']\n\n# SNI only *really* works if we can read the subjectAltName of certificates.\nHAS_SNI = SUBJ_ALT_NAME_SUPPORT\n\n# Map from urllib3 to PyOpenSSL compatible parameter-values.\n_openssl_versions = {\n    ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,\n    ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,\n}\n\ntry:\n    _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})\nexcept AttributeError:\n    pass\n\n_openssl_verify = {\n    ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,\n    ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,\n    ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER\n                       + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,\n}\n\nDEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS\n\n# OpenSSL will only write 16K at a time\nSSL_WRITE_BLOCKSIZE = 16384\n\ntry:\n    _ = memoryview\n    has_memoryview = True\nexcept NameError:\n    has_memoryview = False\n\norig_util_HAS_SNI = util.HAS_SNI\norig_connection_ssl_wrap_socket = connection.ssl_wrap_socket\n\n\ndef inject_into_urllib3():\n    'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'\n\n    connection.ssl_wrap_socket = ssl_wrap_socket\n    util.HAS_SNI = HAS_SNI\n\n\ndef extract_from_urllib3():\n    'Undo monkey-patching by :func:`inject_into_urllib3`.'\n\n    connection.ssl_wrap_socket = orig_connection_ssl_wrap_socket\n    util.HAS_SNI = orig_util_HAS_SNI\n\n\n### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.\nclass SubjectAltName(BaseSubjectAltName):\n    '''ASN.1 implementation for subjectAltNames support'''\n\n    # There is no limit to how many SAN certificates a certificate may have,\n    #   however this needs to have some limit so we'll set an arbitrarily high\n    #   limit.\n    sizeSpec = univ.SequenceOf.sizeSpec + \\\n        constraint.ValueSizeConstraint(1, 1024)\n\n\n### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.\ndef get_subj_alt_name(peer_cert):\n    # Search through extensions\n    dns_name = []\n    if not SUBJ_ALT_NAME_SUPPORT:\n        return dns_name\n\n    general_names = SubjectAltName()\n    for i in range(peer_cert.get_extension_count()):\n        ext = peer_cert.get_extension(i)\n        ext_name = ext.get_short_name()\n        if ext_name != 'subjectAltName':\n            continue\n\n        # PyOpenSSL returns extension data in ASN.1 encoded form\n        ext_dat = ext.get_data()\n        decoded_dat = der_decoder.decode(ext_dat,\n                                         asn1Spec=general_names)\n\n        for name in decoded_dat:\n            if not isinstance(name, SubjectAltName):\n                continue\n            for entry in range(len(name)):\n                component = name.getComponentByPosition(entry)\n                if component.getName() != 'dNSName':\n                    continue\n                dns_name.append(str(component.getComponent()))\n\n    return dns_name\n\n\nclass WrappedSocket(object):\n    '''API-compatibility wrapper for Python OpenSSL's Connection-class.\n\n    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage\n    collector of pypy.\n    '''\n\n    def __init__(self, connection, socket, suppress_ragged_eofs=True):\n        self.connection = connection\n        self.socket = socket\n        self.suppress_ragged_eofs = suppress_ragged_eofs\n        self._makefile_refs = 0\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    def makefile(self, mode, bufsize=-1):\n        self._makefile_refs += 1\n        return _fileobject(self, mode, bufsize, close=True)\n\n    def recv(self, *args, **kwargs):\n        try:\n            data = self.connection.recv(*args, **kwargs)\n        except OpenSSL.SSL.SysCallError as e:\n            if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):\n                return b''\n            else:\n                raise\n        except OpenSSL.SSL.ZeroReturnError as e:\n            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:\n                return b''\n            else:\n                raise\n        except OpenSSL.SSL.WantReadError:\n            rd, wd, ed = select.select(\n                [self.socket], [], [], self.socket.gettimeout())\n            if not rd:\n                raise timeout('The read operation timed out')\n            else:\n                return self.recv(*args, **kwargs)\n        else:\n            return data\n\n    def settimeout(self, timeout):\n        return self.socket.settimeout(timeout)\n\n    def _send_until_done(self, data):\n        while True:\n            try:\n                return self.connection.send(data)\n            except OpenSSL.SSL.WantWriteError:\n                _, wlist, _ = select.select([], [self.socket], [],\n                                            self.socket.gettimeout())\n                if not wlist:\n                    raise timeout()\n                continue\n\n    def sendall(self, data):\n        if has_memoryview and not isinstance(data, memoryview):\n            data = memoryview(data)\n\n        total_sent = 0\n        while total_sent < len(data):\n            sent = self._send_until_done(data[total_sent:total_sent+SSL_WRITE_BLOCKSIZE])\n            total_sent += sent\n\n    def shutdown(self):\n        # FIXME rethrow compatible exceptions should we ever use this\n        self.connection.shutdown()\n\n    def close(self):\n        if self._makefile_refs < 1:\n            return self.connection.close()\n        else:\n            self._makefile_refs -= 1\n\n    def getpeercert(self, binary_form=False):\n        x509 = self.connection.get_peer_certificate()\n\n        if not x509:\n            return x509\n\n        if binary_form:\n            return OpenSSL.crypto.dump_certificate(\n                OpenSSL.crypto.FILETYPE_ASN1,\n                x509)\n\n        return {\n            'subject': (\n                (('commonName', x509.get_subject().CN),),\n            ),\n            'subjectAltName': [\n                ('DNS', value)\n                for value in get_subj_alt_name(x509)\n            ]\n        }\n\n    def _reuse(self):\n        self._makefile_refs += 1\n\n    def _drop(self):\n        if self._makefile_refs < 1:\n            self.close()\n        else:\n            self._makefile_refs -= 1\n\n\ndef _verify_callback(cnx, x509, err_no, err_depth, return_code):\n    return err_no == 0\n\n\ndef ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,\n                    ca_certs=None, server_hostname=None,\n                    ssl_version=None):\n    ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version])\n    if certfile:\n        keyfile = keyfile or certfile  # Match behaviour of the normal python ssl library\n        ctx.use_certificate_file(certfile)\n    if keyfile:\n        ctx.use_privatekey_file(keyfile)\n    if cert_reqs != ssl.CERT_NONE:\n        ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback)\n    if ca_certs:\n        try:\n            ctx.load_verify_locations(ca_certs, None)\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e)\n    else:\n        ctx.set_default_verify_paths()\n\n    # Disable TLS compression to migitate CRIME attack (issue #309)\n    OP_NO_COMPRESSION = 0x20000\n    ctx.set_options(OP_NO_COMPRESSION)\n\n    # Set list of supported ciphersuites.\n    ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)\n\n    cnx = OpenSSL.SSL.Connection(ctx, sock)\n    cnx.set_tlsext_host_name(server_hostname)\n    cnx.set_connect_state()\n    while True:\n        try:\n            cnx.do_handshake()\n        except OpenSSL.SSL.WantReadError:\n            rd, _, _ = select.select([sock], [], [], sock.gettimeout())\n            if not rd:\n                raise timeout('select timed out')\n            continue\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError('bad handshake: %r' % e)\n        break\n\n    return WrappedSocket(cnx, sock)\n", "path": "urllib3/contrib/pyopenssl.py"}], "after_files": [{"content": "'''SSL with SNI_-support for Python 2. Follow these instructions if you would\nlike to verify SSL certificates in Python 2. Note, the default libraries do\n*not* do certificate checking; you need to do additional work to validate\ncertificates yourself.\n\nThis needs the following packages installed:\n\n* pyOpenSSL (tested with 0.13)\n* ndg-httpsclient (tested with 0.3.2)\n* pyasn1 (tested with 0.1.6)\n\nYou can install them with the following command:\n\n    pip install pyopenssl ndg-httpsclient pyasn1\n\nTo activate certificate checking, call\n:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code\nbefore you begin making HTTP requests. This can be done in a ``sitecustomize``\nmodule, or at any other time before your application begins using ``urllib3``,\nlike this::\n\n    try:\n        import urllib3.contrib.pyopenssl\n        urllib3.contrib.pyopenssl.inject_into_urllib3()\n    except ImportError:\n        pass\n\nNow you can use :mod:`urllib3` as you normally would, and it will support SNI\nwhen the required modules are installed.\n\nActivating this module also has the positive side effect of disabling SSL/TLS\ncompression in Python 2 (see `CRIME attack`_).\n\nIf you want to configure the default list of supported cipher suites, you can\nset the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.\n\nModule Variables\n----------------\n\n:var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites.\n\n.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication\n.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)\n\n'''\n\ntry:\n    from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT\n    from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName\nexcept SyntaxError as e:\n    raise ImportError(e)\n\nimport OpenSSL.SSL\nfrom pyasn1.codec.der import decoder as der_decoder\nfrom pyasn1.type import univ, constraint\nfrom socket import _fileobject, timeout\nimport ssl\nimport select\n\nfrom .. import connection\nfrom .. import util\n\n__all__ = ['inject_into_urllib3', 'extract_from_urllib3']\n\n# SNI only *really* works if we can read the subjectAltName of certificates.\nHAS_SNI = SUBJ_ALT_NAME_SUPPORT\n\n# Map from urllib3 to PyOpenSSL compatible parameter-values.\n_openssl_versions = {\n    ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,\n    ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,\n}\n\nif hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):\n    _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD\n\nif hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):\n    _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD\n\ntry:\n    _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD})\nexcept AttributeError:\n    pass\n\n_openssl_verify = {\n    ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,\n    ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,\n    ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER\n                       + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,\n}\n\nDEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS\n\n# OpenSSL will only write 16K at a time\nSSL_WRITE_BLOCKSIZE = 16384\n\ntry:\n    _ = memoryview\n    has_memoryview = True\nexcept NameError:\n    has_memoryview = False\n\norig_util_HAS_SNI = util.HAS_SNI\norig_connection_ssl_wrap_socket = connection.ssl_wrap_socket\n\n\ndef inject_into_urllib3():\n    'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'\n\n    connection.ssl_wrap_socket = ssl_wrap_socket\n    util.HAS_SNI = HAS_SNI\n\n\ndef extract_from_urllib3():\n    'Undo monkey-patching by :func:`inject_into_urllib3`.'\n\n    connection.ssl_wrap_socket = orig_connection_ssl_wrap_socket\n    util.HAS_SNI = orig_util_HAS_SNI\n\n\n### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.\nclass SubjectAltName(BaseSubjectAltName):\n    '''ASN.1 implementation for subjectAltNames support'''\n\n    # There is no limit to how many SAN certificates a certificate may have,\n    #   however this needs to have some limit so we'll set an arbitrarily high\n    #   limit.\n    sizeSpec = univ.SequenceOf.sizeSpec + \\\n        constraint.ValueSizeConstraint(1, 1024)\n\n\n### Note: This is a slightly bug-fixed version of same from ndg-httpsclient.\ndef get_subj_alt_name(peer_cert):\n    # Search through extensions\n    dns_name = []\n    if not SUBJ_ALT_NAME_SUPPORT:\n        return dns_name\n\n    general_names = SubjectAltName()\n    for i in range(peer_cert.get_extension_count()):\n        ext = peer_cert.get_extension(i)\n        ext_name = ext.get_short_name()\n        if ext_name != 'subjectAltName':\n            continue\n\n        # PyOpenSSL returns extension data in ASN.1 encoded form\n        ext_dat = ext.get_data()\n        decoded_dat = der_decoder.decode(ext_dat,\n                                         asn1Spec=general_names)\n\n        for name in decoded_dat:\n            if not isinstance(name, SubjectAltName):\n                continue\n            for entry in range(len(name)):\n                component = name.getComponentByPosition(entry)\n                if component.getName() != 'dNSName':\n                    continue\n                dns_name.append(str(component.getComponent()))\n\n    return dns_name\n\n\nclass WrappedSocket(object):\n    '''API-compatibility wrapper for Python OpenSSL's Connection-class.\n\n    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage\n    collector of pypy.\n    '''\n\n    def __init__(self, connection, socket, suppress_ragged_eofs=True):\n        self.connection = connection\n        self.socket = socket\n        self.suppress_ragged_eofs = suppress_ragged_eofs\n        self._makefile_refs = 0\n\n    def fileno(self):\n        return self.socket.fileno()\n\n    def makefile(self, mode, bufsize=-1):\n        self._makefile_refs += 1\n        return _fileobject(self, mode, bufsize, close=True)\n\n    def recv(self, *args, **kwargs):\n        try:\n            data = self.connection.recv(*args, **kwargs)\n        except OpenSSL.SSL.SysCallError as e:\n            if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'):\n                return b''\n            else:\n                raise\n        except OpenSSL.SSL.ZeroReturnError as e:\n            if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:\n                return b''\n            else:\n                raise\n        except OpenSSL.SSL.WantReadError:\n            rd, wd, ed = select.select(\n                [self.socket], [], [], self.socket.gettimeout())\n            if not rd:\n                raise timeout('The read operation timed out')\n            else:\n                return self.recv(*args, **kwargs)\n        else:\n            return data\n\n    def settimeout(self, timeout):\n        return self.socket.settimeout(timeout)\n\n    def _send_until_done(self, data):\n        while True:\n            try:\n                return self.connection.send(data)\n            except OpenSSL.SSL.WantWriteError:\n                _, wlist, _ = select.select([], [self.socket], [],\n                                            self.socket.gettimeout())\n                if not wlist:\n                    raise timeout()\n                continue\n\n    def sendall(self, data):\n        if has_memoryview and not isinstance(data, memoryview):\n            data = memoryview(data)\n\n        total_sent = 0\n        while total_sent < len(data):\n            sent = self._send_until_done(data[total_sent:total_sent+SSL_WRITE_BLOCKSIZE])\n            total_sent += sent\n\n    def shutdown(self):\n        # FIXME rethrow compatible exceptions should we ever use this\n        self.connection.shutdown()\n\n    def close(self):\n        if self._makefile_refs < 1:\n            return self.connection.close()\n        else:\n            self._makefile_refs -= 1\n\n    def getpeercert(self, binary_form=False):\n        x509 = self.connection.get_peer_certificate()\n\n        if not x509:\n            return x509\n\n        if binary_form:\n            return OpenSSL.crypto.dump_certificate(\n                OpenSSL.crypto.FILETYPE_ASN1,\n                x509)\n\n        return {\n            'subject': (\n                (('commonName', x509.get_subject().CN),),\n            ),\n            'subjectAltName': [\n                ('DNS', value)\n                for value in get_subj_alt_name(x509)\n            ]\n        }\n\n    def _reuse(self):\n        self._makefile_refs += 1\n\n    def _drop(self):\n        if self._makefile_refs < 1:\n            self.close()\n        else:\n            self._makefile_refs -= 1\n\n\ndef _verify_callback(cnx, x509, err_no, err_depth, return_code):\n    return err_no == 0\n\n\ndef ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,\n                    ca_certs=None, server_hostname=None,\n                    ssl_version=None):\n    ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version])\n    if certfile:\n        keyfile = keyfile or certfile  # Match behaviour of the normal python ssl library\n        ctx.use_certificate_file(certfile)\n    if keyfile:\n        ctx.use_privatekey_file(keyfile)\n    if cert_reqs != ssl.CERT_NONE:\n        ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback)\n    if ca_certs:\n        try:\n            ctx.load_verify_locations(ca_certs, None)\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e)\n    else:\n        ctx.set_default_verify_paths()\n\n    # Disable TLS compression to migitate CRIME attack (issue #309)\n    OP_NO_COMPRESSION = 0x20000\n    ctx.set_options(OP_NO_COMPRESSION)\n\n    # Set list of supported ciphersuites.\n    ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)\n\n    cnx = OpenSSL.SSL.Connection(ctx, sock)\n    cnx.set_tlsext_host_name(server_hostname)\n    cnx.set_connect_state()\n    while True:\n        try:\n            cnx.do_handshake()\n        except OpenSSL.SSL.WantReadError:\n            rd, _, _ = select.select([sock], [], [], sock.gettimeout())\n            if not rd:\n                raise timeout('select timed out')\n            continue\n        except OpenSSL.SSL.Error as e:\n            raise ssl.SSLError('bad handshake: %r' % e)\n        break\n\n    return WrappedSocket(cnx, sock)\n", "path": "urllib3/contrib/pyopenssl.py"}]}