From e8eb6cb7920ded66abc5d284319a8539bdc2bae3 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Tue, 22 May 2018 22:50:12 +0200 Subject: [PATCH] bpo-33570: TLS 1.3 ciphers for OpenSSL 1.1.1 (GH-6976) Change TLS 1.3 cipher suite settings for compatibility with OpenSSL 1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 cipers enabled by default. Also update multissltests and Travis config to test with latest OpenSSL. Signed-off-by: Christian Heimes --- .travis.yml | 2 +- Doc/library/ssl.rst | 8 ++- Lib/test/test_ssl.py | 51 ++++++++----------- .../2018-05-18-21-50-47.bpo-33570.7CZy4t.rst | 3 ++ Tools/ssl/multissltests.py | 8 +-- 5 files changed, 33 insertions(+), 39 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst diff --git a/.travis.yml b/.travis.yml index fecad290d8b..204c63fb567 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ cache: env: global: - - OPENSSL=1.1.0g + - OPENSSL=1.1.0h - OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}" - PATH="${OPENSSL_DIR}/bin:$PATH" # Use -O3 because we don't use debugger on Travis-CI diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index dcb26664fea..2ccea13b614 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -169,11 +169,6 @@ purposes. 3DES was dropped from the default cipher string. - .. versionchanged:: 3.7 - - TLS 1.3 cipher suites TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, - and TLS_CHACHA20_POLY1305_SHA256 were added to the default cipher string. - Exceptions ^^^^^^^^^^ @@ -1601,6 +1596,9 @@ to speed up repeated connections from the same clients. when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will give the currently selected cipher. + OpenSSL 1.1.1 has TLS 1.3 cipher suites enabled by default. The suites + cannot be disabled with :meth:`~SSLContext.set_ciphers`. + .. method:: SSLContext.set_alpn_protocols(protocols) Specify which protocols the socket should advertise during the SSL/TLS diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 71380797748..03952b10a8e 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2695,10 +2695,7 @@ class ThreadedTests(unittest.TestCase): def test_ecc_cert(self): client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) client_context.load_verify_locations(SIGNING_CA) - client_context.set_ciphers( - 'TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:' - 'ECDHE:ECDSA:!NULL:!aRSA' - ) + client_context.set_ciphers('ECDHE:ECDSA:!NULL:!aRSA') hostname = SIGNED_CERTFILE_ECC_HOSTNAME server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) @@ -3439,17 +3436,16 @@ class ThreadedTests(unittest.TestCase): sock.do_handshake() self.assertEqual(cm.exception.errno, errno.ENOTCONN) - def test_default_ciphers(self): - context = ssl.SSLContext(ssl.PROTOCOL_TLS) - try: - # Force a set of weak ciphers on our client context - context.set_ciphers("DES") - except ssl.SSLError: - self.skipTest("no DES cipher available") - with ThreadedEchoServer(CERTFILE, - ssl_version=ssl.PROTOCOL_TLS, - chatty=False) as server: - with context.wrap_socket(socket.socket()) as s: + def test_no_shared_ciphers(self): + client_context, server_context, hostname = testing_context() + # OpenSSL enables all TLS 1.3 ciphers, enforce TLS 1.2 for test + client_context.options |= ssl.OP_NO_TLSv1_3 + # Force different suites on client and master + client_context.set_ciphers("AES128") + server_context.set_ciphers("AES256") + with ThreadedEchoServer(context=server_context) as server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: with self.assertRaises(OSError): s.connect((HOST, server.port)) self.assertIn("no shared cipher", server.conn_errors[0]) @@ -3490,9 +3486,9 @@ class ThreadedTests(unittest.TestCase): with context.wrap_socket(socket.socket()) as s: s.connect((HOST, server.port)) self.assertIn(s.cipher()[0], { - 'TLS13-AES-256-GCM-SHA384', - 'TLS13-CHACHA20-POLY1305-SHA256', - 'TLS13-AES-128-GCM-SHA256', + 'TLS_AES_256_GCM_SHA384', + 'TLS_CHACHA20_POLY1305_SHA256', + 'TLS_AES_128_GCM_SHA256', }) self.assertEqual(s.version(), 'TLSv1.3') @@ -3898,23 +3894,20 @@ class ThreadedTests(unittest.TestCase): def test_shared_ciphers(self): client_context, server_context, hostname = testing_context() - if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): - client_context.set_ciphers("AES128:AES256") - server_context.set_ciphers("AES256") - alg1 = "AES256" - alg2 = "AES-256" - else: - client_context.set_ciphers("AES:3DES") - server_context.set_ciphers("3DES") - alg1 = "3DES" - alg2 = "DES-CBC3" + client_context.set_ciphers("AES128:AES256") + server_context.set_ciphers("AES256") + expected_algs = [ + "AES256", "AES-256", + # TLS 1.3 ciphers are always enabled + "TLS_CHACHA20", "TLS_AES", + ] stats = server_params_test(client_context, server_context, sni_name=hostname) ciphers = stats['server_shared_ciphers'][0] self.assertGreater(len(ciphers), 0) for name, tls_version, bits in ciphers: - if not alg1 in name.split("-") and alg2 not in name: + if not any(alg in name for alg in expected_algs): self.fail(name) def test_read_write_after_close_raises_valuerror(self): diff --git a/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst b/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst new file mode 100644 index 00000000000..bd719a47e8f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst @@ -0,0 +1,3 @@ +Change TLS 1.3 cipher suite settings for compatibility with OpenSSL +1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 cipers enabled by +default. diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 2efc4258de9..bbc5c665209 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -45,16 +45,16 @@ OPENSSL_OLD_VERSIONS = [ ] OPENSSL_RECENT_VERSIONS = [ - "1.0.2n", - "1.1.0g", - "1.1.1-pre1", + "1.0.2o", + "1.1.0h", + "1.1.1-pre6", ] LIBRESSL_OLD_VERSIONS = [ ] LIBRESSL_RECENT_VERSIONS = [ - "2.7.1", + "2.7.3", ] # store files in ../multissl