Skip to content

Commit

Permalink
Use system TLS ciphers in OpenSSL 1.1.1+
Browse files Browse the repository at this point in the history
  • Loading branch information
sethmlarson committed Nov 24, 2020
1 parent edbdc34 commit 439c9be
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
13 changes: 11 additions & 2 deletions src/urllib3/util/ssl_.py
Expand Up @@ -14,6 +14,7 @@
IS_PYOPENSSL = False
IS_SECURETRANSPORT = False
ALPN_PROTOCOLS = ["http/1.1"]
USE_SYSTEM_SSL_CIPHERS = False

# Maps the length of a digest to a possible hash function producing this digest
HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}
Expand Down Expand Up @@ -41,12 +42,16 @@ def _const_compare_digest_backport(a, b):
HAS_SNI,
OP_NO_COMPRESSION,
OP_NO_TICKET,
OPENSSL_VERSION_INFO,
PROTOCOL_TLS,
OP_NO_SSLv2,
OP_NO_SSLv3,
SSLContext,
)

if OPENSSL_VERSION_INFO >= (1, 1, 1):
USE_SYSTEM_SSL_CIPHERS = True

PROTOCOL_SSLv23 = PROTOCOL_TLS
from .ssltransport import SSLTransport
except ImportError:
Expand Down Expand Up @@ -189,14 +194,18 @@ def create_urllib3_context(
Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
:param ciphers:
Which cipher suites to allow the server to select.
Which cipher suites to allow the server to select. Defaults to either system configured
ciphers if OpenSSL 1.1.1+, otherwise uses a secure default set of ciphers.
:returns:
Constructed SSLContext object with specified options
:rtype: SSLContext
"""
context = SSLContext(ssl_version or PROTOCOL_TLS)

context.set_ciphers(ciphers or DEFAULT_CIPHERS)
# Unless we're given ciphers defer to either system ciphers in
# the case of OpenSSL 1.1.1+ or use our own secure default ciphers.
if ciphers is not None or not USE_SYSTEM_SSL_CIPHERS:
context.set_ciphers(ciphers or DEFAULT_CIPHERS)

# Setting the default here, as we may have no ssl module on import
cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
Expand Down
23 changes: 21 additions & 2 deletions test/test_ssl.py
Expand Up @@ -112,8 +112,11 @@ def test_create_urllib3_context_set_ciphers(monkeypatch, ciphers, expected_ciphe

assert ssl_.create_urllib3_context(ciphers=ciphers) is context

assert context.set_ciphers.call_count == 1
assert context.set_ciphers.call_args == mock.call(expected_ciphers)
if ciphers is None and ssl_.USE_SYSTEM_SSL_CIPHERS:
assert context.set_ciphers.call_count == 0
else:
assert context.set_ciphers.call_count == 1
assert context.set_ciphers.call_args == mock.call(expected_ciphers)


def test_wrap_socket_given_context_no_load_default_certs():
Expand Down Expand Up @@ -166,3 +169,19 @@ def test_create_urllib3_context_pha(monkeypatch, pha, expected_pha):
assert ssl_.create_urllib3_context() is context

assert context.post_handshake_auth == expected_pha


@pytest.mark.parametrize("use_system_ssl_ciphers", [True, False])
def test_create_urllib3_context_default_ciphers(monkeypatch, use_system_ssl_ciphers):
context = mock.create_autospec(ssl_.SSLContext)
context.set_ciphers = mock.Mock()
context.options = 0
monkeypatch.setattr(ssl_, "SSLContext", lambda *_, **__: context)
monkeypatch.setattr(ssl_, "USE_SYSTEM_SSL_CIPHERS", use_system_ssl_ciphers)

ssl_.create_urllib3_context()

if use_system_ssl_ciphers:
context.set_ciphers.assert_not_called()
else:
context.set_ciphers.assert_called_with(ssl_.DEFAULT_CIPHERS)

0 comments on commit 439c9be

Please sign in to comment.