summaryrefslogtreecommitdiff
path: root/test/with_dummyserver/test_https.py
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2022-01-14 17:46:36 +0100
committerGitHub <noreply@github.com>2022-01-14 10:46:36 -0600
commitf070ec2e6f6c545f40d9196e5246df10c72e48e1 (patch)
tree8d5a1e9541072005a2e25be5492fa88ca6c0da3a /test/with_dummyserver/test_https.py
parent33afb5c96c435ab7118b5f41e26f96c290fef55b (diff)
downloadurllib3-f070ec2e6f6c545f40d9196e5246df10c72e48e1.tar.gz
Respect 'SSLContext.hostname_checks_common_name' when available and set
Co-authored-by: Seth Michael Larson <sethmichaellarson@gmail.com>
Diffstat (limited to 'test/with_dummyserver/test_https.py')
-rw-r--r--test/with_dummyserver/test_https.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/test/with_dummyserver/test_https.py b/test/with_dummyserver/test_https.py
index d72da06a..ec4b00c2 100644
--- a/test/with_dummyserver/test_https.py
+++ b/test/with_dummyserver/test_https.py
@@ -42,6 +42,7 @@ from urllib3.exceptions import (
SSLError,
SystemTimeWarning,
)
+from urllib3.util.ssl_match_hostname import CertificateError
from urllib3.util.timeout import Timeout
from .. import has_alpn
@@ -988,6 +989,68 @@ class TestHTTPS_Hostname:
e.value
) or "no appropriate subjectAltName" in str(e.value)
+ def test_common_name_without_san_with_different_common_name(
+ self, no_san_server_with_different_commmon_name: ServerConfig
+ ) -> None:
+ ctx = urllib3.util.ssl_.create_urllib3_context()
+ try:
+ ctx.hostname_checks_common_name = True
+ except AttributeError:
+ pytest.skip("Couldn't set 'SSLContext.hostname_checks_common_name'")
+
+ with HTTPSConnectionPool(
+ no_san_server_with_different_commmon_name.host,
+ no_san_server_with_different_commmon_name.port,
+ cert_reqs="CERT_REQUIRED",
+ ca_certs=no_san_server_with_different_commmon_name.ca_certs,
+ ssl_context=ctx,
+ ) as https_pool:
+ with pytest.raises(MaxRetryError) as e:
+ https_pool.request("GET", "/")
+ assert "mismatch, certificate is not valid for 'localhost'" in str(
+ e.value
+ ) or "hostname 'localhost' doesn't match 'example.com'" in str(e.value)
+
+ @pytest.mark.parametrize("use_assert_hostname", [True, False])
+ def test_hostname_checks_common_name_respected(
+ self, no_san_server: ServerConfig, use_assert_hostname: bool
+ ) -> None:
+ ctx = urllib3.util.ssl_.create_urllib3_context()
+ if not hasattr(ctx, "hostname_checks_common_name"):
+ pytest.skip("Test requires 'SSLContext.hostname_checks_common_name'")
+ ctx.load_verify_locations(no_san_server.ca_certs)
+ try:
+ ctx.hostname_checks_common_name = True
+ except AttributeError:
+ pytest.skip("Couldn't set 'SSLContext.hostname_checks_common_name'")
+
+ err: Optional[MaxRetryError]
+ try:
+ with HTTPSConnectionPool(
+ no_san_server.host,
+ no_san_server.port,
+ cert_reqs="CERT_REQUIRED",
+ ssl_context=ctx,
+ assert_hostname=no_san_server.host if use_assert_hostname else None,
+ ) as https_pool:
+ https_pool.request("GET", "/")
+ except MaxRetryError as e:
+ err = e
+ else:
+ err = None
+
+ # commonName is only valid for DNS names, not IP addresses.
+ if no_san_server.host == "localhost":
+ assert err is None
+
+ # IP addresses should fail for commonName.
+ else:
+ assert err is not None
+ assert type(err.reason) == SSLError
+ assert isinstance(
+ err.reason.args[0], (ssl.SSLCertVerificationError, CertificateError)
+ )
+
def test_strip_square_brackets_before_validating(
self, ipv6_san_server: ServerConfig
) -> None: