mirror of
https://git.yoctoproject.org/poky
synced 2026-02-10 18:53:13 +01:00
Due to human error an older revision of the SSL patch was merged. (From OE-Core rev: 325af0f4a821971a7aeeca35b10e3558f86029e0) Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
228 lines
8.7 KiB
Diff
228 lines
8.7 KiB
Diff
From e950ea68dab006944af194c9910b8f2341d1437d Mon Sep 17 00:00:00 2001
|
|
From: Christian Heimes <christian@python.org>
|
|
Date: Thu, 7 Sep 2017 20:23:52 -0700
|
|
Subject: [PATCH] bpo-29136: Add TLS 1.3 cipher suites and OP_NO_TLSv1_3
|
|
(GH-1363) (#3444)
|
|
|
|
* bpo-29136: Add TLS 1.3 support
|
|
|
|
TLS 1.3 introduces a new, distinct set of cipher suites. The TLS 1.3
|
|
cipher suites don't overlap with cipher suites from TLS 1.2 and earlier.
|
|
Since Python sets its own set of permitted ciphers, TLS 1.3 handshake
|
|
will fail as soon as OpenSSL 1.1.1 is released. Let's enable the common
|
|
AES-GCM and ChaCha20 suites.
|
|
|
|
Additionally the flag OP_NO_TLSv1_3 is added. It defaults to 0 (no op) with
|
|
OpenSSL prior to 1.1.1. This allows applications to opt-out from TLS 1.3
|
|
now.
|
|
|
|
Signed-off-by: Christian Heimes <christian@python.org>.
|
|
(cherry picked from commit cb5b68abdeb1b1d56c581d5b4d647018703d61e3)
|
|
|
|
Upstream-Status: Backport
|
|
[https://github.com/python/cpython/commit/cb5b68abdeb1b1d56c581d5b4d647018703d61e3]
|
|
|
|
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
|
---
|
|
Doc/library/ssl.rst | 21 ++++++++++++++
|
|
Lib/ssl.py | 7 +++++
|
|
Lib/test/test_ssl.py | 29 ++++++++++++++++++-
|
|
.../2017-09-04-16-39-49.bpo-29136.vSn1oR.rst | 1 +
|
|
Modules/_ssl.c | 13 +++++++++
|
|
5 files changed, 70 insertions(+), 1 deletion(-)
|
|
create mode 100644 Misc/NEWS.d/next/Library/2017-09-04-16-39-49.bpo-29136.vSn1oR.rst
|
|
|
|
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
|
|
index 14f2d68217..29c5e94cf6 100644
|
|
--- a/Doc/library/ssl.rst
|
|
+++ b/Doc/library/ssl.rst
|
|
@@ -285,6 +285,11 @@ 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.
|
|
+
|
|
|
|
Random generation
|
|
^^^^^^^^^^^^^^^^^
|
|
@@ -719,6 +724,16 @@ Constants
|
|
|
|
.. versionadded:: 3.4
|
|
|
|
+.. data:: OP_NO_TLSv1_3
|
|
+
|
|
+ Prevents a TLSv1.3 connection. This option is only applicable in conjunction
|
|
+ with :const:`PROTOCOL_TLS`. It prevents the peers from choosing TLSv1.3 as
|
|
+ the protocol version. TLS 1.3 is available with OpenSSL 1.1.1 or later.
|
|
+ When Python has been compiled against an older version of OpenSSL, the
|
|
+ flag defaults to *0*.
|
|
+
|
|
+ .. versionadded:: 3.7
|
|
+
|
|
.. data:: OP_CIPHER_SERVER_PREFERENCE
|
|
|
|
Use the server's cipher ordering preference, rather than the client's.
|
|
@@ -783,6 +798,12 @@ Constants
|
|
|
|
.. versionadded:: 3.3
|
|
|
|
+.. data:: HAS_TLSv1_3
|
|
+
|
|
+ Whether the OpenSSL library has built-in support for the TLS 1.3 protocol.
|
|
+
|
|
+ .. versionadded:: 3.7
|
|
+
|
|
.. data:: CHANNEL_BINDING_TYPES
|
|
|
|
List of supported TLS channel binding types. Strings in this list
|
|
diff --git a/Lib/ssl.py b/Lib/ssl.py
|
|
index 4d302a78fa..f233e72e1f 100644
|
|
--- a/Lib/ssl.py
|
|
+++ b/Lib/ssl.py
|
|
@@ -122,6 +122,7 @@ _import_symbols('OP_')
|
|
_import_symbols('ALERT_DESCRIPTION_')
|
|
_import_symbols('SSL_ERROR_')
|
|
_import_symbols('VERIFY_')
|
|
+from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN, HAS_TLSv1_3
|
|
|
|
from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
|
|
|
|
@@ -162,6 +163,7 @@ else:
|
|
# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
|
|
# Enable a better set of ciphers by default
|
|
# This list has been explicitly chosen to:
|
|
+# * TLS 1.3 ChaCha20 and AES-GCM cipher suites
|
|
# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
|
|
# * Prefer ECDHE over DHE for better performance
|
|
# * Prefer AEAD over CBC for better performance and security
|
|
@@ -173,6 +175,8 @@ else:
|
|
# * Disable NULL authentication, NULL encryption, 3DES and MD5 MACs
|
|
# for security reasons
|
|
_DEFAULT_CIPHERS = (
|
|
+ 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:'
|
|
+ 'TLS13-AES-128-GCM-SHA256:'
|
|
'ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:'
|
|
'ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:'
|
|
'!aNULL:!eNULL:!MD5:!3DES'
|
|
@@ -180,6 +184,7 @@ _DEFAULT_CIPHERS = (
|
|
|
|
# Restricted and more secure ciphers for the server side
|
|
# This list has been explicitly chosen to:
|
|
+# * TLS 1.3 ChaCha20 and AES-GCM cipher suites
|
|
# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE)
|
|
# * Prefer ECDHE over DHE for better performance
|
|
# * Prefer AEAD over CBC for better performance and security
|
|
@@ -190,6 +195,8 @@ _DEFAULT_CIPHERS = (
|
|
# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, RC4, and
|
|
# 3DES for security reasons
|
|
_RESTRICTED_SERVER_CIPHERS = (
|
|
+ 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:'
|
|
+ 'TLS13-AES-128-GCM-SHA256:'
|
|
'ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:'
|
|
'ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:'
|
|
'!aNULL:!eNULL:!MD5:!DSS:!RC4:!3DES'
|
|
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
|
index f91af7bd05..1acc12ec2d 100644
|
|
--- a/Lib/test/test_ssl.py
|
|
+++ b/Lib/test/test_ssl.py
|
|
@@ -150,6 +150,13 @@ class BasicSocketTests(unittest.TestCase):
|
|
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
|
|
|
|
def test_str_for_enums(self):
|
|
# Make sure that the PROTOCOL_* constants have enum-like string
|
|
@@ -3028,12 +3035,33 @@ else:
|
|
self.assertEqual(s.version(), 'TLSv1')
|
|
self.assertIs(s.version(), None)
|
|
|
|
+ @unittest.skipUnless(ssl.HAS_TLSv1_3,
|
|
+ "test requires TLSv1.3 enabled OpenSSL")
|
|
+ def test_tls1_3(self):
|
|
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
|
+ context.load_cert_chain(CERTFILE)
|
|
+ # disable all but TLS 1.3
|
|
+ context.options |= (
|
|
+ ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
|
|
+ )
|
|
+ with ThreadedEchoServer(context=context) as server:
|
|
+ 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',
|
|
+ ])
|
|
+
|
|
@unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
|
|
def test_default_ecdh_curve(self):
|
|
# Issue #21015: elliptic curve-based Diffie Hellman key exchange
|
|
# should be enabled by default on SSL contexts.
|
|
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
|
context.load_cert_chain(CERTFILE)
|
|
+ # TLSv1.3 defaults to PFS key agreement and no longer has KEA in
|
|
+ # cipher name.
|
|
+ context.options |= ssl.OP_NO_TLSv1_3
|
|
# Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
|
|
# explicitly using the 'ECCdraft' cipher alias. Otherwise,
|
|
# our default cipher list should prefer ECDH-based ciphers
|
|
@@ -3394,7 +3422,6 @@ else:
|
|
s.sendfile(file)
|
|
self.assertEqual(s.recv(1024), TEST_DATA)
|
|
|
|
-
|
|
def test_main(verbose=False):
|
|
if support.verbose:
|
|
import warnings
|
|
diff --git a/Misc/NEWS.d/next/Library/2017-09-04-16-39-49.bpo-29136.vSn1oR.rst b/Misc/NEWS.d/next/Library/2017-09-04-16-39-49.bpo-29136.vSn1oR.rst
|
|
new file mode 100644
|
|
index 0000000000..e76997ef83
|
|
--- /dev/null
|
|
+++ b/Misc/NEWS.d/next/Library/2017-09-04-16-39-49.bpo-29136.vSn1oR.rst
|
|
@@ -0,0 +1 @@
|
|
+Add TLS 1.3 cipher suites and OP_NO_TLSv1_3.
|
|
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
|
|
index 0d5c121d2c..c71d89607c 100644
|
|
--- a/Modules/_ssl.c
|
|
+++ b/Modules/_ssl.c
|
|
@@ -4842,6 +4842,11 @@ PyInit__ssl(void)
|
|
#if HAVE_TLSv1_2
|
|
PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
|
|
PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
|
|
+#endif
|
|
+#ifdef SSL_OP_NO_TLSv1_3
|
|
+ PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3);
|
|
+#else
|
|
+ PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", 0);
|
|
#endif
|
|
PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE",
|
|
SSL_OP_CIPHER_SERVER_PREFERENCE);
|
|
@@ -4890,6 +4895,14 @@ PyInit__ssl(void)
|
|
Py_INCREF(r);
|
|
PyModule_AddObject(m, "HAS_ALPN", r);
|
|
|
|
+#if defined(TLS1_3_VERSION) && !defined(OPENSSL_NO_TLS1_3)
|
|
+ r = Py_True;
|
|
+#else
|
|
+ r = Py_False;
|
|
+#endif
|
|
+ Py_INCREF(r);
|
|
+ PyModule_AddObject(m, "HAS_TLSv1_3", r);
|
|
+
|
|
/* Mappings for error codes */
|
|
err_codes_to_names = PyDict_New();
|
|
err_names_to_codes = PyDict_New();
|
|
--
|
|
2.17.1
|
|
|