diff options
author | Christian Heimes <christian@python.org> | 2021-04-17 09:36:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-17 09:36:35 (GMT) |
commit | 39258d3595300bc7b952854c915f63ae2d4b9c3e (patch) | |
tree | c15a6172739d53516aa45042f22658e0af6ff992 /Lib/test/test_ssl.py | |
parent | b467d9a24011992242c95d9157d3455f8a84466b (diff) | |
download | cpython-39258d3595300bc7b952854c915f63ae2d4b9c3e.zip cpython-39258d3595300bc7b952854c915f63ae2d4b9c3e.tar.gz cpython-39258d3595300bc7b952854c915f63ae2d4b9c3e.tar.bz2 |
bpo-43669: PEP 644: Require OpenSSL 1.1.1 or newer (GH-23014)
- Remove HAVE_X509_VERIFY_PARAM_SET1_HOST check
- Update hashopenssl to require OpenSSL 1.1.1
- multissltests only OpenSSL > 1.1.0
- ALPN is always supported
- SNI is always supported
- Remove deprecated NPN code. Python wrappers are no-op.
- ECDH is always supported
- Remove OPENSSL_VERSION_1_1 macro
- Remove locking callbacks
- Drop PY_OPENSSL_1_1_API macro
- Drop HAVE_SSL_CTX_CLEAR_OPTIONS macro
- SSL_CTRL_GET_MAX_PROTO_VERSION is always defined now
- security level is always available now
- get_num_tickets is available with TLS 1.3
- X509_V_ERR MISMATCH is always available now
- Always set SSL_MODE_RELEASE_BUFFERS
- X509_V_FLAG_TRUSTED_FIRST is always available
- get_ciphers is always supported
- SSL_CTX_set_keylog_callback is always available
- Update Modules/Setup with static link example
- Mention PEP in whatsnew
- Drop 1.0.2 and 1.1.0 from GHA tests
Diffstat (limited to 'Lib/test/test_ssl.py')
-rw-r--r-- | Lib/test/test_ssl.py | 119 |
1 files changed, 26 insertions, 93 deletions
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 54007c7..3ad14c6 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -40,7 +40,6 @@ Py_DEBUG_WIN32 = Py_DEBUG and sys.platform == 'win32' PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) HOST = socket_helper.HOST IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL') -IS_OPENSSL_1_1_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0) IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1) IS_OPENSSL_3_0_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (3, 0, 0) PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') @@ -270,18 +269,6 @@ def handle_error(prefix): if support.verbose: sys.stdout.write(prefix + exc_format) -def can_clear_options(): - # 0.9.8m or higher - return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15) - -def no_sslv2_implies_sslv3_hello(): - # 0.9.7h or higher - return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) - -def have_verify_flags(): - # 0.9.8 or higher - return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15) - def _have_secp_curves(): if not ssl.HAS_ECDH: return False @@ -372,17 +359,15 @@ class BasicSocketTests(unittest.TestCase): ssl.OP_SINGLE_DH_USE if ssl.HAS_ECDH: ssl.OP_SINGLE_ECDH_USE - if ssl.OPENSSL_VERSION_INFO >= (1, 0): - ssl.OP_NO_COMPRESSION + ssl.OP_NO_COMPRESSION self.assertIn(ssl.HAS_SNI, {True, False}) self.assertIn(ssl.HAS_ECDH, {True, False}) ssl.OP_NO_SSLv2 ssl.OP_NO_SSLv3 ssl.OP_NO_TLSv1 ssl.OP_NO_TLSv1_3 - if ssl.OPENSSL_VERSION_INFO >= (1, 0, 1): - ssl.OP_NO_TLSv1_1 - ssl.OP_NO_TLSv1_2 + ssl.OP_NO_TLSv1_1 + ssl.OP_NO_TLSv1_2 self.assertEqual(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv23) def test_private_init(self): @@ -1161,7 +1146,6 @@ class ContextTests(unittest.TestCase): self.assertNotIn("RC4", name) self.assertNotIn("3DES", name) - @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old') def test_get_ciphers(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.set_ciphers('AESGCM') @@ -1181,15 +1165,11 @@ class ContextTests(unittest.TestCase): self.assertEqual(default, ctx.options) ctx.options |= ssl.OP_NO_TLSv1 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) - if can_clear_options(): - ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) - self.assertEqual(default, ctx.options) - ctx.options = 0 - # Ubuntu has OP_NO_SSLv3 forced on by default - self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) - else: - with self.assertRaises(ValueError): - ctx.options = 0 + ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) + self.assertEqual(default, ctx.options) + ctx.options = 0 + # Ubuntu has OP_NO_SSLv3 forced on by default + self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) def test_verify_mode_protocol(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) @@ -1327,8 +1307,6 @@ class ContextTests(unittest.TestCase): } self.assertIn(ctx.security_level, security_level_range) - @unittest.skipUnless(have_verify_flags(), - "verify_flags need OpenSSL > 0.9.8") def test_verify_flags(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) # default value @@ -1797,7 +1775,6 @@ class ContextTests(unittest.TestCase): obj = ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO()) self.assertIsInstance(obj, MySSLObject) - @unittest.skipUnless(IS_OPENSSL_1_1_1, "Test requires OpenSSL 1.1.1") def test_num_tickest(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) self.assertEqual(ctx.num_tickets, 2) @@ -2956,8 +2933,6 @@ class ThreadedTests(unittest.TestCase): after = ssl.cert_time_to_seconds(cert['notAfter']) self.assertLess(before, after) - @unittest.skipUnless(have_verify_flags(), - "verify_flags need OpenSSL > 0.9.8") def test_crl_check(self): if support.verbose: sys.stdout.write("\n") @@ -3859,12 +3834,7 @@ class ThreadedTests(unittest.TestCase): self.assertIs(s.version(), None) self.assertIs(s._sslobj, None) s.connect((HOST, server.port)) - 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') - else: # 0.9.8 to 1.0.1 - self.assertIn(s.version(), ('TLSv1', 'TLSv1.2')) + self.assertEqual(s.version(), 'TLSv1.3') self.assertIs(s._sslobj, None) self.assertIs(s.version(), None) @@ -3966,8 +3936,6 @@ class ThreadedTests(unittest.TestCase): # explicitly using the 'ECCdraft' cipher alias. Otherwise, # our default cipher list should prefer ECDH-based ciphers # automatically. - if ssl.OPENSSL_VERSION_INFO < (1, 0, 0): - context.set_ciphers("ECCdraft:ECDH") with ThreadedEchoServer(context=context) as server: with context.wrap_socket(socket.socket()) as s: s.connect((HOST, server.port)) @@ -4099,15 +4067,11 @@ class ThreadedTests(unittest.TestCase): server_context.set_ciphers("ECDHE:!eNULL:!aNULL") server_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 try: - stats = server_params_test(client_context, server_context, - chatty=True, connectionchatty=True, - sni_name=hostname) + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) except ssl.SSLError: - pass - else: - # OpenSSL 1.0.2 does not fail although it should. - if IS_OPENSSL_1_1_0: - self.fail("mismatch curve did not fail") + self.fail("mismatch curve did not fail") def test_selected_alpn_protocol(self): # selected_alpn_protocol() is None unless ALPN is used. @@ -4117,7 +4081,6 @@ class ThreadedTests(unittest.TestCase): sni_name=hostname) self.assertIs(stats['client_alpn_protocol'], None) - @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required") def test_selected_alpn_protocol_if_server_uses_alpn(self): # selected_alpn_protocol() is None unless ALPN is used by the client. client_context, server_context, hostname = testing_context() @@ -4127,7 +4090,6 @@ class ThreadedTests(unittest.TestCase): sni_name=hostname) self.assertIs(stats['client_alpn_protocol'], None) - @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test") def test_alpn_protocols(self): server_protocols = ['foo', 'bar', 'milkshake'] protocol_tests = [ @@ -4150,22 +4112,17 @@ class ThreadedTests(unittest.TestCase): except ssl.SSLError as e: stats = e - if (expected is None and IS_OPENSSL_1_1_0 - and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)): - # OpenSSL 1.1.0 to 1.1.0e raises handshake error - self.assertIsInstance(stats, ssl.SSLError) - else: - msg = "failed trying %s (s) and %s (c).\n" \ - "was expecting %s, but got %%s from the %%s" \ - % (str(server_protocols), str(client_protocols), - str(expected)) - client_result = stats['client_alpn_protocol'] - self.assertEqual(client_result, expected, - msg % (client_result, "client")) - server_result = stats['server_alpn_protocols'][-1] \ - if len(stats['server_alpn_protocols']) else 'nothing' - self.assertEqual(server_result, expected, - msg % (server_result, "server")) + msg = "failed trying %s (s) and %s (c).\n" \ + "was expecting %s, but got %%s from the %%s" \ + % (str(server_protocols), str(client_protocols), + str(expected)) + client_result = stats['client_alpn_protocol'] + self.assertEqual(client_result, expected, + msg % (client_result, "client")) + server_result = stats['server_alpn_protocols'][-1] \ + if len(stats['server_alpn_protocols']) else 'nothing' + self.assertEqual(server_result, expected, + msg % (server_result, "server")) def test_selected_npn_protocol(self): # selected_npn_protocol() is None unless NPN is used @@ -4175,31 +4132,8 @@ class ThreadedTests(unittest.TestCase): sni_name=hostname) self.assertIs(stats['client_npn_protocol'], None) - @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test") def test_npn_protocols(self): - server_protocols = ['http/1.1', 'spdy/2'] - protocol_tests = [ - (['http/1.1', 'spdy/2'], 'http/1.1'), - (['spdy/2', 'http/1.1'], 'http/1.1'), - (['spdy/2', 'test'], 'spdy/2'), - (['abc', 'def'], 'abc') - ] - for client_protocols, expected in protocol_tests: - client_context, server_context, hostname = testing_context() - server_context.set_npn_protocols(server_protocols) - client_context.set_npn_protocols(client_protocols) - stats = server_params_test(client_context, server_context, - chatty=True, connectionchatty=True, - sni_name=hostname) - msg = "failed trying %s (s) and %s (c).\n" \ - "was expecting %s, but got %%s from the %%s" \ - % (str(server_protocols), str(client_protocols), - str(expected)) - client_result = stats['client_npn_protocol'] - self.assertEqual(client_result, expected, msg % (client_result, "client")) - server_result = stats['server_npn_protocols'][-1] \ - if len(stats['server_npn_protocols']) else 'nothing' - self.assertEqual(server_result, expected, msg % (server_result, "server")) + assert not ssl.HAS_NPN def sni_contexts(self): server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) @@ -4369,8 +4303,7 @@ class ThreadedTests(unittest.TestCase): self.assertGreater(session.time, 0) self.assertGreater(session.timeout, 0) self.assertTrue(session.has_ticket) - if ssl.OPENSSL_VERSION_INFO > (1, 0, 1): - self.assertGreater(session.ticket_lifetime_hint, 0) + self.assertGreater(session.ticket_lifetime_hint, 0) self.assertFalse(stats['session_reused']) sess_stat = server_context.session_stats() self.assertEqual(sess_stat['accept'], 1) |