bpo-41561: Add workaround for Ubuntu's custom security level (GH-24915)

Ubuntu 20.04 comes with a patched OpenSSL 1.1.1. Default security level
2 blocks TLS 1.0 and 1.1 connections. Regular OpenSSL 1.1.1 builds allow
TLS 1.0 and 1.1 on security level 2.

See:
See: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1899878
See: https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1917625
Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit f6c6b5821b)

Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
Miss Islington (bot) 2021-03-18 15:31:34 -07:00 committed by GitHub
parent 4cc9e2348b
commit 3365e684a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 1 deletions

View File

@ -121,7 +121,7 @@ jobs:
build_ubuntu:
name: 'Ubuntu'
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
needs: check_source
if: needs.check_source.outputs.run_tests == 'true'
env:

View File

@ -147,6 +147,27 @@ def data_file(*name):
OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
# Ubuntu has patched OpenSSL and changed behavior of security level 2
# see https://bugs.python.org/issue41561#msg389003
def is_ubuntu():
try:
# Assume that any references of "ubuntu" implies Ubuntu-like distro
# The workaround is not required for 18.04, but doesn't hurt either.
with open("/etc/os-release", encoding="utf-8") as f:
return "ubuntu" in f.read()
except FileNotFoundError:
return False
if is_ubuntu():
def seclevel_workaround(*ctxs):
""""Lower security level to '1' and allow all ciphers for TLS 1.0/1"""
for ctx in ctxs:
if ctx.minimum_version <= ssl.TLSVersion.TLSv1_1:
ctx.set_ciphers("@SECLEVEL=1:ALL")
else:
def seclevel_workaround(*ctxs):
pass
def has_tls_protocol(protocol):
"""Check if a TLS protocol is available and enabled
@ -2777,6 +2798,8 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
if client_context.protocol == ssl.PROTOCOL_TLS:
client_context.set_ciphers("ALL")
seclevel_workaround(server_context, client_context)
for ctx in (client_context, server_context):
ctx.verify_mode = certsreqs
ctx.load_cert_chain(SIGNED_CERTFILE)
@ -2818,6 +2841,7 @@ def test_echo(self):
with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
context = ssl.SSLContext(protocol)
context.load_cert_chain(CERTFILE)
seclevel_workaround(context)
server_params_test(context, context,
chatty=True, connectionchatty=True)
@ -3822,6 +3846,7 @@ def test_min_max_version_tlsv1_1(self):
client_context.maximum_version = ssl.TLSVersion.TLSv1_2
server_context.minimum_version = ssl.TLSVersion.TLSv1
server_context.maximum_version = ssl.TLSVersion.TLSv1_1
seclevel_workaround(client_context, server_context)
with ThreadedEchoServer(context=server_context) as server:
with client_context.wrap_socket(socket.socket(),
@ -3839,6 +3864,8 @@ def test_min_max_version_mismatch(self):
server_context.minimum_version = ssl.TLSVersion.TLSv1_2
client_context.maximum_version = ssl.TLSVersion.TLSv1
client_context.minimum_version = ssl.TLSVersion.TLSv1
seclevel_workaround(client_context, server_context)
with ThreadedEchoServer(context=server_context) as server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as s:
@ -3853,6 +3880,8 @@ def test_min_max_version_sslv3(self):
server_context.minimum_version = ssl.TLSVersion.SSLv3
client_context.minimum_version = ssl.TLSVersion.SSLv3
client_context.maximum_version = ssl.TLSVersion.SSLv3
seclevel_workaround(client_context, server_context)
with ThreadedEchoServer(context=server_context) as server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as s:

View File

@ -0,0 +1 @@
Add workaround for Ubuntu's custom OpenSSL security level policy.