Browse Source

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 <christian@python.org>
pull/6977/head
Christian Heimes 8 years ago
committed by GitHub
parent
commit
e8eb6cb792
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .travis.yml
  2. 8
      Doc/library/ssl.rst
  3. 51
      Lib/test/test_ssl.py
  4. 3
      Misc/NEWS.d/next/Library/2018-05-18-21-50-47.bpo-33570.7CZy4t.rst
  5. 8
      Tools/ssl/multissltests.py

2
.travis.yml

@ -12,7 +12,7 @@ cache:
env: env:
global: global:
- OPENSSL=1.1.0g
- OPENSSL=1.1.0h
- OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}" - OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}"
- PATH="${OPENSSL_DIR}/bin:$PATH" - PATH="${OPENSSL_DIR}/bin:$PATH"
# Use -O3 because we don't use debugger on Travis-CI # Use -O3 because we don't use debugger on Travis-CI

8
Doc/library/ssl.rst

@ -169,11 +169,6 @@ purposes.
3DES was dropped from the default cipher string. 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 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 when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will
give the currently selected cipher. 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) .. method:: SSLContext.set_alpn_protocols(protocols)
Specify which protocols the socket should advertise during the SSL/TLS Specify which protocols the socket should advertise during the SSL/TLS

51
Lib/test/test_ssl.py

@ -2695,10 +2695,7 @@ class ThreadedTests(unittest.TestCase):
def test_ecc_cert(self): def test_ecc_cert(self):
client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client_context.load_verify_locations(SIGNING_CA) 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 hostname = SIGNED_CERTFILE_ECC_HOSTNAME
server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
@ -3439,17 +3436,16 @@ class ThreadedTests(unittest.TestCase):
sock.do_handshake() sock.do_handshake()
self.assertEqual(cm.exception.errno, errno.ENOTCONN) 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): with self.assertRaises(OSError):
s.connect((HOST, server.port)) s.connect((HOST, server.port))
self.assertIn("no shared cipher", server.conn_errors[0]) 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: with context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port)) s.connect((HOST, server.port))
self.assertIn(s.cipher()[0], { 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') self.assertEqual(s.version(), 'TLSv1.3')
@ -3898,23 +3894,20 @@ class ThreadedTests(unittest.TestCase):
def test_shared_ciphers(self): def test_shared_ciphers(self):
client_context, server_context, hostname = testing_context() 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, stats = server_params_test(client_context, server_context,
sni_name=hostname) sni_name=hostname)
ciphers = stats['server_shared_ciphers'][0] ciphers = stats['server_shared_ciphers'][0]
self.assertGreater(len(ciphers), 0) self.assertGreater(len(ciphers), 0)
for name, tls_version, bits in ciphers: 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) self.fail(name)
def test_read_write_after_close_raises_valuerror(self): def test_read_write_after_close_raises_valuerror(self):

3
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.

8
Tools/ssl/multissltests.py

@ -45,16 +45,16 @@ OPENSSL_OLD_VERSIONS = [
] ]
OPENSSL_RECENT_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_OLD_VERSIONS = [
] ]
LIBRESSL_RECENT_VERSIONS = [ LIBRESSL_RECENT_VERSIONS = [
"2.7.1",
"2.7.3",
] ]
# store files in ../multissl # store files in ../multissl

Loading…
Cancel
Save