diff options
-rw-r--r-- | setuptools/ssl_support.py | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index 6362f1f4..77e67d8f 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -3,6 +3,7 @@ import socket import atexit import re import functools +import sys from setuptools.extern.six.moves import urllib, http_client, map, filter @@ -48,6 +49,12 @@ except ImportError: CertificateError = None match_hostname = None +try: + import OpenSSL +except ImportError: + pass + + if not CertificateError: class CertificateError(ValueError): @@ -158,7 +165,7 @@ class VerifyingHTTPSHandler(HTTPSHandler): def https_open(self, req): return self.do_open( - lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req + lambda host, **kw: pick_ssl()(host, self.ca_bundle, **kw), req ) @@ -202,6 +209,29 @@ class VerifyingHTTPSConn(HTTPSConnection): raise +class OpenSSLHTTPSConnection(HTTPSConnection): + def __init__(self, host, ca_bundle, **kw): + HTTPSConnection.__init__(self, host, **kw) + self.ca_bundle = ca_bundle + + def connect(self): + context = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) + context.use_certificate_file(self.ca_bundle) + + raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock = OpenSSL.SSL.Connection(context, raw_sock) + self.sock.connect((self.host, self.port)) + + +def pick_ssl(): + use_openssl = ( + sys.platform == "darwin" + and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f + and 'OpenSSL' in globals() + ) + return OpenSSLHTTPSConnection if use_openssl else VerifyingHTTPSConn + + def opener_for(ca_bundle=None): """Get a urlopen() replacement that uses ca_bundle for verification""" return urllib.request.build_opener( |