| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -93,6 +93,78 @@ def data_file(*name): | |
| OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0) | ||
|
|
||
|
|
||
| def has_tls_protocol(protocol): | ||
| """Check if a TLS protocol is available and enabled | ||
| :param protocol: enum ssl._SSLMethod member or name | ||
| :return: bool | ||
| """ | ||
| if isinstance(protocol, str): | ||
| assert protocol.startswith('PROTOCOL_') | ||
| protocol = getattr(ssl, protocol, None) | ||
| if protocol is None: | ||
| return False | ||
| if protocol in { | ||
| ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS_SERVER, | ||
| ssl.PROTOCOL_TLS_CLIENT | ||
| }: | ||
| # auto-negotiate protocols are always available | ||
| return True | ||
| name = protocol.name | ||
| return has_tls_version(name[len('PROTOCOL_'):]) | ||
|
|
||
|
|
||
| @functools.lru_cache() | ||
| def has_tls_version(version): | ||
| """Check if a TLS/SSL version is enabled | ||
| :param version: TLS version name or ssl.TLSVersion member | ||
| :return: bool | ||
| """ | ||
| if version == "SSLv2": | ||
| # never supported and not even in TLSVersion enum | ||
| return False | ||
|
|
||
| if isinstance(version, str): | ||
| version = ssl.TLSVersion.__members__[version] | ||
|
|
||
| # check compile time flags like ssl.HAS_TLSv1_2 | ||
| if not getattr(ssl, f'HAS_{version.name}'): | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityNeither does this.
Sorry, something went wrong.
All reactions
|
||
| return False | ||
|
|
||
| # check runtime and dynamic crypto policy settings. A TLS version may | ||
| # be compiled in but disabled by a policy or config option. | ||
| ctx = ssl.SSLContext() | ||
| if ( | ||
| hasattr(ctx, 'minimum_version') and | ||
| ctx.minimum_version != ssl.TLSVersion.MINIMUM_SUPPORTED and | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityYet the most importantly, and that I believe is what is problematic on newer systems is that this (and MAXIMUM_SUPPORTED) is also not here yet.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis change requires #5259 to be backported. However even if we backport that, it relies on some features from #5128 . So in general I don't think it's possible to pull this off with this approach. And it's easy to figure out the baked/compiled in versions of supported protocols in openssl but no easy way, without those features, to determine the runtime config.
Sorry, something went wrong.
All reactions
|
||
| version < ctx.minimum_version | ||
| ): | ||
| return False | ||
| if ( | ||
| hasattr(ctx, 'maximum_version') and | ||
| ctx.maximum_version != ssl.TLSVersion.MAXIMUM_SUPPORTED and | ||
| version > ctx.maximum_version | ||
| ): | ||
| return False | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| def requires_tls_version(version): | ||
| """Decorator to skip tests when a required TLS version is not available | ||
| :param version: TLS version name or ssl.TLSVersion member | ||
| :return: | ||
| """ | ||
| def decorator(func): | ||
| @functools.wraps(func) | ||
| def wrapper(*args, **kw): | ||
| if not has_tls_version(version): | ||
| raise unittest.SkipTest(f"{version} is not available.") | ||
| else: | ||
| return func(*args, **kw) | ||
| return wrapper | ||
| return decorator | ||
|
|
||
|
|
||
| def handle_error(prefix): | ||
| exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) | ||
| if support.verbose: | ||
| Expand Down Expand Up | @@ -132,7 +204,7 @@ def asn1time(cert_time): | |
|
|
||
| # Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2 | ||
| def skip_if_broken_ubuntu_ssl(func): | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| @functools.wraps(func) | ||
| def f(*args, **kwargs): | ||
| try: | ||
| Expand Down Expand Up | @@ -1751,7 +1823,7 @@ def test_get_ca_certs_capath(self): | |
| self.assertEqual(len(ctx.get_ca_certs()), 1) | ||
|
|
||
| @needs_sni | ||
| @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"), "needs TLS 1.2") | ||
| @requires_tls_version('TLSv1_2') | ||
| def test_context_setget(self): | ||
| # Check that the context of a connected socket can be replaced. | ||
| ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) | ||
| Expand Down Expand Up | @@ -2399,6 +2471,8 @@ def test_echo(self): | |
| for protocol in PROTOCOLS: | ||
| if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}: | ||
| continue | ||
| if not has_tls_protocol(protocol): | ||
| continue | ||
| with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]): | ||
| context = ssl.SSLContext(protocol) | ||
| context.load_cert_chain(CERTFILE) | ||
| Expand Down Expand Up | @@ -2637,9 +2711,7 @@ def connector(): | |
| finally: | ||
| t.join() | ||
|
|
||
| @skip_if_broken_ubuntu_ssl | ||
| @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), | ||
| "OpenSSL is compiled without SSLv2 support") | ||
| @requires_tls_version('SSLv2') | ||
| def test_protocol_sslv2(self): | ||
| """Connecting to an SSLv2 server with various client options""" | ||
| if support.verbose: | ||
| Expand All | @@ -2648,7 +2720,7 @@ def test_protocol_sslv2(self): | |
| try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) | ||
| # SSLv23 client with specific SSL options | ||
| Expand All | @@ -2667,7 +2739,7 @@ def test_protocol_sslv23(self): | |
| """Connecting to an SSLv23 server with various client options""" | ||
| if support.verbose: | ||
| sys.stdout.write("\n") | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| try: | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True) | ||
| except OSError as x: | ||
| Expand All | @@ -2676,23 +2748,23 @@ def test_protocol_sslv23(self): | |
| sys.stdout.write( | ||
| " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" | ||
| % str(x)) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1') | ||
|
|
||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) | ||
|
|
||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) | ||
|
|
||
| # Server with specific SSL options | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, | ||
| server_options=ssl.OP_NO_SSLv3) | ||
| # Will choose TLSv1 | ||
| Expand All | @@ -2702,17 +2774,15 @@ def test_protocol_sslv23(self): | |
| server_options=ssl.OP_NO_TLSv1) | ||
|
|
||
|
|
||
| @skip_if_broken_ubuntu_ssl | ||
| @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'), | ||
| "OpenSSL is compiled without SSLv3 support") | ||
| @requires_tls_version('SSLv3') | ||
| def test_protocol_sslv3(self): | ||
| """Connecting to an SSLv3 server with various client options""" | ||
| if support.verbose: | ||
| sys.stdout.write("\n") | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3') | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) | ||
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False, | ||
| client_options=ssl.OP_NO_SSLv3) | ||
| Expand All | @@ -2722,46 +2792,42 @@ def test_protocol_sslv3(self): | |
| try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, | ||
| False, client_options=ssl.OP_NO_SSLv2) | ||
|
|
||
| @skip_if_broken_ubuntu_ssl | ||
| @requires_tls_version('TLSv1') | ||
| def test_protocol_tlsv1(self): | ||
| """Connecting to a TLSv1 server with various client options""" | ||
| if support.verbose: | ||
| sys.stdout.write("\n") | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1') | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False, | ||
| client_options=ssl.OP_NO_TLSv1) | ||
|
|
||
| @skip_if_broken_ubuntu_ssl | ||
| @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"), | ||
| "TLS version 1.1 not supported.") | ||
| @requires_tls_version('TLSv1_1') | ||
| @skip_if_openssl_cnf_minprotocol_gt_tls1 | ||
| def test_protocol_tlsv1_1(self): | ||
| """Connecting to a TLSv1.1 server with various client options. | ||
| Testing against older TLS versions.""" | ||
| if support.verbose: | ||
| sys.stdout.write("\n") | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False, | ||
| client_options=ssl.OP_NO_TLSv1_1) | ||
|
|
||
| try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) | ||
|
|
||
|
|
||
| @skip_if_broken_ubuntu_ssl | ||
| @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"), | ||
| "TLS version 1.2 not supported.") | ||
| @requires_tls_version('TLSv1_2') | ||
| def test_protocol_tlsv1_2(self): | ||
| """Connecting to a TLSv1.2 server with various client options. | ||
| Testing against older TLS versions.""" | ||
| Expand All | @@ -2770,9 +2836,9 @@ def test_protocol_tlsv1_2(self): | |
| try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2', | ||
| server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2, | ||
| client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv2'): | ||
| if has_tls_version('SSLv2'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) | ||
| if hasattr(ssl, 'PROTOCOL_SSLv3'): | ||
| if has_tls_version('SSLv3'): | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) | ||
| try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False, | ||
| client_options=ssl.OP_NO_TLSv1_2) | ||
| Expand Down Expand Up | @@ -3218,11 +3284,13 @@ def test_version_basic(self): | |
| with context.wrap_socket(socket.socket()) as s: | ||
| self.assertIs(s.version(), None) | ||
| s.connect((HOST, server.port)) | ||
| self.assertEqual(s.version(), 'TLSv1') | ||
| if IS_OPENSSL_1_1_1 and has_tls_version('TLSv1_3'): | ||
| self.assertEqual(s.version(), 'TLSv1.3') | ||
| elif ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): | ||
| self.assertEqual(s.version(), 'TLSv1.2') | ||
| self.assertIs(s.version(), None) | ||
|
|
||
| @unittest.skipUnless(ssl.HAS_TLSv1_3, | ||
| "test requires TLSv1.3 enabled OpenSSL") | ||
| @requires_tls_version('TLSv1_3') | ||
| def test_tls1_3(self): | ||
| context = ssl.SSLContext(ssl.PROTOCOL_TLS) | ||
| context.load_cert_chain(CERTFILE) | ||
| Expand Down Expand Up | @@ -3740,7 +3808,7 @@ def testing_context(): | |
| return client_context, server_context, 'localhost' | ||
|
|
||
|
|
||
| @unittest.skipUnless(ssl.HAS_TLSv1_3, "Test needs TLS 1.3") | ||
| @unittest.skipUnless(has_tls_version('TLSv1_3'), "Test needs TLS 1.3") | ||
| class TestPostHandshakeAuth(unittest.TestCase): | ||
| def test_pha_setter(self): | ||
| protocols = [ | ||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| test_ssl now handles disabled TLS/SSL versions better. OpenSSL's crypto | ||
| policy and run-time settings are recognized and tests for disabled versions | ||
| are skipped. |
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySo this entire thing does not exist on 3.6 yet.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.