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
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)
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)
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(),
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:
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: