From 023803647ff933fdbbea3cb5f9f9487232c2fc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Sat, 27 Jan 2024 18:56:42 +0100 Subject: [PATCH] Update with all development for OpenSSL 3.1.4. Especially: - Add bpo31429_define-TLS-cipher-suite.patch defines TLS cipher suite on build time (add --with-ssl-default-suites option to ./configure; from gh#python/cpython!3532). --- python36.changes | 3 + python36.spec | 10 +- switch-to-PROTOCOL_TLS_CLIENT.patch | 155 ++++++++++++++-------------- 3 files changed, 89 insertions(+), 79 deletions(-) diff --git a/python36.changes b/python36.changes index 52c1a07..883e245 100644 --- a/python36.changes +++ b/python36.changes @@ -26,6 +26,9 @@ Thu Jan 11 15:14:09 UTC 2024 - Matej Cepl (from gh#python/cpython!100373/files) to stopping SSLContext.load_verify_locations from accepting some cases of trailing data in DER. +- Add bpo31429_define-TLS-cipher-suite.patch defines TLS cipher + suite on build time (add --with-ssl-default-suites option to + ./configure; from gh#python/cpython!3532). - Add switch-to-PROTOCOL_TLS_CLIENT.patch switching to PROTOCOL_TLS_CLIENT for testing. diff --git a/python36.spec b/python36.spec index 2c2c103..c28bbd6 100644 --- a/python36.spec +++ b/python36.spec @@ -257,9 +257,13 @@ Patch63: bpo43920-fix-load_verify_locations-errmsgs.patch # PATCH-FIX-UPSTREAM gh100372-SSLContext_load_verify_locations-trailing-data.patch bsc#1217782 mcepl@suse.com # SSLContext.load_verify_locations stop accepting some cases of trailing data in DER (from gh#python/cpython!100373) Patch64: gh100372-SSLContext_load_verify_locations-trailing-data.patch +# PATCH-FIX-UPSTREAM bpo31429_define-TLS-cipher-suite.patch bsc#1217782 mcepl@suse.com +# default to OpenSSL DEFAULT cipher suite selection and black list all unwanted ciphers +# (add --with-ssl-default-suites option to ./configure; from gh#python/cpython!3532). +Patch65: bpo31429_define-TLS-cipher-suite.patch # PATCH-FIX-UPSTREAM switch-to-PROTOCOL_TLS_CLIENT.patch bsc#1217782 mcepl@suse.com # switching to PROTOCOL_TLS settings for testing -Patch65: switch-to-PROTOCOL_TLS_CLIENT.patch +Patch66: switch-to-PROTOCOL_TLS_CLIENT.patch BuildRequires: automake BuildRequires: fdupes BuildRequires: gmp-devel @@ -564,6 +568,7 @@ other applications. %patch -P 63 -p1 %patch -P 64 -p1 %patch -P 65 -p1 +%patch -P 66 -p1 # drop Autoconf version requirement sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac @@ -646,7 +651,8 @@ sed -e 's/-fprofile-correction//' -i Makefile.pre.in %if %{with profileopt} --enable-optimizations \ %endif - --enable-loadable-sqlite-extensions + --enable-loadable-sqlite-extensions \ + --with-ssl-default-suites=openssl # prevent make from trying to rebuild PYTHON_FOR_GEN stuff %make_build -t Python/Python-ast.c \ diff --git a/switch-to-PROTOCOL_TLS_CLIENT.patch b/switch-to-PROTOCOL_TLS_CLIENT.patch index 3dc1a03..3b65e46 100644 --- a/switch-to-PROTOCOL_TLS_CLIENT.patch +++ b/switch-to-PROTOCOL_TLS_CLIENT.patch @@ -1,6 +1,6 @@ --- - Lib/test/test_ssl.py | 516 +++++++++++++++++++++++++++------------------------ - 1 file changed, 282 insertions(+), 234 deletions(-) + Lib/test/test_ssl.py | 510 +++++++++++++++++++++++++++------------------------ + 1 file changed, 275 insertions(+), 235 deletions(-) Index: Python-3.6.15/Lib/test/test_ssl.py =================================================================== @@ -11,10 +11,10 @@ Index: Python-3.6.15/Lib/test/test_ssl.py import re import functools +import warnings + import sysconfig try: import ctypes - except ImportError: -@@ -71,6 +72,7 @@ CRLFILE = data_file("revocation.crl") +@@ -73,6 +74,7 @@ CRLFILE = data_file("revocation.crl") # Two keys and certs signed by the same CA (for SNI tests) SIGNED_CERTFILE = data_file("keycert3.pem") @@ -22,7 +22,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py SIGNED_CERTFILE2 = data_file("keycert4.pem") # Same certificate as pycacert.pem, but without extra text in file SIGNING_CA = data_file("capath", "ceff1710.0") -@@ -203,15 +205,17 @@ def skip_if_openssl_cnf_minprotocol_gt_t +@@ -205,15 +207,17 @@ def skip_if_openssl_cnf_minprotocol_gt_t return f @@ -41,7 +41,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py if cert_reqs is not None: context.verify_mode = cert_reqs if ca_certs is not None: -@@ -222,6 +226,30 @@ def test_wrap_socket(sock, ssl_version=s +@@ -224,6 +228,30 @@ def test_wrap_socket(sock, ssl_version=s context.set_ciphers(ciphers) return context.wrap_socket(sock, **kwargs) @@ -72,7 +72,16 @@ Index: Python-3.6.15/Lib/test/test_ssl.py class BasicSocketTests(unittest.TestCase): def test_constants(self): -@@ -543,7 +571,8 @@ class BasicSocketTests(unittest.TestCase +@@ -466,7 +494,7 @@ class BasicSocketTests(unittest.TestCase + self.assertTrue(s.startswith("LibreSSL {:d}".format(major)), + (s, t, hex(n))) + else: +- self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), ++ self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, patch)), + (s, t, hex(n))) + + @support.cpython_only +@@ -545,7 +573,8 @@ class BasicSocketTests(unittest.TestCase with self.assertRaises(ssl.SSLError): test_wrap_socket(sock, certfile=certfile, @@ -82,7 +91,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py def test_empty_cert(self): """Wrapping with an empty cert file""" -@@ -972,7 +1001,7 @@ class ContextTests(unittest.TestCase): +@@ -974,7 +1003,7 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.protocol, proto) def test_ciphers(self): @@ -91,7 +100,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.set_ciphers("ALL") ctx.set_ciphers("DEFAULT") with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): -@@ -980,7 +1009,7 @@ class ContextTests(unittest.TestCase): +@@ -995,7 +1024,7 @@ class ContextTests(unittest.TestCase): @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old') def test_get_ciphers(self): @@ -100,7 +109,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.set_ciphers('AESGCM') names = set(d['name'] for d in ctx.get_ciphers()) self.assertIn('AES256-GCM-SHA384', names) -@@ -1012,6 +1041,7 @@ class ContextTests(unittest.TestCase): +@@ -1027,6 +1056,7 @@ class ContextTests(unittest.TestCase): def test_verify_mode(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) @@ -108,7 +117,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # Default value self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) ctx.verify_mode = ssl.CERT_OPTIONAL -@@ -1028,7 +1058,7 @@ class ContextTests(unittest.TestCase): +@@ -1043,7 +1073,7 @@ class ContextTests(unittest.TestCase): @unittest.skipUnless(have_verify_flags(), "verify_flags need OpenSSL > 0.9.8") def test_verify_flags(self): @@ -117,7 +126,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # default value tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0) self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf) -@@ -1046,7 +1076,7 @@ class ContextTests(unittest.TestCase): +@@ -1061,7 +1091,7 @@ class ContextTests(unittest.TestCase): ctx.verify_flags = None def test_load_cert_chain(self): @@ -126,7 +135,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # Combined key and cert in a single file ctx.load_cert_chain(CERTFILE, keyfile=None) ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE) -@@ -1059,7 +1089,7 @@ class ContextTests(unittest.TestCase): +@@ -1074,7 +1104,7 @@ class ContextTests(unittest.TestCase): with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(EMPTYCERT) # Separate key and cert @@ -135,7 +144,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.load_cert_chain(ONLYCERT, ONLYKEY) ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY) -@@ -1070,7 +1100,7 @@ class ContextTests(unittest.TestCase): +@@ -1085,7 +1115,7 @@ class ContextTests(unittest.TestCase): with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT) # Mismatching key and cert @@ -144,7 +153,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"): ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY) # Password protected key and cert -@@ -1129,7 +1159,7 @@ class ContextTests(unittest.TestCase): +@@ -1144,7 +1174,7 @@ class ContextTests(unittest.TestCase): ctx.load_cert_chain(CERTFILE, password=getpass_exception) def test_load_verify_locations(self): @@ -153,7 +162,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.load_verify_locations(CERTFILE) ctx.load_verify_locations(cafile=CERTFILE, capath=None) ctx.load_verify_locations(BYTES_CERTFILE) -@@ -1157,7 +1187,7 @@ class ContextTests(unittest.TestCase): +@@ -1172,7 +1202,7 @@ class ContextTests(unittest.TestCase): neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem) # test PEM @@ -162,7 +171,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0) ctx.load_verify_locations(cadata=cacert_pem) self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1) -@@ -1168,20 +1198,20 @@ class ContextTests(unittest.TestCase): +@@ -1183,20 +1213,20 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2) # combined @@ -186,7 +195,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.load_verify_locations(cadata=cacert_der) ctx.load_verify_locations(cadata=neuronio_der) self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2) -@@ -1190,13 +1220,13 @@ class ContextTests(unittest.TestCase): +@@ -1205,13 +1235,13 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2) # combined @@ -202,7 +211,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object) with self.assertRaisesRegex( -@@ -1214,7 +1244,7 @@ class ContextTests(unittest.TestCase): +@@ -1229,7 +1259,7 @@ class ContextTests(unittest.TestCase): def test_load_dh_params(self): @@ -211,7 +220,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.load_dh_params(DHFILE) if os.name != 'nt': ctx.load_dh_params(BYTES_DHFILE) -@@ -1247,12 +1277,12 @@ class ContextTests(unittest.TestCase): +@@ -1262,12 +1292,12 @@ class ContextTests(unittest.TestCase): def test_set_default_verify_paths(self): # There's not much we can do to test that it acts as expected, # so just check it doesn't crash or raise an exception. @@ -226,7 +235,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.set_ecdh_curve("prime256v1") ctx.set_ecdh_curve(b"prime256v1") self.assertRaises(TypeError, ctx.set_ecdh_curve) -@@ -1262,7 +1292,8 @@ class ContextTests(unittest.TestCase): +@@ -1277,7 +1307,8 @@ class ContextTests(unittest.TestCase): @needs_sni def test_sni_callback(self): @@ -236,7 +245,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # set_servername_callback expects a callable, or None self.assertRaises(TypeError, ctx.set_servername_callback) -@@ -1279,7 +1310,7 @@ class ContextTests(unittest.TestCase): +@@ -1294,7 +1325,7 @@ class ContextTests(unittest.TestCase): def test_sni_callback_refcycle(self): # Reference cycles through the servername callback are detected # and cleared. @@ -245,7 +254,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py def dummycallback(sock, servername, ctx, cycle=ctx): pass ctx.set_servername_callback(dummycallback) -@@ -1289,7 +1320,7 @@ class ContextTests(unittest.TestCase): +@@ -1304,7 +1335,7 @@ class ContextTests(unittest.TestCase): self.assertIs(wr(), None) def test_cert_store_stats(self): @@ -254,7 +263,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertEqual(ctx.cert_store_stats(), {'x509_ca': 0, 'crl': 0, 'x509': 0}) ctx.load_cert_chain(CERTFILE) -@@ -1303,7 +1334,7 @@ class ContextTests(unittest.TestCase): +@@ -1318,7 +1349,7 @@ class ContextTests(unittest.TestCase): {'x509_ca': 1, 'crl': 0, 'x509': 2}) def test_get_ca_certs(self): @@ -263,7 +272,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertEqual(ctx.get_ca_certs(), []) # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE ctx.load_verify_locations(CERTFILE) -@@ -1331,24 +1362,24 @@ class ContextTests(unittest.TestCase): +@@ -1346,24 +1377,24 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.get_ca_certs(True), [der]) def test_load_default_certs(self): @@ -293,7 +302,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with support.EnvironmentVarGuard() as env: env["SSL_CERT_DIR"] = CAPATH env["SSL_CERT_FILE"] = CERTFILE -@@ -1357,11 +1388,11 @@ class ContextTests(unittest.TestCase): +@@ -1372,11 +1403,11 @@ class ContextTests(unittest.TestCase): @unittest.skipUnless(sys.platform == "win32", "Windows specific") def test_load_default_certs_env_windows(self): @@ -307,7 +316,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with support.EnvironmentVarGuard() as env: env["SSL_CERT_DIR"] = CAPATH env["SSL_CERT_FILE"] = CERTFILE -@@ -1408,20 +1439,20 @@ class ContextTests(unittest.TestCase): +@@ -1423,20 +1454,20 @@ class ContextTests(unittest.TestCase): def test__create_stdlib_context(self): ctx = ssl._create_stdlib_context() @@ -334,7 +343,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) self.assertTrue(ctx.check_hostname) self._assert_context_options(ctx) -@@ -1432,7 +1463,7 @@ class ContextTests(unittest.TestCase): +@@ -1447,7 +1478,7 @@ class ContextTests(unittest.TestCase): self._assert_context_options(ctx) def test_check_hostname(self): @@ -343,7 +352,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertFalse(ctx.check_hostname) # Requires CERT_REQUIRED or CERT_OPTIONAL -@@ -1479,7 +1510,7 @@ class SSLErrorTests(unittest.TestCase): +@@ -1494,7 +1525,7 @@ class SSLErrorTests(unittest.TestCase): def test_lib_reason(self): # Test the library and reason attributes @@ -352,7 +361,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with self.assertRaises(ssl.SSLError) as cm: ctx.load_dh_params(CERTFILE) self.assertEqual(cm.exception.library, 'PEM') -@@ -1490,7 +1521,9 @@ class SSLErrorTests(unittest.TestCase): +@@ -1505,7 +1536,9 @@ class SSLErrorTests(unittest.TestCase): def test_subclass(self): # Check that the appropriate SSLError subclass is raised # (this only tests one of them) @@ -363,7 +372,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with socket.socket() as s: s.bind(("127.0.0.1", 0)) s.listen() -@@ -1642,7 +1675,9 @@ class SimpleBackgroundTests(unittest.Tes +@@ -1657,7 +1690,9 @@ class SimpleBackgroundTests(unittest.Tes def test_connect_with_context(self): # Same as test_connect, but with a separately created context @@ -374,7 +383,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s: s.connect(self.server_addr) self.assertEqual({}, s.getpeercert()) -@@ -1790,10 +1825,12 @@ class SimpleBackgroundTests(unittest.Tes +@@ -1805,10 +1840,12 @@ class SimpleBackgroundTests(unittest.Tes @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"), "needs TLS 1.2") def test_context_setget(self): # Check that the context of a connected socket can be replaced. @@ -390,7 +399,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ss.connect(self.server_addr) self.assertIs(ss.context, ctx1) self.assertIs(ss._sslobj.context, ctx1) -@@ -2121,24 +2158,26 @@ if _have_threads: +@@ -2136,24 +2173,26 @@ if _have_threads: certreqs=None, cacerts=None, chatty=True, connectionchatty=False, starttls_server=False, npn_protocols=None, alpn_protocols=None, @@ -423,7 +432,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.context.set_ciphers(ciphers) self.chatty = chatty self.connectionchatty = connectionchatty -@@ -2317,7 +2356,7 @@ if _have_threads: +@@ -2332,7 +2371,7 @@ if _have_threads: def server_params_test(client_context, server_context, indata=b"FOO\n", chatty=True, connectionchatty=False, sni_name=None, @@ -432,7 +441,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py """ Launch a server, connect a client to it and try various reads and writes. -@@ -2325,7 +2364,8 @@ if _have_threads: +@@ -2340,7 +2379,8 @@ if _have_threads: stats = {} server = ThreadedEchoServer(context=server_context, chatty=chatty, @@ -442,7 +451,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with server: with client_context.wrap_socket(socket.socket(), server_hostname=sni_name, session=session) as s: -@@ -2387,18 +2427,24 @@ if _have_threads: +@@ -2402,18 +2442,24 @@ if _have_threads: (ssl.get_protocol_name(client_protocol), ssl.get_protocol_name(server_protocol), certtype)) @@ -472,7 +481,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py ctx.verify_mode = certsreqs ctx.load_cert_chain(CERTFILE) ctx.load_verify_locations(CERTFILE) -@@ -2432,26 +2478,22 @@ if _have_threads: +@@ -2447,26 +2493,14 @@ if _have_threads: """Basic test of an SSL client connecting to a server""" if support.verbose: sys.stdout.write("\n") @@ -484,14 +493,6 @@ Index: Python-3.6.15/Lib/test/test_ssl.py - context.load_cert_chain(CERTFILE) - server_params_test(context, context, - chatty=True, connectionchatty=True) -+ # for protocol in PROTOCOLS: -+ # if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}: -+ # continue -+ # with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]): -+ # context = ssl.SSLContext(protocol) -+ # context.load_cert_chain(CERTFILE) -+ # server_params_test(context, context, -+ # chatty=True, connectionchatty=True) - client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - client_context.load_verify_locations(SIGNING_CA) @@ -509,7 +510,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.check_hostname = False with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT): -@@ -2459,9 +2501,8 @@ if _have_threads: +@@ -2474,9 +2508,8 @@ if _have_threads: server_params_test(client_context=server_context, server_context=client_context, chatty=True, connectionchatty=True, @@ -521,7 +522,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER): with self.assertRaises(ssl.SSLError) as e: -@@ -2524,39 +2565,37 @@ if _have_threads: +@@ -2539,39 +2572,37 @@ if _have_threads: if support.verbose: sys.stdout.write("\n") @@ -571,7 +572,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py s.connect((HOST, server.port)) cert = s.getpeercert() self.assertTrue(cert, "Can't get peer certificate.") -@@ -2565,10 +2604,10 @@ if _have_threads: +@@ -2580,10 +2611,10 @@ if _have_threads: if support.verbose: sys.stdout.write("\n") @@ -584,7 +585,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py context.verify_mode = ssl.CERT_REQUIRED context.check_hostname = True context.load_verify_locations(SIGNING_CA) -@@ -2604,17 +2643,19 @@ if _have_threads: +@@ -2619,17 +2650,19 @@ if _have_threads: ) def test_hostname_checks_common_name(self): client_context, server_context, hostname = testing_context() @@ -607,7 +608,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.hostname_checks_common_name = False server = ThreadedEchoServer(context=server_context, chatty=True) with server: -@@ -2702,29 +2743,31 @@ if _have_threads: +@@ -2717,29 +2750,31 @@ if _have_threads: "OpenSSL is compiled without SSLv2 support") def test_protocol_sslv2(self): """Connecting to an SSLv2 server with various client options""" @@ -644,7 +645,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py if support.verbose: sys.stdout.write("\n") if hasattr(ssl, 'PROTOCOL_SSLv2'): -@@ -2736,20 +2779,23 @@ if _have_threads: +@@ -2751,20 +2786,23 @@ if _have_threads: sys.stdout.write( " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) @@ -671,7 +672,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # Server with specific SSL options if hasattr(ssl, 'PROTOCOL_SSLv3'): -@@ -2759,7 +2805,7 @@ if _have_threads: +@@ -2774,7 +2812,7 @@ if _have_threads: try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False, @@ -680,7 +681,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py @skip_if_broken_ubuntu_ssl -@@ -2776,13 +2822,15 @@ if _have_threads: +@@ -2791,13 +2829,15 @@ if _have_threads: try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_SSLv3) @@ -697,7 +698,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py def test_protocol_tlsv1(self): """Connecting to a TLSv1 server with various client options""" if support.verbose: -@@ -2794,7 +2842,7 @@ if _have_threads: +@@ -2809,7 +2849,7 @@ if _have_threads: try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) if hasattr(ssl, 'PROTOCOL_SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) @@ -706,7 +707,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_options=ssl.OP_NO_TLSv1) @skip_if_broken_ubuntu_ssl -@@ -2811,12 +2859,12 @@ if _have_threads: +@@ -2826,12 +2866,12 @@ if _have_threads: try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) if hasattr(ssl, 'PROTOCOL_SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) @@ -723,7 +724,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py @skip_if_broken_ubuntu_ssl -@@ -2834,24 +2882,27 @@ if _have_threads: +@@ -2849,24 +2889,27 @@ if _have_threads: try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) if hasattr(ssl, 'PROTOCOL_SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) @@ -759,7 +760,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py wrapped = False with server: s = socket.socket() -@@ -2876,7 +2927,8 @@ if _have_threads: +@@ -2891,7 +2934,8 @@ if _have_threads: sys.stdout.write( " client: read %r from server, starting TLS...\n" % msg) @@ -769,7 +770,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py wrapped = True elif indata == b"ENDTLS" and msg.startswith(b"ok"): # ENDTLS ok, switch back to clear text -@@ -2903,17 +2955,17 @@ if _have_threads: +@@ -2918,17 +2962,17 @@ if _have_threads: def test_socketserver(self): """Using socketserver to create and manage SSL connections.""" @@ -791,7 +792,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py f = urllib.request.urlopen(url, context=context) try: dlen = f.info().get("content-length") -@@ -2963,7 +3015,7 @@ if _have_threads: +@@ -2978,7 +3022,7 @@ if _have_threads: server = ThreadedEchoServer(CERTFILE, certreqs=ssl.CERT_NONE, @@ -800,7 +801,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py cacerts=CERTFILE, chatty=True, connectionchatty=False) -@@ -2972,8 +3024,7 @@ if _have_threads: +@@ -2987,8 +3031,7 @@ if _have_threads: server_side=False, certfile=CERTFILE, ca_certs=CERTFILE, @@ -810,7 +811,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py s.connect((HOST, server.port)) # helper methods for standardising recv* method signatures def _recv_into(): -@@ -3115,32 +3166,30 @@ if _have_threads: +@@ -3130,32 +3173,30 @@ if _have_threads: def test_nonblocking_send(self): server = ThreadedEchoServer(CERTFILE, certreqs=ssl.CERT_NONE, @@ -858,7 +859,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py def test_handshake_timeout(self): # Issue #5103: SSL handshake must respect the socket timeout -@@ -3271,14 +3320,17 @@ if _have_threads: +@@ -3286,14 +3327,17 @@ if _have_threads: Basic tests for SSLSocket.version(). More tests are done in the test_protocol_*() methods. """ @@ -879,7 +880,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertIs(s.version(), None) @unittest.skipUnless(ssl.HAS_TLSv1_3, -@@ -3291,7 +3343,7 @@ if _have_threads: +@@ -3306,7 +3350,7 @@ if _have_threads: ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2 ) with ThreadedEchoServer(context=context) as server: @@ -888,7 +889,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py s.connect((HOST, server.port)) self.assertIn(s.cipher()[0], [ 'TLS_AES_256_GCM_SHA384', -@@ -3327,64 +3379,59 @@ if _have_threads: +@@ -3342,64 +3386,59 @@ if _have_threads: if support.verbose: sys.stdout.write("\n") @@ -998,7 +999,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py if support.verbose: sys.stdout.write(" got compression: {!r}\n".format(stats['compression'])) self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' }) -@@ -3392,44 +3439,45 @@ if _have_threads: +@@ -3407,44 +3446,45 @@ if _have_threads: @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'), "ssl.OP_NO_COMPRESSION needed for this test") def test_compression_disabled(self): @@ -1024,7 +1025,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py - stats = server_params_test(context, context, - chatty=True, connectionchatty=True) + client_context, server_context, hostname = testing_context() -+ client_context.options = ssl.PROTOCOL_TLS & ssl.OP_NO_TLSv1_3 ++ client_context.options |= ssl.OP_NO_TLSv1_3 + client_context.load_dh_params(DHFILE) + client_context.set_ciphers("kEDH") + stats = server_params_test(client_context, server_context, @@ -1065,7 +1066,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertIs(stats['client_alpn_protocol'], None) @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test") -@@ -3443,10 +3491,10 @@ if _have_threads: +@@ -3458,10 +3498,10 @@ if _have_threads: (['http/3.0', 'http/4.0'], None) ] for client_protocols, expected in protocol_tests: @@ -1078,7 +1079,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.load_cert_chain(CERTFILE) client_context.set_alpn_protocols(client_protocols) -@@ -3475,9 +3523,10 @@ if _have_threads: +@@ -3490,9 +3530,10 @@ if _have_threads: self.assertEqual(server_result, expected, msg % (server_result, "server")) @@ -1090,7 +1091,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py context.load_cert_chain(CERTFILE) stats = server_params_test(context, context, chatty=True, connectionchatty=True) -@@ -3493,10 +3542,10 @@ if _have_threads: +@@ -3508,10 +3549,10 @@ if _have_threads: (['abc', 'def'], 'abc') ] for client_protocols, expected in protocol_tests: @@ -1103,7 +1104,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.load_cert_chain(CERTFILE) client_context.set_npn_protocols(client_protocols) stats = server_params_test(client_context, server_context, -@@ -3513,12 +3562,11 @@ if _have_threads: +@@ -3528,12 +3569,11 @@ if _have_threads: self.assertEqual(server_result, expected, msg % (server_result, "server")) def sni_contexts(self): @@ -1119,7 +1120,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.load_verify_locations(SIGNING_CA) return server_context, other_context, client_context -@@ -3552,7 +3600,7 @@ if _have_threads: +@@ -3567,7 +3607,7 @@ if _have_threads: chatty=True, sni_name=None) self.assertEqual(calls, [(None, server_context)]) @@ -1128,7 +1129,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py # Check disabling the callback calls = [] -@@ -3562,7 +3610,7 @@ if _have_threads: +@@ -3577,7 +3617,7 @@ if _have_threads: chatty=True, sni_name='notfunny') # Certificate didn't change @@ -1137,7 +1138,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertEqual(calls, []) @skip_if_OpenSSL30 -@@ -3620,9 +3668,9 @@ if _have_threads: +@@ -3635,9 +3675,9 @@ if _have_threads: @unittest.skipIf(IS_OPENSSL_1_1_1, "bpo-36576: fail on OpenSSL 1.1.1") def test_shared_ciphers(self): @@ -1149,7 +1150,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py client_context.verify_mode = ssl.CERT_REQUIRED client_context.load_verify_locations(SIGNING_CA) if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): -@@ -3682,14 +3730,11 @@ if _have_threads: +@@ -3697,14 +3737,11 @@ if _have_threads: self.assertEqual(s.recv(1024), TEST_DATA) def test_session(self): @@ -1167,7 +1168,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py session = stats['session'] self.assertTrue(session.id) self.assertGreater(session.time, 0) -@@ -3703,7 +3748,8 @@ if _have_threads: +@@ -3718,7 +3755,8 @@ if _have_threads: self.assertEqual(sess_stat['hits'], 0) # reuse session @@ -1177,7 +1178,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py sess_stat = server_context.session_stats() self.assertEqual(sess_stat['accept'], 2) self.assertEqual(sess_stat['hits'], 1) -@@ -3716,7 +3762,8 @@ if _have_threads: +@@ -3731,7 +3769,8 @@ if _have_threads: self.assertGreaterEqual(session2.timeout, session.timeout) # another one without session @@ -1187,7 +1188,7 @@ Index: Python-3.6.15/Lib/test/test_ssl.py self.assertFalse(stats['session_reused']) session3 = stats['session'] self.assertNotEqual(session3.id, session.id) -@@ -3726,7 +3773,8 @@ if _have_threads: +@@ -3741,7 +3780,8 @@ if _have_threads: self.assertEqual(sess_stat['hits'], 1) # reuse session again