diff options
author | Hasan Ramezani <hasan.r67@gmail.com> | 2022-01-14 17:46:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-14 10:46:36 -0600 |
commit | f070ec2e6f6c545f40d9196e5246df10c72e48e1 (patch) | |
tree | 8d5a1e9541072005a2e25be5492fa88ca6c0da3a /test/with_dummyserver/test_https.py | |
parent | 33afb5c96c435ab7118b5f41e26f96c290fef55b (diff) | |
download | urllib3-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.py | 63 |
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: |