From dba6346d5329f88c2af8bf9203fed0ee0a92927e Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 11 May 2019 13:39:44 -0700 Subject: [PATCH] [2.7] bpo-35925: Skip SSL tests that fail due to weak external certs or old TLS (GH-13124) Modern Linux distros such as Debian Buster have default OpenSSL system configurations that reject connections to servers with weak certificates by default. This causes our test suite run with external networking resources enabled to skip these tests when they encounter such a failure. Fixing the network servers is a separate issue. (cherry picked from commit 2cc0223) Changes to test_ssl.py required as 2.7 has legacy protocol tests. The test_httplib.py change is omitted from this backport as self-signed.pythontest.net's certificate was updated and the test_nntplib.py change is not applicable on 2.7. Authored-by: Gregory P. Smith greg@krypto.org --- Lib/test/test_ssl.py | 33 +++++++++++++++++++ .../2019-05-06-18-29-54.bpo-35925.gwQPuC.rst | 1 + 2 files changed, 34 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 0eecc781d9e6c8..ef2e59c1d15d06 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -19,6 +19,7 @@ import traceback import weakref import platform +import re import functools from contextlib import closing @@ -159,6 +160,36 @@ def f(*args, **kwargs): else: return func +def skip_if_openssl_cnf_minprotocol_gt_tls1(func): + """Skip a test if the OpenSSL config MinProtocol is > TLSv1. + OS distros with an /etc/ssl/openssl.cnf and MinProtocol set often do so to + require TLSv1.2 or higher (Debian Buster). Some of our tests for older + protocol versions will fail under such a config. + Alternative workaround: Run this test in a process with + OPENSSL_CONF=/dev/null in the environment. + """ + @functools.wraps(func) + def f(*args, **kwargs): + openssl_cnf = os.environ.get("OPENSSL_CONF", "/etc/ssl/openssl.cnf") + try: + with open(openssl_cnf, "r") as config: + for line in config: + match = re.match(r"MinProtocol\s*=\s*(TLSv\d+\S*)", line) + if match: + tls_ver = match.group(1) + if tls_ver > "TLSv1": + raise unittest.SkipTest( + "%s has MinProtocol = %s which is > TLSv1." % + (openssl_cnf, tls_ver)) + except (EnvironmentError, UnicodeDecodeError) as err: + # no config file found, etc. + if support.verbose: + sys.stdout.write("\n Could not scan %s for MinProtocol: %s\n" + % (openssl_cnf, err)) + return func(*args, **kwargs) + return f + + needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test") @@ -2351,6 +2382,7 @@ def test_protocol_sslv2(self): client_options=ssl.OP_NO_TLSv1) @skip_if_broken_ubuntu_ssl + @skip_if_openssl_cnf_minprotocol_gt_tls1 def test_protocol_sslv23(self): """Connecting to an SSLv23 server with various client options""" if support.verbose: @@ -2428,6 +2460,7 @@ def test_protocol_tlsv1(self): @skip_if_broken_ubuntu_ssl @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"), "TLS version 1.1 not supported.") + @skip_if_openssl_cnf_minprotocol_gt_tls1 def test_protocol_tlsv1_1(self): """Connecting to a TLSv1.1 server with various client options. Testing against older TLS versions.""" diff --git a/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst b/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst new file mode 100644 index 00000000000000..428326cdfe5bba --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst @@ -0,0 +1 @@ +Skip specific nntplib and ssl networking tests when they would otherwise fail due to a modern OS or distro with a default OpenSSL policy of rejecting connections to servers with weak certificates or disabling TLS below TLSv1.2.