Skip to content

Commit

Permalink
bpo-32947: OpenSSL 1.1.1-pre1 / TLS 1.3 fixes (python#5663)
Browse files Browse the repository at this point in the history
* 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 <christian@python.org>
  • Loading branch information
tiran committed Feb 27, 2018
1 parent 2fa6b9e commit 05d9fe3
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 74 deletions.
9 changes: 9 additions & 0 deletions Doc/library/ssl.rst
Expand Up @@ -831,6 +831,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.8

.. data:: OP_NO_COMPRESSION

Disable compression on the SSL channel. This is useful if the application
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.7.rst
Expand Up @@ -669,6 +669,9 @@ expected hostname in A-label form (``"xn--pythn-mua.org"``), rather
than the U-label form (``"pythön.org"``). (Contributed by
Nathaniel J. Smith and Christian Heimes in :issue:`28414`.)

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

string
------
Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_asyncio/utils.py
Expand Up @@ -74,6 +74,8 @@ def simple_server_sslcontext():
server_context.load_cert_chain(ONLYCERT, ONLYKEY)
server_context.check_hostname = False
server_context.verify_mode = ssl.CERT_NONE
# TODO: fix TLSv1.3 support
server_context.options |= ssl.OP_NO_TLSv1_3
return server_context


Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_ftplib.py
Expand Up @@ -312,6 +312,8 @@ class SSLConnection(asyncore.dispatcher):

def secure_connection(self):
context = ssl.SSLContext()
# TODO: fix TLSv1.3 support
context.options |= ssl.OP_NO_TLSv1_3
context.load_cert_chain(CERTFILE)
socket = context.wrap_socket(self.socket,
suppress_ragged_eofs=False,
Expand Down Expand Up @@ -908,6 +910,8 @@ def test_auth_issued_twice(self):
def test_context(self):
self.client.quit()
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# TODO: fix TLSv1.3 support
ctx.options |= ssl.OP_NO_TLSv1_3
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE,
Expand Down Expand Up @@ -940,6 +944,8 @@ def test_ccc(self):
def test_check_hostname(self):
self.client.quit()
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# TODO: fix TLSv1.3 support
ctx.options |= ssl.OP_NO_TLSv1_3
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
self.assertEqual(ctx.check_hostname, True)
ctx.load_verify_locations(CAFILE)
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_poplib.py
Expand Up @@ -153,6 +153,8 @@ def cmd_stls(self, arg):
if self.tls_active is False:
self.push('+OK Begin TLS negotiation')
context = ssl.SSLContext()
# TODO: fix TLSv1.3 support
context.options |= ssl.OP_NO_TLSv1_3
context.load_cert_chain(CERTFILE)
tls_sock = context.wrap_socket(self.socket,
server_side=True,
Expand Down Expand Up @@ -356,6 +358,8 @@ def test_stls(self):
def test_stls_context(self):
expected = b'+OK Begin TLS negotiation'
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# TODO: fix TLSv1.3 support
ctx.options |= ssl.OP_NO_TLSv1_3
ctx.load_verify_locations(CAFILE)
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
self.assertEqual(ctx.check_hostname, True)
Expand Down Expand Up @@ -396,6 +400,8 @@ def test__all__(self):

def test_context(self):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
# TODO: fix TLSv1.3 support
ctx.options |= ssl.OP_NO_TLSv1_3
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,
Expand Down

0 comments on commit 05d9fe3

Please sign in to comment.