]> code.ossystems Code Review - openembedded-core.git/blob
56d591d1b526398fb8ddda758bf3c925411566ca
[openembedded-core.git] /
1 From 170a614904febd14ff6cfd7a75c9bccc114b3948 Mon Sep 17 00:00:00 2001
2 From: Christian Heimes <christian@python.org>
3 Date: Tue, 14 Aug 2018 16:56:32 +0200
4 Subject: [PATCH] bpo-32947: Fixes for TLS 1.3 and OpenSSL 1.1.1 (GH-8761)
5
6 Backport of TLS 1.3 related fixes from 3.7.
7
8 Misc fixes and workarounds for compatibility with OpenSSL 1.1.1 from git
9 master and TLS 1.3 support. With OpenSSL 1.1.1, Python negotiates TLS 1.3 by
10 default. Some test cases only apply to TLS 1.2.
11
12 OpenSSL 1.1.1 has added a new option OP_ENABLE_MIDDLEBOX_COMPAT for TLS
13 1.3. The feature is enabled by default for maximum compatibility with
14 broken middle boxes. Users should be able to disable the hack and CPython's test suite needs
15 it to verify default options
16
17 Signed-off-by: Christian Heimes <christian@python.org>
18
19 Upstream-Status: Backport
20 [https://github.com/python/cpython/commit/2a4ee8aa01d61b6a9c8e9c65c211e61bdb471826]
21
22 Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
23 ---
24  Doc/library/ssl.rst                           |  9 ++++++
25  Lib/test/test_asyncio/test_events.py          |  6 +++-
26  Lib/test/test_ssl.py                          | 29 +++++++++++++++----
27  .../2018-08-14-08-57-01.bpo-32947.mqStVW.rst  |  2 ++
28  Modules/_ssl.c                                |  4 +++
29  5 files changed, 44 insertions(+), 6 deletions(-)
30  create mode 100644 Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst
31
32 diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
33 index 29c5e94cf6..f63a3deec5 100644
34 --- a/Doc/library/ssl.rst
35 +++ b/Doc/library/ssl.rst
36 @@ -757,6 +757,15 @@ Constants
37  
38     .. versionadded:: 3.3
39  
40 +.. data:: OP_ENABLE_MIDDLEBOX_COMPAT
41 +
42 +   Send dummy Change Cipher Spec (CCS) messages in TLS 1.3 handshake to make
43 +   a TLS 1.3 connection look more like a TLS 1.2 connection.
44 +
45 +   This option is only available with OpenSSL 1.1.1 and later.
46 +
47 +   .. versionadded:: 3.6.7
48 +
49  .. data:: OP_NO_COMPRESSION
50  
51     Disable compression on the SSL channel.  This is useful if the application
52 diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
53 index 492a84a231..6f208474b9 100644
54 --- a/Lib/test/test_asyncio/test_events.py
55 +++ b/Lib/test/test_asyncio/test_events.py
56 @@ -1169,7 +1169,11 @@ class EventLoopTestsMixin:
57                      self.loop.run_until_complete(f_c)
58  
59          # close connection
60 -        proto.transport.close()
61 +        # transport may be None with TLS 1.3, because connection is
62 +        # interrupted, server is unable to send session tickets, and
63 +        # transport is closed.
64 +        if proto.transport is not None:
65 +            proto.transport.close()
66          server.close()
67  
68      def test_legacy_create_server_ssl_match_failed(self):
69 diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
70 index 1acc12ec2d..a2e1d32a62 100644
71 --- a/Lib/test/test_ssl.py
72 +++ b/Lib/test/test_ssl.py
73 @@ -78,6 +78,7 @@ OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0)
74  OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
75  OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
76  OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
77 +OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
78  
79  
80  def handle_error(prefix):
81 @@ -155,8 +156,8 @@ class BasicSocketTests(unittest.TestCase):
82          ssl.OP_NO_TLSv1
83          ssl.OP_NO_TLSv1_3
84      if ssl.OPENSSL_VERSION_INFO >= (1, 0, 1):
85 -            ssl.OP_NO_TLSv1_1
86 -            ssl.OP_NO_TLSv1_2
87 +        ssl.OP_NO_TLSv1_1
88 +        ssl.OP_NO_TLSv1_2
89  
90      def test_str_for_enums(self):
91          # Make sure that the PROTOCOL_* constants have enum-like string
92 @@ -854,7 +855,8 @@ class ContextTests(unittest.TestCase):
93          default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
94          # SSLContext also enables these by default
95          default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE |
96 -                    OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE)
97 +                    OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE |
98 +                    OP_ENABLE_MIDDLEBOX_COMPAT)
99          self.assertEqual(default, ctx.options)
100          ctx.options |= ssl.OP_NO_TLSv1
101          self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
102 @@ -1860,11 +1862,26 @@ else:
103                          self.sock, server_side=True)
104                      self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
105                      self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
106 -                except (ssl.SSLError, ConnectionResetError) as e:
107 +                except (ConnectionResetError, BrokenPipeError) as e:
108                      # We treat ConnectionResetError as though it were an
109                      # SSLError - OpenSSL on Ubuntu abruptly closes the
110                      # connection when asked to use an unsupported protocol.
111                      #
112 +                    # BrokenPipeError is raised in TLS 1.3 mode, when OpenSSL
113 +                    # tries to send session tickets after handshake.
114 +                    # https://github.com/openssl/openssl/issues/6342
115 +                    self.server.conn_errors.append(str(e))
116 +                    if self.server.chatty:
117 +                        handle_error(
118 +                            "\n server:  bad connection attempt from " + repr(
119 +                                self.addr) + ":\n")
120 +                    self.running = False
121 +                    self.close()
122 +                    return False
123 +                except (ssl.SSLError, OSError) as e:
124 +                    # OSError may occur with wrong protocols, e.g. both
125 +                    # sides use PROTOCOL_TLS_SERVER.
126 +                    #
127                      # XXX Various errors can have happened here, for example
128                      # a mismatching protocol version, an invalid certificate,
129                      # or a low-level bug. This should be made more discriminating.
130 @@ -2974,7 +2991,7 @@ else:
131                  # Block on the accept and wait on the connection to close.
132                  evt.set()
133                  remote, peer = server.accept()
134 -                remote.recv(1)
135 +                remote.send(remote.recv(4))
136  
137              t = threading.Thread(target=serve)
138              t.start()
139 @@ -2982,6 +2999,8 @@ else:
140              evt.wait()
141              client = context.wrap_socket(socket.socket())
142              client.connect((host, port))
143 +            client.send(b'data')
144 +            client.recv()
145              client_addr = client.getsockname()
146              client.close()
147              t.join()
148 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
149 new file mode 100644
150 index 0000000000..28de360c36
151 --- /dev/null
152 +++ b/Misc/NEWS.d/next/Library/2018-08-14-08-57-01.bpo-32947.mqStVW.rst
153 @@ -0,0 +1,2 @@
154 +Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 for future
155 +compatibility with OpenSSL 1.1.1.
156 diff --git a/Modules/_ssl.c b/Modules/_ssl.c
157 index c71d89607c..eb123a87ba 100644
158 --- a/Modules/_ssl.c
159 +++ b/Modules/_ssl.c
160 @@ -4858,6 +4858,10 @@ PyInit__ssl(void)
161      PyModule_AddIntConstant(m, "OP_NO_COMPRESSION",
162                              SSL_OP_NO_COMPRESSION);
163  #endif
164 +#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
165 +    PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT",
166 +                            SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
167 +#endif
168  
169  #if HAVE_SNI
170      r = Py_True;
171 -- 
172 2.17.1
173