Skip to content

Commit

Permalink
Stop considering LibreSSL for HAS_NEVER_CHECK_COMMON_NAME
Browse files Browse the repository at this point in the history
  • Loading branch information
pquentin committed Nov 12, 2022
1 parent 0152ca9 commit 9763f09
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 34 deletions.
33 changes: 9 additions & 24 deletions src/urllib3/util/ssl_.py
Expand Up @@ -23,24 +23,6 @@
HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}


def _is_openssl_issue_14579_fixed(
openssl_version_text: str, openssl_version_number: int
) -> bool:
"""
Returns True for OpenSSL 1.1.1l+ (>=0x101010cf) where this issue was fixed.
Before the fix, the SSL_new() API was not copying hostflags like
X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, which tripped up CPython.
https://github.com/openssl/openssl/issues/14579
LibreSSL reports a version number of 0x20000000 for
OpenSSL version number so we need to filter out LibreSSL.
"""
return (
not openssl_version_text.startswith("LibreSSL")
and openssl_version_number >= 0x101010CF
)


def _is_bpo_43522_fixed(
implementation_name: str, version_info: _TYPE_VERSION_INFO
) -> bool:
Expand Down Expand Up @@ -71,14 +53,19 @@ def _is_bpo_43522_fixed(


def _is_has_never_check_common_name_reliable(
openssl_version: str,
openssl_version_number: int,
implementation_name: str,
version_info: _TYPE_VERSION_INFO,
) -> bool:
return _is_openssl_issue_14579_fixed(
openssl_version, openssl_version_number
) or _is_bpo_43522_fixed(implementation_name, version_info)
# Before fixing OpenSSL issue #14579, the SSL_new() API was not copying hostflags
# like X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, which tripped up CPython.
# https://github.com/openssl/openssl/issues/14579
# This was released in OpenSSL 1.1.1l+ (>=0x101010cf)
is_openssl_issue_14579_fixed = openssl_version_number >= 0x101010CF

return is_openssl_issue_14579_fixed or _is_bpo_43522_fixed(
implementation_name, version_info
)


if TYPE_CHECKING:
Expand All @@ -104,7 +91,6 @@ class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False):
HAS_NEVER_CHECK_COMMON_NAME,
OP_NO_COMPRESSION,
OP_NO_TICKET,
OPENSSL_VERSION,
OPENSSL_VERSION_NUMBER,
PROTOCOL_TLS,
PROTOCOL_TLS_CLIENT,
Expand All @@ -119,7 +105,6 @@ class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False):
# Setting SSLContext.hostname_checks_common_name = False didn't work before CPython
# 3.8.9, 3.9.3, and 3.10 (but OK on PyPy) or OpenSSL 1.1.1l+
if HAS_NEVER_CHECK_COMMON_NAME and not _is_has_never_check_common_name_reliable(
OPENSSL_VERSION,
OPENSSL_VERSION_NUMBER,
sys.implementation.name,
sys.version_info,
Expand Down
16 changes: 6 additions & 10 deletions test/test_util.py
Expand Up @@ -1052,32 +1052,28 @@ def test_ssl_wrap_socket_sni_none_no_warn(self) -> None:
warn.assert_not_called()

@pytest.mark.parametrize(
"openssl_version, openssl_version_number, implementation_name, version_info, reliable",
"openssl_version_number, implementation_name, version_info, reliable",
[
# OpenSSL and Python OK -> reliable
("OpenSSL 1.1.1l", 0x101010CF, "cpython", (3, 9, 3), True),
(0x101010CF, "cpython", (3, 9, 3), True),
# Python OK -> reliable
("OpenSSL 1.1.1", 0x10101000, "cpython", (3, 9, 3), True),
("OpenSSL 1.1.1", 0x10101000, "pypy", (3, 6, 9), False),
("LibreSSL 3.3.5", 0x101010CF, "pypy", (3, 6, 9), False),
(0x10101000, "cpython", (3, 9, 3), True),
(0x10101000, "pypy", (3, 6, 9), False),
# OpenSSL OK -> reliable
("OpenSSL", 0x101010CF, "cpython", (3, 9, 2), True),
(0x101010CF, "cpython", (3, 9, 2), True),
# unreliable
("OpenSSL", 0x10101000, "cpython", (3, 9, 2), False),
("LibreSSL", 0x101010CF, "cpython", (3, 9, 2), False),
(0x10101000, "cpython", (3, 9, 2), False),
],
)
def test_is_has_never_check_common_name_reliable(
self,
openssl_version: str,
openssl_version_number: int,
implementation_name: str,
version_info: _TYPE_VERSION_INFO,
reliable: bool,
) -> None:
assert (
_is_has_never_check_common_name_reliable(
openssl_version,
openssl_version_number,
implementation_name,
version_info,
Expand Down

0 comments on commit 9763f09

Please sign in to comment.