mirror of
https://github.com/python/cpython.git
synced 2025-09-30 04:15:43 +00:00
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>
(cherry picked from commit e8eb6cb792
)
Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
parent
1f22a3003e
commit
cd57b48ef9
5 changed files with 33 additions and 39 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -2716,10 +2716,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(
|
client_context.set_ciphers('ECDHE:ECDSA:!NULL:!aRSA')
|
||||||
'TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:'
|
|
||||||
'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)
|
||||||
|
@ -3466,17 +3463,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):
|
def test_no_shared_ciphers(self):
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
client_context, server_context, hostname = testing_context()
|
||||||
try:
|
# OpenSSL enables all TLS 1.3 ciphers, enforce TLS 1.2 for test
|
||||||
# Force a set of weak ciphers on our client context
|
client_context.options |= ssl.OP_NO_TLSv1_3
|
||||||
context.set_ciphers("DES")
|
# Force different suites on client and master
|
||||||
except ssl.SSLError:
|
client_context.set_ciphers("AES128")
|
||||||
self.skipTest("no DES cipher available")
|
server_context.set_ciphers("AES256")
|
||||||
with ThreadedEchoServer(CERTFILE,
|
with ThreadedEchoServer(context=server_context) as server:
|
||||||
ssl_version=ssl.PROTOCOL_TLS,
|
with client_context.wrap_socket(socket.socket(),
|
||||||
chatty=False) as server:
|
server_hostname=hostname) as s:
|
||||||
with context.wrap_socket(socket.socket()) 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])
|
||||||
|
@ -3517,9 +3513,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',
|
'TLS_AES_256_GCM_SHA384',
|
||||||
'TLS13-CHACHA20-POLY1305-SHA256',
|
'TLS_CHACHA20_POLY1305_SHA256',
|
||||||
'TLS13-AES-128-GCM-SHA256',
|
'TLS_AES_128_GCM_SHA256',
|
||||||
})
|
})
|
||||||
self.assertEqual(s.version(), 'TLSv1.3')
|
self.assertEqual(s.version(), 'TLSv1.3')
|
||||||
|
|
||||||
|
@ -3925,23 +3921,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")
|
||||||
client_context.set_ciphers("AES128:AES256")
|
server_context.set_ciphers("AES256")
|
||||||
server_context.set_ciphers("AES256")
|
expected_algs = [
|
||||||
alg1 = "AES256"
|
"AES256", "AES-256",
|
||||||
alg2 = "AES-256"
|
# TLS 1.3 ciphers are always enabled
|
||||||
else:
|
"TLS_CHACHA20", "TLS_AES",
|
||||||
client_context.set_ciphers("AES:3DES")
|
]
|
||||||
server_context.set_ciphers("3DES")
|
|
||||||
alg1 = "3DES"
|
|
||||||
alg2 = "DES-CBC3"
|
|
||||||
|
|
||||||
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):
|
||||||
|
|
|
@ -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.
|
|
@ -45,16 +45,16 @@ OPENSSL_OLD_VERSIONS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
OPENSSL_RECENT_VERSIONS = [
|
OPENSSL_RECENT_VERSIONS = [
|
||||||
"1.0.2n",
|
"1.0.2o",
|
||||||
"1.1.0g",
|
"1.1.0h",
|
||||||
"1.1.1-pre1",
|
"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…
Add table
Add a link
Reference in a new issue