mirror of
https://git.yoctoproject.org/poky
synced 2026-02-05 16:28:43 +01:00
python3{,-native}: backport openssl 1.1.1 compatibility changes
Backport changes from 3.7/3.6 to fix failing python3 ssl test suite. Fixes [YOCTO #12919] (From OE-Core rev: 6c123468b546931de005cf136d98bca6b893b37b) Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
55f36a4045
commit
3c32b1525a
@@ -0,0 +1,272 @@
|
||||
From 758e7463c104f71b810c8588166747eeab6148d7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <christian@python.org>
|
||||
Date: Sat, 10 Sep 2016 22:43:48 +0200
|
||||
Subject: [PATCH 1/4] Issue 28043: SSLContext has improved default settings
|
||||
|
||||
The options OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE, OP_NO_SSLv2 (except for PROTOCOL_SSLv2), and OP_NO_SSLv3 (except for PROTOCOL_SSLv3) are set by default. The initial cipher suite list contains only HIGH ciphers, no NULL ciphers and MD5 ciphers (except for PROTOCOL_SSLv2).
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://github.com/python/cpython/commit/358cfd426ccc0fcd6a7940d306602138e76420ae]
|
||||
|
||||
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||
---
|
||||
Doc/library/ssl.rst | 9 ++++++-
|
||||
Lib/ssl.py | 30 +++++----------------
|
||||
Lib/test/test_ssl.py | 62 +++++++++++++++++++++++---------------------
|
||||
Modules/_ssl.c | 31 ++++++++++++++++++++++
|
||||
4 files changed, 78 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
|
||||
index a2f008346b..14f2d68217 100644
|
||||
--- a/Doc/library/ssl.rst
|
||||
+++ b/Doc/library/ssl.rst
|
||||
@@ -1151,7 +1151,14 @@ to speed up repeated connections from the same clients.
|
||||
|
||||
.. versionchanged:: 3.5.3
|
||||
|
||||
- :data:`PROTOCOL_TLS` is the default value.
|
||||
+ The context is created with secure default values. The options
|
||||
+ :data:`OP_NO_COMPRESSION`, :data:`OP_CIPHER_SERVER_PREFERENCE`,
|
||||
+ :data:`OP_SINGLE_DH_USE`, :data:`OP_SINGLE_ECDH_USE`,
|
||||
+ :data:`OP_NO_SSLv2` (except for :data:`PROTOCOL_SSLv2`),
|
||||
+ and :data:`OP_NO_SSLv3` (except for :data:`PROTOCOL_SSLv3`) are
|
||||
+ set by default. The initial cipher suite list contains only ``HIGH``
|
||||
+ ciphers, no ``NULL`` ciphers and no ``MD5`` ciphers (except for
|
||||
+ :data:`PROTOCOL_SSLv2`).
|
||||
|
||||
|
||||
:class:`SSLContext` objects have the following methods and attributes:
|
||||
diff --git a/Lib/ssl.py b/Lib/ssl.py
|
||||
index e1913904f3..4d302a78fa 100644
|
||||
--- a/Lib/ssl.py
|
||||
+++ b/Lib/ssl.py
|
||||
@@ -446,32 +446,16 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
||||
if not isinstance(purpose, _ASN1Object):
|
||||
raise TypeError(purpose)
|
||||
|
||||
+ # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
|
||||
+ # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
|
||||
+ # by default.
|
||||
context = SSLContext(PROTOCOL_TLS)
|
||||
|
||||
- # SSLv2 considered harmful.
|
||||
- context.options |= OP_NO_SSLv2
|
||||
-
|
||||
- # SSLv3 has problematic security and is only required for really old
|
||||
- # clients such as IE6 on Windows XP
|
||||
- context.options |= OP_NO_SSLv3
|
||||
-
|
||||
- # disable compression to prevent CRIME attacks (OpenSSL 1.0+)
|
||||
- context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0)
|
||||
-
|
||||
if purpose == Purpose.SERVER_AUTH:
|
||||
# verify certs and host name in client mode
|
||||
context.verify_mode = CERT_REQUIRED
|
||||
context.check_hostname = True
|
||||
elif purpose == Purpose.CLIENT_AUTH:
|
||||
- # Prefer the server's ciphers by default so that we get stronger
|
||||
- # encryption
|
||||
- context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
|
||||
-
|
||||
- # Use single use keys in order to improve forward secrecy
|
||||
- context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0)
|
||||
- context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0)
|
||||
-
|
||||
- # disallow ciphers with known vulnerabilities
|
||||
context.set_ciphers(_RESTRICTED_SERVER_CIPHERS)
|
||||
|
||||
if cafile or capath or cadata:
|
||||
@@ -497,12 +481,10 @@ def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=None,
|
||||
if not isinstance(purpose, _ASN1Object):
|
||||
raise TypeError(purpose)
|
||||
|
||||
+ # SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
|
||||
+ # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
|
||||
+ # by default.
|
||||
context = SSLContext(protocol)
|
||||
- # SSLv2 considered harmful.
|
||||
- context.options |= OP_NO_SSLv2
|
||||
- # SSLv3 has problematic security and is only required for really old
|
||||
- # clients such as IE6 on Windows XP
|
||||
- context.options |= OP_NO_SSLv3
|
||||
|
||||
if cert_reqs is not None:
|
||||
context.verify_mode = cert_reqs
|
||||
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
||||
index ffb7314f57..f91af7bd05 100644
|
||||
--- a/Lib/test/test_ssl.py
|
||||
+++ b/Lib/test/test_ssl.py
|
||||
@@ -73,6 +73,12 @@ NULLBYTECERT = data_file("nullbytecert.pem")
|
||||
DHFILE = data_file("dh1024.pem")
|
||||
BYTES_DHFILE = os.fsencode(DHFILE)
|
||||
|
||||
+# Not defined in all versions of OpenSSL
|
||||
+OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0)
|
||||
+OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
|
||||
+OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
|
||||
+OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
|
||||
+
|
||||
|
||||
def handle_error(prefix):
|
||||
exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
|
||||
@@ -839,8 +845,9 @@ class ContextTests(unittest.TestCase):
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||
# OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
|
||||
default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
|
||||
- if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0):
|
||||
- default |= ssl.OP_NO_COMPRESSION
|
||||
+ # SSLContext also enables these by default
|
||||
+ default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE |
|
||||
+ OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE)
|
||||
self.assertEqual(default, ctx.options)
|
||||
ctx.options |= ssl.OP_NO_TLSv1
|
||||
self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
|
||||
@@ -1205,16 +1212,29 @@ class ContextTests(unittest.TestCase):
|
||||
stats["x509"] += 1
|
||||
self.assertEqual(ctx.cert_store_stats(), stats)
|
||||
|
||||
+ def _assert_context_options(self, ctx):
|
||||
+ self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
+ if OP_NO_COMPRESSION != 0:
|
||||
+ self.assertEqual(ctx.options & OP_NO_COMPRESSION,
|
||||
+ OP_NO_COMPRESSION)
|
||||
+ if OP_SINGLE_DH_USE != 0:
|
||||
+ self.assertEqual(ctx.options & OP_SINGLE_DH_USE,
|
||||
+ OP_SINGLE_DH_USE)
|
||||
+ if OP_SINGLE_ECDH_USE != 0:
|
||||
+ self.assertEqual(ctx.options & OP_SINGLE_ECDH_USE,
|
||||
+ OP_SINGLE_ECDH_USE)
|
||||
+ if OP_CIPHER_SERVER_PREFERENCE != 0:
|
||||
+ self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE,
|
||||
+ OP_CIPHER_SERVER_PREFERENCE)
|
||||
+
|
||||
def test_create_default_context(self):
|
||||
ctx = ssl.create_default_context()
|
||||
+
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
|
||||
self.assertTrue(ctx.check_hostname)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
- self.assertEqual(
|
||||
- ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- )
|
||||
+ self._assert_context_options(ctx)
|
||||
+
|
||||
|
||||
with open(SIGNING_CA) as f:
|
||||
cadata = f.read()
|
||||
@@ -1222,40 +1242,24 @@ class ContextTests(unittest.TestCase):
|
||||
cadata=cadata)
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
- self.assertEqual(
|
||||
- ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- )
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
- self.assertEqual(
|
||||
- ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- getattr(ssl, "OP_NO_COMPRESSION", 0),
|
||||
- )
|
||||
- self.assertEqual(
|
||||
- ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0),
|
||||
- getattr(ssl, "OP_SINGLE_DH_USE", 0),
|
||||
- )
|
||||
- self.assertEqual(
|
||||
- ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
|
||||
- getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
|
||||
- )
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
def test__create_stdlib_context(self):
|
||||
ctx = ssl._create_stdlib_context()
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
|
||||
self.assertFalse(ctx.check_hostname)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
|
||||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
@@ -1263,12 +1267,12 @@ class ContextTests(unittest.TestCase):
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
|
||||
self.assertTrue(ctx.check_hostname)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
|
||||
self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
|
||||
self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
|
||||
- self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
|
||||
+ self._assert_context_options(ctx)
|
||||
|
||||
def test_check_hostname(self):
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
|
||||
index 86482677ae..0d5c121d2c 100644
|
||||
--- a/Modules/_ssl.c
|
||||
+++ b/Modules/_ssl.c
|
||||
@@ -2330,6 +2330,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
||||
PySSLContext *self;
|
||||
long options;
|
||||
SSL_CTX *ctx = NULL;
|
||||
+ int result;
|
||||
#if defined(SSL_MODE_RELEASE_BUFFERS)
|
||||
unsigned long libver;
|
||||
#endif
|
||||
@@ -2393,8 +2394,38 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
||||
options |= SSL_OP_NO_SSLv2;
|
||||
if (proto_version != PY_SSL_VERSION_SSL3)
|
||||
options |= SSL_OP_NO_SSLv3;
|
||||
+ /* Minimal security flags for server and client side context.
|
||||
+ * Client sockets ignore server-side parameters. */
|
||||
+#ifdef SSL_OP_NO_COMPRESSION
|
||||
+ options |= SSL_OP_NO_COMPRESSION;
|
||||
+#endif
|
||||
+#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
||||
+ options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
|
||||
+#endif
|
||||
+#ifdef SSL_OP_SINGLE_DH_USE
|
||||
+ options |= SSL_OP_SINGLE_DH_USE;
|
||||
+#endif
|
||||
+#ifdef SSL_OP_SINGLE_ECDH_USE
|
||||
+ options |= SSL_OP_SINGLE_ECDH_USE;
|
||||
+#endif
|
||||
SSL_CTX_set_options(self->ctx, options);
|
||||
|
||||
+ /* A bare minimum cipher list without completly broken cipher suites.
|
||||
+ * It's far from perfect but gives users a better head start. */
|
||||
+ if (proto_version != PY_SSL_VERSION_SSL2) {
|
||||
+ result = SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!eNULL:!MD5");
|
||||
+ } else {
|
||||
+ /* SSLv2 needs MD5 */
|
||||
+ result = SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!eNULL");
|
||||
+ }
|
||||
+ if (result == 0) {
|
||||
+ Py_DECREF(self);
|
||||
+ ERR_clear_error();
|
||||
+ PyErr_SetString(PySSLErrorObject,
|
||||
+ "No cipher can be selected.");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
#if defined(SSL_MODE_RELEASE_BUFFERS)
|
||||
/* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory
|
||||
usage for no cost at all. However, don't do this for OpenSSL versions
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
From 46c719ec4f79d6830c55ab7f5a03d826eabd0bd5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <christian@python.org>
|
||||
Date: Thu, 7 Sep 2017 20:23:52 -0700
|
||||
Subject: [PATCH 2/4] 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 | 14 +++++++++
|
||||
Lib/test/test_ssl.py | 29 ++++++++++++++++++-
|
||||
.../2017-09-04-16-39-49.bpo-29136.vSn1oR.rst | 1 +
|
||||
Modules/_ssl.c | 13 +++++++++
|
||||
5 files changed, 77 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..ac2c0cbaf3 100644
|
||||
--- a/Lib/ssl.py
|
||||
+++ b/Lib/ssl.py
|
||||
@@ -122,6 +122,14 @@ _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 _OPENSSL_API_VERSION
|
||||
+
|
||||
+
|
||||
+_IntEnum._convert(
|
||||
+ '_SSLMethod', __name__,
|
||||
+ lambda name: name.startswith('PROTOCOL_') and name != 'PROTOCOL_SSLv23',
|
||||
+ source=_ssl)
|
||||
|
||||
from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
|
||||
|
||||
@@ -162,6 +170,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 +182,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 +191,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 +202,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
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
From 170a614904febd14ff6cfd7a75c9bccc114b3948 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <christian@python.org>
|
||||
Date: Tue, 14 Aug 2018 16:56:32 +0200
|
||||
Subject: [PATCH] bpo-32947: Fixes for TLS 1.3 and OpenSSL 1.1.1 (GH-8761)
|
||||
|
||||
Backport of TLS 1.3 related fixes from 3.7.
|
||||
|
||||
Misc fixes and workarounds for compatibility with OpenSSL 1.1.1 from git
|
||||
master and TLS 1.3 support. With OpenSSL 1.1.1, Python negotiates TLS 1.3 by
|
||||
default. Some test cases only apply to TLS 1.2.
|
||||
|
||||
OpenSSL 1.1.1 has added a new option OP_ENABLE_MIDDLEBOX_COMPAT for TLS
|
||||
1.3. The feature is enabled by default for maximum compatibility with
|
||||
broken middle boxes. Users should be able to disable the hack and CPython's test suite needs
|
||||
it to verify default options
|
||||
|
||||
Signed-off-by: Christian Heimes <christian@python.org>
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://github.com/python/cpython/commit/2a4ee8aa01d61b6a9c8e9c65c211e61bdb471826]
|
||||
|
||||
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||
---
|
||||
Doc/library/ssl.rst | 9 ++++++
|
||||
Lib/test/test_asyncio/test_events.py | 6 +++-
|
||||
Lib/test/test_ssl.py | 29 +++++++++++++++----
|
||||
.../2018-08-14-08-57-01.bpo-32947.mqStVW.rst | 2 ++
|
||||
Modules/_ssl.c | 4 +++
|
||||
5 files changed, 44 insertions(+), 6 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst
|
||||
|
||||
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
|
||||
index 29c5e94cf6..f63a3deec5 100644
|
||||
--- a/Doc/library/ssl.rst
|
||||
+++ b/Doc/library/ssl.rst
|
||||
@@ -757,6 +757,15 @@ Constants
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
+.. data:: OP_ENABLE_MIDDLEBOX_COMPAT
|
||||
+
|
||||
+ Send dummy Change Cipher Spec (CCS) messages in TLS 1.3 handshake to make
|
||||
+ a TLS 1.3 connection look more like a TLS 1.2 connection.
|
||||
+
|
||||
+ This option is only available with OpenSSL 1.1.1 and later.
|
||||
+
|
||||
+ .. versionadded:: 3.6.7
|
||||
+
|
||||
.. data:: OP_NO_COMPRESSION
|
||||
|
||||
Disable compression on the SSL channel. This is useful if the application
|
||||
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
|
||||
index 492a84a231..6f208474b9 100644
|
||||
--- a/Lib/test/test_asyncio/test_events.py
|
||||
+++ b/Lib/test/test_asyncio/test_events.py
|
||||
@@ -1169,7 +1169,11 @@ class EventLoopTestsMixin:
|
||||
self.loop.run_until_complete(f_c)
|
||||
|
||||
# close connection
|
||||
- proto.transport.close()
|
||||
+ # transport may be None with TLS 1.3, because connection is
|
||||
+ # interrupted, server is unable to send session tickets, and
|
||||
+ # transport is closed.
|
||||
+ if proto.transport is not None:
|
||||
+ proto.transport.close()
|
||||
server.close()
|
||||
|
||||
def test_legacy_create_server_ssl_match_failed(self):
|
||||
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
||||
index 1acc12ec2d..a2e1d32a62 100644
|
||||
--- a/Lib/test/test_ssl.py
|
||||
+++ b/Lib/test/test_ssl.py
|
||||
@@ -78,6 +78,7 @@ OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0)
|
||||
OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
|
||||
OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
|
||||
OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
|
||||
+OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
|
||||
|
||||
|
||||
def handle_error(prefix):
|
||||
@@ -155,8 +156,8 @@ class BasicSocketTests(unittest.TestCase):
|
||||
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
|
||||
|
||||
def test_str_for_enums(self):
|
||||
# Make sure that the PROTOCOL_* constants have enum-like string
|
||||
@@ -854,7 +855,8 @@ class ContextTests(unittest.TestCase):
|
||||
default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
|
||||
# SSLContext also enables these by default
|
||||
default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE |
|
||||
- OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE)
|
||||
+ OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE |
|
||||
+ OP_ENABLE_MIDDLEBOX_COMPAT)
|
||||
self.assertEqual(default, ctx.options)
|
||||
ctx.options |= ssl.OP_NO_TLSv1
|
||||
self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
|
||||
@@ -1860,11 +1862,26 @@ else:
|
||||
self.sock, server_side=True)
|
||||
self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
|
||||
self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
|
||||
- except (ssl.SSLError, ConnectionResetError) as e:
|
||||
+ except (ConnectionResetError, BrokenPipeError) as e:
|
||||
# We treat ConnectionResetError as though it were an
|
||||
# SSLError - OpenSSL on Ubuntu abruptly closes the
|
||||
# connection when asked to use an unsupported protocol.
|
||||
#
|
||||
+ # BrokenPipeError is raised in TLS 1.3 mode, when OpenSSL
|
||||
+ # tries to send session tickets after handshake.
|
||||
+ # https://github.com/openssl/openssl/issues/6342
|
||||
+ self.server.conn_errors.append(str(e))
|
||||
+ if self.server.chatty:
|
||||
+ handle_error(
|
||||
+ "\n server: bad connection attempt from " + repr(
|
||||
+ self.addr) + ":\n")
|
||||
+ self.running = False
|
||||
+ self.close()
|
||||
+ return False
|
||||
+ except (ssl.SSLError, OSError) as e:
|
||||
+ # OSError may occur with wrong protocols, e.g. both
|
||||
+ # sides use PROTOCOL_TLS_SERVER.
|
||||
+ #
|
||||
# XXX Various errors can have happened here, for example
|
||||
# a mismatching protocol version, an invalid certificate,
|
||||
# or a low-level bug. This should be made more discriminating.
|
||||
@@ -2974,7 +2991,7 @@ else:
|
||||
# Block on the accept and wait on the connection to close.
|
||||
evt.set()
|
||||
remote, peer = server.accept()
|
||||
- remote.recv(1)
|
||||
+ remote.send(remote.recv(4))
|
||||
|
||||
t = threading.Thread(target=serve)
|
||||
t.start()
|
||||
@@ -2982,6 +2999,8 @@ else:
|
||||
evt.wait()
|
||||
client = context.wrap_socket(socket.socket())
|
||||
client.connect((host, port))
|
||||
+ client.send(b'data')
|
||||
+ client.recv()
|
||||
client_addr = client.getsockname()
|
||||
client.close()
|
||||
t.join()
|
||||
diff --git a/Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst b/Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst
|
||||
new file mode 100644
|
||||
index 0000000000..28de360c36
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst
|
||||
@@ -0,0 +1,2 @@
|
||||
+Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 for future
|
||||
+compatibility with OpenSSL 1.1.1.
|
||||
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
|
||||
index c71d89607c..eb123a87ba 100644
|
||||
--- a/Modules/_ssl.c
|
||||
+++ b/Modules/_ssl.c
|
||||
@@ -4858,6 +4858,10 @@ PyInit__ssl(void)
|
||||
PyModule_AddIntConstant(m, "OP_NO_COMPRESSION",
|
||||
SSL_OP_NO_COMPRESSION);
|
||||
#endif
|
||||
+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
|
||||
+ PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT",
|
||||
+ SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
|
||||
+#endif
|
||||
|
||||
#if HAVE_SNI
|
||||
r = Py_True;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
From 0c9354362bfa5f90fbea8ff8237a1f1f5dba686f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <christian@python.org>
|
||||
Date: Wed, 12 Sep 2018 15:20:31 +0800
|
||||
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 <christian@python.org>
|
||||
(cherry picked from commit e8eb6cb7920ded66abc5d284319a8539bdc2bae3)
|
||||
|
||||
Co-authored-by: Christian Heimes <christian@python.org
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://github.com/python/cpython/commit/3e630c541b35c96bfe5619165255e559f577ee71]
|
||||
|
||||
Tweaked patch to not take changes for multissltests and Travis config.
|
||||
|
||||
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||
---
|
||||
Lib/test/test_ssl.py | 51 ++++++++++++++++++++++----------------------
|
||||
1 file changed, 26 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
||||
index a2e1d32a62..c484ead5ff 100644
|
||||
--- a/Lib/test/test_ssl.py
|
||||
+++ b/Lib/test/test_ssl.py
|
||||
@@ -3024,17 +3024,21 @@ else:
|
||||
sock.do_handshake()
|
||||
self.assertEqual(cm.exception.errno, errno.ENOTCONN)
|
||||
|
||||
- def test_default_ciphers(self):
|
||||
- context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
- 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_SSLv23,
|
||||
- chatty=False) as server:
|
||||
- with context.wrap_socket(socket.socket()) as s:
|
||||
+ def test_no_shared_ciphers(self):
|
||||
+ server_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
+ server_context.load_cert_chain(SIGNED_CERTFILE)
|
||||
+ client_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
+ client_context.verify_mode = ssl.CERT_REQUIRED
|
||||
+ client_context.check_hostname = True
|
||||
+
|
||||
+ client_context.set_ciphers("AES128")
|
||||
+ server_context.set_ciphers("AES256")
|
||||
+ # OpenSSL enables all TLS 1.3 ciphers, enforce TLS 1.2 for test
|
||||
+ client_context.options |= ssl.OP_NO_TLSv1_3
|
||||
+ with ThreadedEchoServer(context=server_context) as server:
|
||||
+ with client_context.wrap_socket(
|
||||
+ socket.socket(),
|
||||
+ server_hostname="localhost") as s:
|
||||
with self.assertRaises(OSError):
|
||||
s.connect((HOST, server.port))
|
||||
self.assertIn("no shared cipher", str(server.conn_errors[0]))
|
||||
@@ -3067,9 +3071,9 @@ else:
|
||||
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',
|
||||
])
|
||||
|
||||
@unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
|
||||
@@ -3391,22 +3395,19 @@ else:
|
||||
client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||
client_context.verify_mode = ssl.CERT_REQUIRED
|
||||
client_context.load_verify_locations(SIGNING_CA)
|
||||
- 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)
|
||||
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):
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From 7b40cb7293cb14e5c7c8ed123efaf9acb33edae2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Heimes <christian@python.org>
|
||||
Date: Tue, 15 Aug 2017 10:33:43 +0200
|
||||
Subject: [PATCH] bpo-30714: ALPN changes for OpenSSL 1.1.0f (#2305)
|
||||
|
||||
OpenSSL 1.1.0 to 1.1.0e aborted the handshake when server and client
|
||||
could not agree on a protocol using ALPN. OpenSSL 1.1.0f changed that.
|
||||
The most recent version now behaves like OpenSSL 1.0.2 again. The ALPN
|
||||
callback can pretend to not been set.
|
||||
|
||||
See https://github.com/openssl/openssl/pull/3158 for more details
|
||||
|
||||
Signed-off-by: Christian Heimes <christian@python.org>
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://github.com/python/cpython/commit/7b40cb7293cb14e5c7c8ed123efaf9acb33edae2]
|
||||
|
||||
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||
---
|
||||
Doc/library/ssl.rst | 5 +++--
|
||||
Lib/test/test_ssl.py | 5 +++--
|
||||
.../next/Tests/2017-07-25-15-27-44.bpo-30715.Sp7bTF.rst | 2 ++
|
||||
3 files changed, 8 insertions(+), 4 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Tests/2017-07-25-15-27-44.bpo-30715.Sp7bTF.rst
|
||||
|
||||
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
|
||||
index 729a239a1b..0a09e7e9d4 100644
|
||||
--- a/Doc/library/ssl.rst
|
||||
+++ b/Doc/library/ssl.rst
|
||||
@@ -1447,8 +1447,9 @@ to speed up repeated connections from the same clients.
|
||||
This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is
|
||||
False.
|
||||
|
||||
- OpenSSL 1.1.0+ will abort the handshake and raise :exc:`SSLError` when
|
||||
- both sides support ALPN but cannot agree on a protocol.
|
||||
+ OpenSSL 1.1.0 to 1.1.0e will abort the handshake and raise :exc:`SSLError`
|
||||
+ when both sides support ALPN but cannot agree on a protocol. 1.1.0f+
|
||||
+ behaves like 1.0.2, :meth:`SSLSocket.selected_alpn_protocol` returns None.
|
||||
|
||||
.. versionadded:: 3.5
|
||||
|
||||
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
|
||||
index d960d82065..104b7f377a 100644
|
||||
--- a/Lib/test/test_ssl.py
|
||||
+++ b/Lib/test/test_ssl.py
|
||||
@@ -3268,8 +3268,9 @@ if _have_threads:
|
||||
except ssl.SSLError as e:
|
||||
stats = e
|
||||
|
||||
- if expected is None and IS_OPENSSL_1_1:
|
||||
- # OpenSSL 1.1.0 raises handshake error
|
||||
+ if (expected is None and IS_OPENSSL_1_1
|
||||
+ 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" \
|
||||
diff --git a/Misc/NEWS.d/next/Tests/2017-07-25-15-27-44.bpo-30715.Sp7bTF.rst b/Misc/NEWS.d/next/Tests/2017-07-25-15-27-44.bpo-30715.Sp7bTF.rst
|
||||
new file mode 100644
|
||||
index 0000000000..88394e585c
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Tests/2017-07-25-15-27-44.bpo-30715.Sp7bTF.rst
|
||||
@@ -0,0 +1,2 @@
|
||||
+Address ALPN callback changes for OpenSSL 1.1.0f. The latest version behaves
|
||||
+like OpenSSL 1.0.2 and no longer aborts handshake.
|
||||
--
|
||||
2.17.1
|
||||
|
||||
Reference in New Issue
Block a user