Skip to content

Commit 05d9fe3

Browse files
authored
bpo-32947: OpenSSL 1.1.1-pre1 / TLS 1.3 fixes (#5663)
* bpo-32947: OpenSSL 1.1.1-pre1 / TLS 1.3 fixes Misc fixes and workarounds for compatibility with OpenSSL 1.1.1-pre1 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. Other tests currently fail because the threaded or async test servers stop after failure. I'm going to address these issues when OpenSSL 1.1.1 reaches beta. 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 <[email protected]>
1 parent 2fa6b9e commit 05d9fe3

File tree

9 files changed

+131
-74
lines changed

9 files changed

+131
-74
lines changed

Doc/library/ssl.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,15 @@ Constants
831831

832832
.. versionadded:: 3.3
833833

834+
.. data:: OP_ENABLE_MIDDLEBOX_COMPAT
835+
836+
Send dummy Change Cipher Spec (CCS) messages in TLS 1.3 handshake to make
837+
a TLS 1.3 connection look more like a TLS 1.2 connection.
838+
839+
This option is only available with OpenSSL 1.1.1 and later.
840+
841+
.. versionadded:: 3.8
842+
834843
.. data:: OP_NO_COMPRESSION
835844

836845
Disable compression on the SSL channel. This is useful if the application

Doc/whatsnew/3.7.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,9 @@ expected hostname in A-label form (``"xn--pythn-mua.org"``), rather
669669
than the U-label form (``"pythön.org"``). (Contributed by
670670
Nathaniel J. Smith and Christian Heimes in :issue:`28414`.)
671671

672+
The ssl module has preliminary and experimental support for TLS 1.3 and
673+
OpenSSL 1.1.1. (Contributed by Christian Heimes in :issue:`32947`,
674+
:issue:`20995`, :issue:`29136`, and :issue:`30622`)
672675

673676
string
674677
------

Lib/test/test_asyncio/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def simple_server_sslcontext():
7474
server_context.load_cert_chain(ONLYCERT, ONLYKEY)
7575
server_context.check_hostname = False
7676
server_context.verify_mode = ssl.CERT_NONE
77+
# TODO: fix TLSv1.3 support
78+
server_context.options |= ssl.OP_NO_TLSv1_3
7779
return server_context
7880

7981

Lib/test/test_ftplib.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ class SSLConnection(asyncore.dispatcher):
312312

313313
def secure_connection(self):
314314
context = ssl.SSLContext()
315+
# TODO: fix TLSv1.3 support
316+
context.options |= ssl.OP_NO_TLSv1_3
315317
context.load_cert_chain(CERTFILE)
316318
socket = context.wrap_socket(self.socket,
317319
suppress_ragged_eofs=False,
@@ -908,6 +910,8 @@ def test_auth_issued_twice(self):
908910
def test_context(self):
909911
self.client.quit()
910912
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
913+
# TODO: fix TLSv1.3 support
914+
ctx.options |= ssl.OP_NO_TLSv1_3
911915
ctx.check_hostname = False
912916
ctx.verify_mode = ssl.CERT_NONE
913917
self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE,
@@ -940,6 +944,8 @@ def test_ccc(self):
940944
def test_check_hostname(self):
941945
self.client.quit()
942946
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
947+
# TODO: fix TLSv1.3 support
948+
ctx.options |= ssl.OP_NO_TLSv1_3
943949
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
944950
self.assertEqual(ctx.check_hostname, True)
945951
ctx.load_verify_locations(CAFILE)

Lib/test/test_poplib.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ def cmd_stls(self, arg):
153153
if self.tls_active is False:
154154
self.push('+OK Begin TLS negotiation')
155155
context = ssl.SSLContext()
156+
# TODO: fix TLSv1.3 support
157+
context.options |= ssl.OP_NO_TLSv1_3
156158
context.load_cert_chain(CERTFILE)
157159
tls_sock = context.wrap_socket(self.socket,
158160
server_side=True,
@@ -356,6 +358,8 @@ def test_stls(self):
356358
def test_stls_context(self):
357359
expected = b'+OK Begin TLS negotiation'
358360
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
361+
# TODO: fix TLSv1.3 support
362+
ctx.options |= ssl.OP_NO_TLSv1_3
359363
ctx.load_verify_locations(CAFILE)
360364
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
361365
self.assertEqual(ctx.check_hostname, True)
@@ -396,6 +400,8 @@ def test__all__(self):
396400

397401
def test_context(self):
398402
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
403+
# TODO: fix TLSv1.3 support
404+
ctx.options |= ssl.OP_NO_TLSv1_3
399405
ctx.check_hostname = False
400406
ctx.verify_mode = ssl.CERT_NONE
401407
self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,

0 commit comments

Comments
 (0)