Skip to content

Commit 64be96a

Browse files
authored
[3.7] bpo-41561: Add workaround for Ubuntu's custom security level (GH-24915) (GH-24928)
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 f6c6b58) Co-authored-by: Christian Heimes <christian@python.org>
1 parent 2f01c56 commit 64be96a

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373

7474
build_ubuntu:
7575
name: 'Ubuntu'
76-
runs-on: ubuntu-18.04
76+
runs-on: ubuntu-20.04
7777
needs: check_source
7878
if: needs.check_source.outputs.run_tests == 'true'
7979
env:

Lib/test/test_ssl.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,27 @@ def data_file(*name):
142142
OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
143143
OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
144144

145+
# Ubuntu has patched OpenSSL and changed behavior of security level 2
146+
# see https://bugs.python.org/issue41561#msg389003
147+
def is_ubuntu():
148+
try:
149+
# Assume that any references of "ubuntu" implies Ubuntu-like distro
150+
# The workaround is not required for 18.04, but doesn't hurt either.
151+
with open("/etc/os-release", encoding="utf-8") as f:
152+
return "ubuntu" in f.read()
153+
except FileNotFoundError:
154+
return False
155+
156+
if is_ubuntu():
157+
def seclevel_workaround(*ctxs):
158+
""""Lower security level to '1' and allow all ciphers for TLS 1.0/1"""
159+
for ctx in ctxs:
160+
if ctx.minimum_version <= ssl.TLSVersion.TLSv1_1:
161+
ctx.set_ciphers("@SECLEVEL=1:ALL")
162+
else:
163+
def seclevel_workaround(*ctxs):
164+
pass
165+
145166

146167
def has_tls_protocol(protocol):
147168
"""Check if a TLS protocol is available and enabled
@@ -2778,6 +2799,8 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success,
27782799
if client_context.protocol == ssl.PROTOCOL_TLS:
27792800
client_context.set_ciphers("ALL")
27802801

2802+
seclevel_workaround(server_context, client_context)
2803+
27812804
for ctx in (client_context, server_context):
27822805
ctx.verify_mode = certsreqs
27832806
ctx.load_cert_chain(SIGNED_CERTFILE)
@@ -2820,6 +2843,7 @@ def test_echo(self):
28202843
with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
28212844
context = ssl.SSLContext(protocol)
28222845
context.load_cert_chain(CERTFILE)
2846+
seclevel_workaround(context)
28232847
server_params_test(context, context,
28242848
chatty=True, connectionchatty=True)
28252849

@@ -3825,6 +3849,7 @@ def test_min_max_version_tlsv1_1(self):
38253849
client_context.maximum_version = ssl.TLSVersion.TLSv1_2
38263850
server_context.minimum_version = ssl.TLSVersion.TLSv1
38273851
server_context.maximum_version = ssl.TLSVersion.TLSv1_1
3852+
seclevel_workaround(client_context, server_context)
38283853

38293854
with ThreadedEchoServer(context=server_context) as server:
38303855
with client_context.wrap_socket(socket.socket(),
@@ -3841,6 +3866,8 @@ def test_min_max_version_mismatch(self):
38413866
server_context.maximum_version = ssl.TLSVersion.TLSv1_2
38423867
client_context.minimum_version = ssl.TLSVersion.TLSv1
38433868
client_context.maximum_version = ssl.TLSVersion.TLSv1
3869+
seclevel_workaround(client_context, server_context)
3870+
38443871
with ThreadedEchoServer(context=server_context) as server:
38453872
with client_context.wrap_socket(socket.socket(),
38463873
server_hostname=hostname) as s:
@@ -3855,6 +3882,8 @@ def test_min_max_version_sslv3(self):
38553882
server_context.minimum_version = ssl.TLSVersion.SSLv3
38563883
client_context.minimum_version = ssl.TLSVersion.SSLv3
38573884
client_context.maximum_version = ssl.TLSVersion.SSLv3
3885+
seclevel_workaround(client_context, server_context)
3886+
38583887
with ThreadedEchoServer(context=server_context) as server:
38593888
with client_context.wrap_socket(socket.socket(),
38603889
server_hostname=hostname) as s:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add workaround for Ubuntu's custom OpenSSL security level policy.

0 commit comments

Comments
 (0)