summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_ssl.py
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2021-04-17 09:36:35 (GMT)
committerGitHub <noreply@github.com>2021-04-17 09:36:35 (GMT)
commit39258d3595300bc7b952854c915f63ae2d4b9c3e (patch)
treec15a6172739d53516aa45042f22658e0af6ff992 /Lib/test/test_ssl.py
parentb467d9a24011992242c95d9157d3455f8a84466b (diff)
downloadcpython-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.py119
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)