diff --git a/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch b/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch new file mode 100644 index 0000000..6fd5f71 --- /dev/null +++ b/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch @@ -0,0 +1,1742 @@ +From 3ddf7fa83b19463e710b75ae6e8a28831e575f3d Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Wed, 28 Oct 2020 09:26:39 +0100 +Subject: [PATCH] PEP-644: Require OpenSSL 1.1.1 or newer + +- Remove HAVE_X509_VERIFY_PARAM_SET1_HOST check +- Update hashopenssl to require OpenSSL 1.1.1 +- multissltests only OpenSSL > 1.1.0 +- ALPN is always supported +- SNI is always supported +- Remove deprecated NPN code. Python wrappers are no-op. +- ECDH is always supported +- Remove OPENSSL_VERSION_1_1 macro +- Remove locking callbacks +- Drop PY_OPENSSL_1_1_API macro +- Drop HAVE_SSL_CTX_CLEAR_OPTIONS macro +- SSL_CTRL_GET_MAX_PROTO_VERSION is always defined now +- security level is always available now +- get_num_tickets is available with TLS 1.3 +- X509_V_ERR MISMATCH is always available now +- Always set SSL_MODE_RELEASE_BUFFERS +- X509_V_FLAG_TRUSTED_FIRST is always available +- get_ciphers is always supported +- SSL_CTX_set_keylog_callback is always available +- Update Modules/Setup with static link example +- Mention PEP in whatsnew +- Drop 1.0.2 and 1.1.0 from GHA tests +--- + Doc/using/unix.rst | 1 + Lib/ssl.py | 10 + Lib/test/test_ssl.py | 119 -- + Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst | 1 + Modules/Setup | 22 + Modules/_hashopenssl.c | 24 + Modules/_ssl.c | 518 ---------- + Modules/_ssl/debughelpers.c | 4 + Modules/clinic/_hashopenssl.c.h | 4 + Modules/clinic/_ssl.c.h | 85 - + Tools/ssl/multissltests.py | 4 + configure | 9 + configure.ac | 36 + pyconfig.h.in | 3 + setup.py | 19 + 15 files changed, 75 insertions(+), 784 deletions(-) + create mode 100644 Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst + +--- a/Doc/using/unix.rst ++++ b/Doc/using/unix.rst +@@ -113,6 +113,7 @@ For example, on most Linux systems, the + | | embedding the interpreter. | + +-----------------------------------------------+------------------------------------------+ + ++.. _unix_custom_openssl: + + Miscellaneous + ============= +--- a/Lib/ssl.py ++++ b/Lib/ssl.py +@@ -909,15 +909,12 @@ class SSLObject: + """Return the currently selected NPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if NPN is not supported by one + of the peers.""" +- if _ssl.HAS_NPN: +- return self._sslobj.selected_npn_protocol() + + def selected_alpn_protocol(self): + """Return the currently selected ALPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if ALPN is not supported by one + of the peers.""" +- if _ssl.HAS_ALPN: +- return self._sslobj.selected_alpn_protocol() ++ return self._sslobj.selected_alpn_protocol() + + def cipher(self): + """Return the currently selected cipher as a 3-tuple ``(name, +@@ -1159,10 +1156,7 @@ class SSLSocket(socket): + @_sslcopydoc + def selected_npn_protocol(self): + self._checkClosed() +- if self._sslobj is None or not _ssl.HAS_NPN: +- return None +- else: +- return self._sslobj.selected_npn_protocol() ++ return None + + @_sslcopydoc + def selected_alpn_protocol(self): +--- a/Lib/test/test_ssl.py ++++ b/Lib/test/test_ssl.py +@@ -35,7 +35,6 @@ from ssl import TLSVersion, _TLSContentT + PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) + HOST = support.HOST + IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL') +-IS_OPENSSL_1_1_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0) + IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 1) + IS_OPENSSL_3_0_0 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (3, 0, 0) + PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') +@@ -268,18 +267,6 @@ def handle_error(prefix): + if support.verbose: + sys.stdout.write(prefix + exc_format) + +-def can_clear_options(): +- # 0.9.8m or higher +- return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15) +- +-def no_sslv2_implies_sslv3_hello(): +- # 0.9.7h or higher +- return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) +- +-def have_verify_flags(): +- # 0.9.8 or higher +- return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15) +- + def _have_secp_curves(): + if not ssl.HAS_ECDH: + return False +@@ -370,17 +357,15 @@ class BasicSocketTests(unittest.TestCase + ssl.OP_SINGLE_DH_USE + if ssl.HAS_ECDH: + ssl.OP_SINGLE_ECDH_USE +- if ssl.OPENSSL_VERSION_INFO >= (1, 0): +- ssl.OP_NO_COMPRESSION ++ ssl.OP_NO_COMPRESSION + self.assertIn(ssl.HAS_SNI, {True, False}) + self.assertIn(ssl.HAS_ECDH, {True, False}) + ssl.OP_NO_SSLv2 + ssl.OP_NO_SSLv3 + ssl.OP_NO_TLSv1 + ssl.OP_NO_TLSv1_3 +- if ssl.OPENSSL_VERSION_INFO >= (1, 0, 1): +- ssl.OP_NO_TLSv1_1 +- ssl.OP_NO_TLSv1_2 ++ ssl.OP_NO_TLSv1_1 ++ ssl.OP_NO_TLSv1_2 + self.assertEqual(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv23) + + def test_private_init(self): +@@ -1189,7 +1174,6 @@ class ContextTests(unittest.TestCase): + self.assertNotIn("RC4", name) + self.assertNotIn("3DES", name) + +- @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old') + def test_get_ciphers(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.set_ciphers('AESGCM') +@@ -1209,15 +1193,11 @@ class ContextTests(unittest.TestCase): + self.assertEqual(default, ctx.options) + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) +- if can_clear_options(): +- ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) +- self.assertEqual(default, ctx.options) +- ctx.options = 0 +- # Ubuntu has OP_NO_SSLv3 forced on by default +- self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) +- else: +- with self.assertRaises(ValueError): +- ctx.options = 0 ++ ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) ++ self.assertEqual(default, ctx.options) ++ ctx.options = 0 ++ # Ubuntu has OP_NO_SSLv3 forced on by default ++ self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) + + def test_verify_mode_protocol(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) +@@ -1336,8 +1316,6 @@ class ContextTests(unittest.TestCase): + with self.assertRaises(ValueError): + ctx.maximum_version = ssl.TLSVersion.TLSv1 + +- @unittest.skipUnless(have_verify_flags(), +- "verify_flags need OpenSSL > 0.9.8") + def test_verify_flags(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + # default value +@@ -1810,7 +1788,6 @@ class ContextTests(unittest.TestCase): + obj = ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO()) + self.assertIsInstance(obj, MySSLObject) + +- @unittest.skipUnless(IS_OPENSSL_1_1_1, "Test requires OpenSSL 1.1.1") + def test_num_tickest(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + self.assertEqual(ctx.num_tickets, 2) +@@ -2973,8 +2950,6 @@ class ThreadedTests(unittest.TestCase): + after = ssl.cert_time_to_seconds(cert['notAfter']) + self.assertLess(before, after) + +- @unittest.skipUnless(have_verify_flags(), +- "verify_flags need OpenSSL > 0.9.8") + def test_crl_check(self): + if support.verbose: + sys.stdout.write("\n") +@@ -3878,12 +3853,7 @@ class ThreadedTests(unittest.TestCase): + self.assertIs(s.version(), None) + self.assertIs(s._sslobj, None) + s.connect((HOST, server.port)) +- if IS_OPENSSL_1_1_1 and has_tls_version('TLSv1_3'): +- self.assertEqual(s.version(), 'TLSv1.3') +- elif ssl.OPENSSL_VERSION_INFO >= (1, 0, 2): +- self.assertEqual(s.version(), 'TLSv1.2') +- else: # 0.9.8 to 1.0.1 +- self.assertIn(s.version(), ('TLSv1', 'TLSv1.2')) ++ self.assertEqual(s.version(), 'TLSv1.3') + self.assertIs(s._sslobj, None) + self.assertIs(s.version(), None) + +@@ -3985,8 +3955,6 @@ class ThreadedTests(unittest.TestCase): + # explicitly using the 'ECCdraft' cipher alias. Otherwise, + # our default cipher list should prefer ECDH-based ciphers + # automatically. +- if ssl.OPENSSL_VERSION_INFO < (1, 0, 0): +- context.set_ciphers("ECCdraft:ECDH") + with ThreadedEchoServer(context=context) as server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) +@@ -4117,15 +4085,11 @@ class ThreadedTests(unittest.TestCase): + server_context.set_ciphers("ECDHE:!eNULL:!aNULL") + server_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + try: +- stats = server_params_test(client_context, server_context, +- chatty=True, connectionchatty=True, +- sni_name=hostname) ++ server_params_test(client_context, server_context, ++ chatty=True, connectionchatty=True, ++ sni_name=hostname) + except ssl.SSLError: +- pass +- else: +- # OpenSSL 1.0.2 does not fail although it should. +- if IS_OPENSSL_1_1_0: +- self.fail("mismatch curve did not fail") ++ self.fail("mismatch curve did not fail") + + def test_selected_alpn_protocol(self): + # selected_alpn_protocol() is None unless ALPN is used. +@@ -4135,7 +4099,6 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_alpn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required") + def test_selected_alpn_protocol_if_server_uses_alpn(self): + # selected_alpn_protocol() is None unless ALPN is used by the client. + client_context, server_context, hostname = testing_context() +@@ -4145,7 +4108,6 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_alpn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test") + def test_alpn_protocols(self): + server_protocols = ['foo', 'bar', 'milkshake'] + protocol_tests = [ +@@ -4168,22 +4130,17 @@ class ThreadedTests(unittest.TestCase): + except ssl.SSLError as e: + stats = e + +- if (expected is None and IS_OPENSSL_1_1_0 +- and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)): +- # OpenSSL 1.1.0 to 1.1.0e raises handshake error +- self.assertIsInstance(stats, ssl.SSLError) +- else: +- msg = "failed trying %s (s) and %s (c).\n" \ +- "was expecting %s, but got %%s from the %%s" \ +- % (str(server_protocols), str(client_protocols), +- str(expected)) +- client_result = stats['client_alpn_protocol'] +- self.assertEqual(client_result, expected, +- msg % (client_result, "client")) +- server_result = stats['server_alpn_protocols'][-1] \ +- if len(stats['server_alpn_protocols']) else 'nothing' +- self.assertEqual(server_result, expected, +- msg % (server_result, "server")) ++ msg = "failed trying %s (s) and %s (c).\n" \ ++ "was expecting %s, but got %%s from the %%s" \ ++ % (str(server_protocols), str(client_protocols), ++ str(expected)) ++ client_result = stats['client_alpn_protocol'] ++ self.assertEqual(client_result, expected, ++ msg % (client_result, "client")) ++ server_result = stats['server_alpn_protocols'][-1] \ ++ if len(stats['server_alpn_protocols']) else 'nothing' ++ self.assertEqual(server_result, expected, ++ msg % (server_result, "server")) + + def test_selected_npn_protocol(self): + # selected_npn_protocol() is None unless NPN is used +@@ -4193,31 +4150,8 @@ class ThreadedTests(unittest.TestCase): + sni_name=hostname) + self.assertIs(stats['client_npn_protocol'], None) + +- @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test") + def test_npn_protocols(self): +- server_protocols = ['http/1.1', 'spdy/2'] +- protocol_tests = [ +- (['http/1.1', 'spdy/2'], 'http/1.1'), +- (['spdy/2', 'http/1.1'], 'http/1.1'), +- (['spdy/2', 'test'], 'spdy/2'), +- (['abc', 'def'], 'abc') +- ] +- for client_protocols, expected in protocol_tests: +- client_context, server_context, hostname = testing_context() +- server_context.set_npn_protocols(server_protocols) +- client_context.set_npn_protocols(client_protocols) +- stats = server_params_test(client_context, server_context, +- chatty=True, connectionchatty=True, +- sni_name=hostname) +- msg = "failed trying %s (s) and %s (c).\n" \ +- "was expecting %s, but got %%s from the %%s" \ +- % (str(server_protocols), str(client_protocols), +- str(expected)) +- client_result = stats['client_npn_protocol'] +- self.assertEqual(client_result, expected, msg % (client_result, "client")) +- server_result = stats['server_npn_protocols'][-1] \ +- if len(stats['server_npn_protocols']) else 'nothing' +- self.assertEqual(server_result, expected, msg % (server_result, "server")) ++ assert not ssl.HAS_NPN + + def sni_contexts(self): + server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) +@@ -4387,8 +4321,7 @@ class ThreadedTests(unittest.TestCase): + self.assertGreater(session.time, 0) + self.assertGreater(session.timeout, 0) + self.assertTrue(session.has_ticket) +- if ssl.OPENSSL_VERSION_INFO > (1, 0, 1): +- self.assertGreater(session.ticket_lifetime_hint, 0) ++ self.assertGreater(session.ticket_lifetime_hint, 0) + self.assertFalse(stats['session_reused']) + sess_stat = server_context.session_stats() + self.assertEqual(sess_stat['accept'], 1) +--- /dev/null ++++ b/Misc/NEWS.d/next/Build/2021-03-30-14-19-39.bpo-43669.lWMUYx.rst +@@ -0,0 +1 @@ ++Implement :pep:`644`. Python now requires OpenSSL 1.1.1 or newer. +--- a/Modules/Setup ++++ b/Modules/Setup +@@ -206,11 +206,23 @@ _symtable symtablemodule.c + #_socket socketmodule.c + + # Socket module helper for SSL support; you must comment out the other +-# socket line above, and possibly edit the SSL variable: +-#SSL=/usr/local/ssl +-#_ssl _ssl.c \ +-# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ +-# -L$(SSL)/lib -lssl -lcrypto ++# socket line above, and edit the OPENSSL variable: ++# OPENSSL=/path/to/openssl/directory ++# _ssl _ssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -lssl -lcrypto ++#_hashlib _hashopenssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -lcrypto ++ ++# To statically link OpenSSL: ++# _ssl _ssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -l:libssl.a -Wl,--exclude-libs,libssl.a \ ++# -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a ++#_hashlib _hashopenssl.c \ ++# -I$(OPENSSL)/include -L$(OPENSSL)/lib \ ++# -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a + + # The crypt module is now disabled by default because it breaks builds + # on many systems (where -lcrypt is needed), e.g. Linux (I believe). +--- a/Modules/_hashopenssl.c ++++ b/Modules/_hashopenssl.c +@@ -37,25 +37,14 @@ + # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" + #endif + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +-/* OpenSSL < 1.1.0 */ +-#define EVP_MD_CTX_new EVP_MD_CTX_create +-#define EVP_MD_CTX_free EVP_MD_CTX_destroy +-#endif +- + #define MUNCH_SIZE INT_MAX + +-#ifdef NID_sha3_224 ++#define PY_OPENSSL_HAS_SCRYPT 1 + #define PY_OPENSSL_HAS_SHA3 1 +-#endif + +-#if defined(EVP_MD_FLAG_XOF) && defined(NID_shake128) + #define PY_OPENSSL_HAS_SHAKE 1 +-#endif + +-#if defined(NID_blake2b512) && !defined(OPENSSL_NO_BLAKE2) + #define PY_OPENSSL_HAS_BLAKE2 1 +-#endif + + typedef struct { + PyObject_HEAD +@@ -848,8 +837,7 @@ pbkdf2_hmac_impl(PyObject *module, const + return key_obj; + } + +-#if OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER) +-#define PY_SCRYPT 1 ++#ifdef PY_OPENSSL_HAS_SCRYPT + + /* XXX: Parameters salt, n, r and p should be required keyword-only parameters. + They are optional in the Argument Clinic declaration only due to a +@@ -972,7 +960,7 @@ _hashlib_scrypt_impl(PyObject *module, P + } + return key_obj; + } +-#endif ++#endif /* PY_OPENSSL_HAS_SCRYPT */ + + /* Fast HMAC for hmac.digest() + */ +@@ -1116,12 +1104,6 @@ PyInit__hashlib(void) + { + PyObject *m, *openssl_md_meth_names; + +-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +- /* Load all digest algorithms and initialize cpuid */ +- OPENSSL_add_all_algorithms_noconf(); +- ERR_load_crypto_strings(); +-#endif +- + /* TODO build EVP_functions openssl_* entries dynamically based + * on what hashes are supported rather than listing many + * but having some be unsupported. Only init appropriate +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -31,9 +31,9 @@ + #define _PySSL_FIX_ERRNO + + #define PySSL_BEGIN_ALLOW_THREADS_S(save) \ +- do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) ++ do { (save) = PyEval_SaveThread(); } while(0) + #define PySSL_END_ALLOW_THREADS_S(save) \ +- do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) ++ do { PyEval_RestoreThread(save); _PySSL_FIX_ERRNO; } while(0) + #define PySSL_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save = NULL; \ + PySSL_BEGIN_ALLOW_THREADS_S(_save); +@@ -64,16 +64,6 @@ static PySocketModule_APIObject PySocket + #include "openssl/bio.h" + #include "openssl/dh.h" + +-#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST +-# ifdef LIBRESSL_VERSION_NUMBER +-# error "LibreSSL is missing X509_VERIFY_PARAM_set1_host(), see https://github.com/libressl-portable/portable/issues/381" +-# elif OPENSSL_VERSION_NUMBER > 0x1000200fL +-# define HAVE_X509_VERIFY_PARAM_SET1_HOST +-# else +-# error "libssl is too old and does not support X509_VERIFY_PARAM_set1_host()" +-# endif +-#endif +- + #ifndef OPENSSL_THREADS + # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" + #endif +@@ -144,15 +134,7 @@ static void _PySSLFixErrno(void) { + #include "_ssl_data.h" + #endif + +-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define OPENSSL_VERSION_1_1 1 +-# define PY_OPENSSL_1_1_API 1 +-#endif +- +-/* OpenSSL API 1.1.0+ does not include version methods. Define the methods +- * unless OpenSSL is compiled without the methods. It's the easiest way to +- * make 1.0.2, 1.1.0, 1.1.1, and 3.0.0 happy without deprecation warnings. +- */ ++/* OpenSSL API 1.1.0+ does not include version methods */ + #ifndef OPENSSL_NO_TLS1_METHOD + extern const SSL_METHOD *TLSv1_method(void); + #endif +@@ -163,59 +145,10 @@ extern const SSL_METHOD *TLSv1_1_method( + extern const SSL_METHOD *TLSv1_2_method(void); + #endif + +-/* LibreSSL 2.7.0 provides necessary OpenSSL 1.1.0 APIs */ +-#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x2070000fL +-# define PY_OPENSSL_1_1_API 1 +-#endif +- +-#if (OPENSSL_VERSION_NUMBER >= 0x30300000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define OPENSSL_VERSION_3_3 1 +-#endif +- +-/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f +- * This includes the SSL_set_SSL_CTX() function. +- */ +-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +-# define HAVE_SNI 1 +-#else +-# define HAVE_SNI 0 +-#endif +- +-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +-# define HAVE_ALPN 1 +-#else +-# define HAVE_ALPN 0 +-#endif +- +-/* We cannot rely on OPENSSL_NO_NEXTPROTONEG because LibreSSL 2.6.1 dropped +- * NPN support but did not set OPENSSL_NO_NEXTPROTONEG for compatibility +- * reasons. The check for TLSEXT_TYPE_next_proto_neg works with +- * OpenSSL 1.0.1+ and LibreSSL. +- * OpenSSL 1.1.1-pre1 dropped NPN but still has TLSEXT_TYPE_next_proto_neg. +- */ +-#ifdef OPENSSL_NO_NEXTPROTONEG +-# define HAVE_NPN 0 +-#elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +-# define HAVE_NPN 0 +-#elif defined(TLSEXT_TYPE_next_proto_neg) +-# define HAVE_NPN 1 +-#else +-# define HAVE_NPN 0 +-#endif +- +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +-#define HAVE_OPENSSL_KEYLOG 1 +-#endif +- + #ifndef INVALID_SOCKET /* MS defines this */ + #define INVALID_SOCKET (-1) + #endif + +-/* OpenSSL 1.0.2 and LibreSSL needs extra code for locking */ +-#ifndef OPENSSL_VERSION_1_1 +-#define HAVE_OPENSSL_CRYPTO_LOCK +-#endif +- + /* OpenSSL 1.1+ allows locking X509_STORE, 1.0.2 doesn't. */ + #ifdef OPENSSL_VERSION_1_1 + #define HAVE_OPENSSL_X509_STORE_LOCK +@@ -226,80 +159,8 @@ extern const SSL_METHOD *TLSv1_2_method( + #define HAVE_OPENSSL_X509_STORE_GET1_OBJECTS 1 + #endif + +-#if defined(OPENSSL_VERSION_1_1) && !defined(OPENSSL_NO_SSL2) ++/* OpenSSL 1.1 does not have SSL 2.0 */ + #define OPENSSL_NO_SSL2 +-#endif +- +-#ifndef PY_OPENSSL_1_1_API +-/* OpenSSL 1.1 API shims for OpenSSL < 1.1.0 and LibreSSL < 2.7.0 */ +- +-#define TLS_method SSLv23_method +-#define TLS_client_method SSLv23_client_method +-#define TLS_server_method SSLv23_server_method +-#define ASN1_STRING_get0_data ASN1_STRING_data +-#define X509_get0_notBefore X509_get_notBefore +-#define X509_get0_notAfter X509_get_notAfter +-#define OpenSSL_version_num SSLeay +-#define OpenSSL_version SSLeay_version +-#define OPENSSL_VERSION SSLEAY_VERSION +- +-static int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +-{ +- return ne->set; +-} +- +-#ifndef OPENSSL_NO_COMP +-/* LCOV_EXCL_START */ +-static int COMP_get_type(const COMP_METHOD *meth) +-{ +- return meth->type; +-} +-/* LCOV_EXCL_STOP */ +-#endif +- +-static pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +-{ +- return ctx->default_passwd_callback; +-} +- +-static void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +-{ +- return ctx->default_passwd_callback_userdata; +-} +- +-static int X509_OBJECT_get_type(X509_OBJECT *x) +-{ +- return x->type; +-} +- +-static X509 *X509_OBJECT_get0_X509(X509_OBJECT *x) +-{ +- return x->data.x509; +-} +- +-static int BIO_up_ref(BIO *b) +-{ +- CRYPTO_add(&b->references, 1, CRYPTO_LOCK_BIO); +- return 1; +-} +- +-static STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *store) { +- return store->objs; +-} +- +-static int +-SSL_SESSION_has_ticket(const SSL_SESSION *s) +-{ +- return (s->tlsext_ticklen > 0) ? 1 : 0; +-} +- +-static unsigned long +-SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s) +-{ +- return s->tlsext_tick_lifetime_hint; +-} +- +-#endif /* OpenSSL < 1.1.0 or LibreSSL < 2.7.0 */ + + /* Default cipher suites */ + #ifndef PY_SSL_DEFAULT_CIPHERS +@@ -411,24 +272,10 @@ enum py_proto_version { + #endif + }; + +- +-/* serves as a flag to see whether we've initialized the SSL thread support. */ +-/* 0 means no, greater than 0 means yes */ +- +-static unsigned int _ssl_locks_count = 0; +- + /* SSL socket object */ + + #define X509_NAME_MAXLEN 256 + +-/* SSL_CTX_clear_options() and SSL_clear_options() were first added in +- * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the +- * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ +-#if OPENSSL_VERSION_NUMBER >= 0x009080dfL && OPENSSL_VERSION_NUMBER != 0x00909000L +-# define HAVE_SSL_CTX_CLEAR_OPTIONS +-#else +-# undef HAVE_SSL_CTX_CLEAR_OPTIONS +-#endif + + /* In case of 'tls-unique' it will be 12 bytes for TLS, 36 bytes for + * older SSL, but let's be safe */ +@@ -438,17 +285,9 @@ static unsigned int _ssl_locks_count = 0 + typedef struct { + PyObject_HEAD + SSL_CTX *ctx; +-#if HAVE_NPN +- unsigned char *npn_protocols; +- int npn_protocols_len; +-#endif +-#if HAVE_ALPN + unsigned char *alpn_protocols; + unsigned int alpn_protocols_len; +-#endif +-#ifndef OPENSSL_NO_TLSEXT + PyObject *set_sni_cb; +-#endif + int check_hostname; + /* OpenSSL has no API to get hostflags from X509_VERIFY_PARAM* struct. + * We have to maintain our own copy. OpenSSL's hostflags default to 0. +@@ -459,10 +298,8 @@ typedef struct { + int post_handshake_auth; + #endif + PyObject *msg_cb; +-#ifdef HAVE_OPENSSL_KEYLOG + PyObject *keylog_filename; + BIO *keylog_bio; +-#endif + } PySSLContext; + + typedef struct { +@@ -669,23 +506,18 @@ fill_and_set_sslerror(PySSLSocket *sslso + } + + switch (verify_code) { +-#ifdef X509_V_ERR_HOSTNAME_MISMATCH +- /* OpenSSL >= 1.0.2, LibreSSL >= 2.5.3 */ + case X509_V_ERR_HOSTNAME_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "Hostname mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +-#endif +-#ifdef X509_V_ERR_IP_ADDRESS_MISMATCH + case X509_V_ERR_IP_ADDRESS_MISMATCH: + verify_obj = PyUnicode_FromFormat( + "IP address mismatch, certificate is not valid for '%S'.", + sslsock->server_hostname + ); + break; +-#endif + default: + verify_str = X509_verify_cert_error_string(verify_code); + if (verify_str != NULL) { +@@ -2016,7 +1848,6 @@ cipher_to_tuple(const SSL_CIPHER *cipher + return NULL; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10002000UL + static PyObject * + cipher_to_dict(const SSL_CIPHER *cipher) + { +@@ -2025,10 +1856,8 @@ cipher_to_dict(const SSL_CIPHER *cipher) + unsigned long cipher_id; + int alg_bits, strength_bits, len; + char buf[512] = {0}; +-#if OPENSSL_VERSION_1_1 + int aead, nid; + const char *skcipher = NULL, *digest = NULL, *kx = NULL, *auth = NULL; +-#endif + + /* can be NULL */ + cipher_name = SSL_CIPHER_get_name(cipher); +@@ -2041,7 +1870,6 @@ cipher_to_dict(const SSL_CIPHER *cipher) + buf[len-1] = '\0'; + strength_bits = SSL_CIPHER_get_bits(cipher, &alg_bits); + +-#if OPENSSL_VERSION_1_1 + aead = SSL_CIPHER_is_aead(cipher); + nid = SSL_CIPHER_get_cipher_nid(cipher); + skcipher = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +@@ -2051,13 +1879,10 @@ cipher_to_dict(const SSL_CIPHER *cipher) + kx = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; + nid = SSL_CIPHER_get_auth_nid(cipher); + auth = nid != NID_undef ? OBJ_nid2ln(nid) : NULL; +-#endif + + return Py_BuildValue( + "{sksssssssisi" +-#if OPENSSL_VERSION_1_1 + "sOssssssss" +-#endif + "}", + "id", cipher_id, + "name", cipher_name, +@@ -2065,16 +1890,13 @@ cipher_to_dict(const SSL_CIPHER *cipher) + "description", buf, + "strength_bits", strength_bits, + "alg_bits", alg_bits +-#if OPENSSL_VERSION_1_1 + ,"aead", aead ? Py_True : Py_False, + "symmetric", skcipher, + "digest", digest, + "kea", kx, + "auth", auth +-#endif + ); + } +-#endif + + /*[clinic input] + _ssl._SSLSocket.shared_ciphers +@@ -2145,28 +1967,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket + return PyUnicode_FromString(version); + } + +-#if HAVE_NPN +-/*[clinic input] +-_ssl._SSLSocket.selected_npn_protocol +-[clinic start generated code]*/ +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self) +-/*[clinic end generated code: output=b91d494cd207ecf6 input=c28fde139204b826]*/ +-{ +- const unsigned char *out; +- unsigned int outlen; +- +- SSL_get0_next_proto_negotiated(self->ssl, +- &out, &outlen); +- +- if (out == NULL) +- Py_RETURN_NONE; +- return PyUnicode_FromStringAndSize((char *)out, outlen); +-} +-#endif +- +-#if HAVE_ALPN + /*[clinic input] + _ssl._SSLSocket.selected_alpn_protocol + [clinic start generated code]*/ +@@ -2184,7 +1984,6 @@ _ssl__SSLSocket_selected_alpn_protocol_i + Py_RETURN_NONE; + return PyUnicode_FromStringAndSize((char *)out, outlen); + } +-#endif + + /*[clinic input] + _ssl._SSLSocket.compression +@@ -2221,11 +2020,6 @@ static int PySSL_set_context(PySSLSocket + void *closure) { + + if (PyObject_TypeCheck(value, &PySSLContext_Type)) { +-#if !HAVE_SNI +- PyErr_SetString(PyExc_NotImplementedError, "setting a socket's " +- "context is not supported by your OpenSSL library"); +- return -1; +-#else + Py_INCREF(value); + Py_SETREF(self->ctx, (PySSLContext *)value); + SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); +@@ -2234,7 +2028,6 @@ static int PySSL_set_context(PySSLSocket + self->ssl, + self->ctx->msg_cb ? _PySSL_msg_callback : NULL + ); +-#endif + } else { + PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext"); + return -1; +@@ -2859,8 +2652,6 @@ _ssl__SSLSocket_verify_client_post_hands + #endif + } + +-#ifdef OPENSSL_VERSION_1_1 +- + static SSL_SESSION* + _ssl_session_dup(SSL_SESSION *session) { + SSL_SESSION *newsession = NULL; +@@ -2901,7 +2692,6 @@ _ssl_session_dup(SSL_SESSION *session) { + } + return NULL; + } +-#endif + + static PyObject * + PySSL_get_session(PySSLSocket *self, void *closure) { +@@ -2910,7 +2700,6 @@ PySSL_get_session(PySSLSocket *self, voi + PySSLSession *pysess; + SSL_SESSION *session; + +-#ifdef OPENSSL_VERSION_1_1 + /* duplicate session as workaround for session bug in OpenSSL 1.1.0, + * https://github.com/openssl/openssl/issues/1550 */ + session = SSL_get0_session(self->ssl); /* borrowed reference */ +@@ -2920,12 +2709,10 @@ PySSL_get_session(PySSLSocket *self, voi + if ((session = _ssl_session_dup(session)) == NULL) { + return NULL; + } +-#else + session = SSL_get1_session(self->ssl); + if (session == NULL) { + Py_RETURN_NONE; + } +-#endif + pysess = PyObject_GC_New(PySSLSession, &PySSLSession_Type); + if (pysess == NULL) { + SSL_SESSION_free(session); +@@ -2944,9 +2731,7 @@ static int PySSL_set_session(PySSLSocket + void *closure) + { + PySSLSession *pysess; +-#ifdef OPENSSL_VERSION_1_1 + SSL_SESSION *session; +-#endif + int result; + + if (!PySSLSession_Check(value)) { +@@ -2970,7 +2755,6 @@ static int PySSL_set_session(PySSLSocket + "Cannot set session after handshake."); + return -1; + } +-#ifdef OPENSSL_VERSION_1_1 + /* duplicate session */ + if ((session = _ssl_session_dup(pysess->session)) == NULL) { + return -1; +@@ -2978,9 +2762,6 @@ static int PySSL_set_session(PySSLSocket + result = SSL_set_session(self->ssl, session); + /* free duplicate, SSL_set_session() bumps ref count */ + SSL_SESSION_free(session); +-#else +- result = SSL_set_session(self->ssl, pysess->session); +-#endif + if (result == 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + return -1; +@@ -3031,7 +2812,6 @@ static PyMethodDef PySSLMethods[] = { + _SSL__SSLSOCKET_CIPHER_METHODDEF + _SSL__SSLSOCKET_SHARED_CIPHERS_METHODDEF + _SSL__SSLSOCKET_VERSION_METHODDEF +- _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF + _SSL__SSLSOCKET_COMPRESSION_METHODDEF + _SSL__SSLSOCKET_SHUTDOWN_METHODDEF +@@ -3125,9 +2905,6 @@ _ssl__SSLContext_impl(PyTypeObject *type + SSL_CTX *ctx = NULL; + X509_VERIFY_PARAM *params; + int result; +-#if defined(SSL_MODE_RELEASE_BUFFERS) +- unsigned long libver; +-#endif + + PySSL_BEGIN_ALLOW_THREADS + switch(proto_version) { +@@ -3192,19 +2969,10 @@ _ssl__SSLContext_impl(PyTypeObject *type + self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; + self->protocol = proto_version; + self->msg_cb = NULL; +-#ifdef HAVE_OPENSSL_KEYLOG + self->keylog_filename = NULL; + self->keylog_bio = NULL; +-#endif +-#if HAVE_NPN +- self->npn_protocols = NULL; +-#endif +-#if HAVE_ALPN + self->alpn_protocols = NULL; +-#endif +-#ifndef OPENSSL_NO_TLSEXT + self->set_sni_cb = NULL; +-#endif + /* Don't check host name by default */ + if (proto_version == PY_SSL_VERSION_TLS_CLIENT) { + self->check_hostname = 1; +@@ -3266,37 +3034,9 @@ _ssl__SSLContext_impl(PyTypeObject *type + return NULL; + } + +-#if defined(SSL_MODE_RELEASE_BUFFERS) + /* Set SSL_MODE_RELEASE_BUFFERS. This potentially greatly reduces memory +- usage for no cost at all. However, don't do this for OpenSSL versions +- between 1.0.1 and 1.0.1h or 1.0.0 and 1.0.0m, which are affected by CVE +- 2014-0198. I can't find exactly which beta fixed this CVE, so be +- conservative and assume it wasn't fixed until release. We do this check +- at runtime to avoid problems from the dynamic linker. +- See #25672 for more on this. */ +- libver = OpenSSL_version_num(); +- if (!(libver >= 0x10001000UL && libver < 0x1000108fUL) && +- !(libver >= 0x10000000UL && libver < 0x100000dfUL)) { +- SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); +- } +-#endif +- +- +-#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) +- /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use +- prime256v1 by default. This is Apache mod_ssl's initialization +- policy, so we should be safe. OpenSSL 1.1 has it enabled by default. +- */ +-#if defined(SSL_CTX_set_ecdh_auto) +- SSL_CTX_set_ecdh_auto(self->ctx, 1); +-#else +- { +- EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); +- SSL_CTX_set_tmp_ecdh(self->ctx, key); +- EC_KEY_free(key); +- } +-#endif +-#endif ++ usage for no cost at all. */ ++ SSL_CTX_set_mode(self->ctx, SSL_MODE_RELEASE_BUFFERS); + + #define SID_CTX "Python" + SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, +@@ -3304,11 +3044,9 @@ _ssl__SSLContext_impl(PyTypeObject *type + #undef SID_CTX + + params = SSL_CTX_get0_param(self->ctx); +-#ifdef X509_V_FLAG_TRUSTED_FIRST + /* Improve trust chain building when cross-signed intermediate + certificates are present. See https://bugs.python.org/issue23476. */ + X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_TRUSTED_FIRST); +-#endif + X509_VERIFY_PARAM_set_hostflags(params, self->hostflags); + + #ifdef TLS1_3_VERSION +@@ -3322,9 +3060,7 @@ _ssl__SSLContext_impl(PyTypeObject *type + static int + context_traverse(PySSLContext *self, visitproc visit, void *arg) + { +-#ifndef OPENSSL_NO_TLSEXT + Py_VISIT(self->set_sni_cb); +-#endif + Py_VISIT(self->msg_cb); + return 0; + } +@@ -3332,11 +3068,8 @@ context_traverse(PySSLContext *self, vis + static int + context_clear(PySSLContext *self) + { +-#ifndef OPENSSL_NO_TLSEXT + Py_CLEAR(self->set_sni_cb); +-#endif + Py_CLEAR(self->msg_cb); +-#ifdef HAVE_OPENSSL_KEYLOG + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + PySSL_BEGIN_ALLOW_THREADS +@@ -3344,7 +3077,6 @@ context_clear(PySSLContext *self) + PySSL_END_ALLOW_THREADS + self->keylog_bio = NULL; + } +-#endif + return 0; + } + +@@ -3355,12 +3087,7 @@ context_dealloc(PySSLContext *self) + PyObject_GC_UnTrack(self); + context_clear(self); + SSL_CTX_free(self->ctx); +-#if HAVE_NPN +- PyMem_FREE(self->npn_protocols); +-#endif +-#if HAVE_ALPN + PyMem_FREE(self->alpn_protocols); +-#endif + Py_TYPE(self)->tp_free(self); + } + +@@ -3387,7 +3114,6 @@ _ssl__SSLContext_set_ciphers_impl(PySSLC + Py_RETURN_NONE; + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10002000UL + /*[clinic input] + _ssl._SSLContext.get_ciphers + [clinic start generated code]*/ +@@ -3430,10 +3156,8 @@ _ssl__SSLContext_get_ciphers_impl(PySSLC + return result; + + } +-#endif + + +-#if HAVE_NPN || HAVE_ALPN + static int + do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, + const unsigned char *server_protocols, unsigned int server_protocols_len, +@@ -3457,77 +3181,7 @@ do_protocol_selection(int alpn, unsigned + + return SSL_TLSEXT_ERR_OK; + } +-#endif + +-#if HAVE_NPN +-/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ +-static int +-_advertiseNPN_cb(SSL *s, +- const unsigned char **data, unsigned int *len, +- void *args) +-{ +- PySSLContext *ssl_ctx = (PySSLContext *) args; +- +- if (ssl_ctx->npn_protocols == NULL) { +- *data = (unsigned char *)""; +- *len = 0; +- } else { +- *data = ssl_ctx->npn_protocols; +- *len = ssl_ctx->npn_protocols_len; +- } +- +- return SSL_TLSEXT_ERR_OK; +-} +-/* this callback gets passed to SSL_CTX_set_next_proto_select_cb */ +-static int +-_selectNPN_cb(SSL *s, +- unsigned char **out, unsigned char *outlen, +- const unsigned char *server, unsigned int server_len, +- void *args) +-{ +- PySSLContext *ctx = (PySSLContext *)args; +- return do_protocol_selection(0, out, outlen, server, server_len, +- ctx->npn_protocols, ctx->npn_protocols_len); +-} +-#endif +- +-/*[clinic input] +-_ssl._SSLContext._set_npn_protocols +- protos: Py_buffer +- / +-[clinic start generated code]*/ +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, +- Py_buffer *protos) +-/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ +-{ +-#if HAVE_NPN +- PyMem_Free(self->npn_protocols); +- self->npn_protocols = PyMem_Malloc(protos->len); +- if (self->npn_protocols == NULL) +- return PyErr_NoMemory(); +- memcpy(self->npn_protocols, protos->buf, protos->len); +- self->npn_protocols_len = (int) protos->len; +- +- /* set both server and client callbacks, because the context can +- * be used to create both types of sockets */ +- SSL_CTX_set_next_protos_advertised_cb(self->ctx, +- _advertiseNPN_cb, +- self); +- SSL_CTX_set_next_proto_select_cb(self->ctx, +- _selectNPN_cb, +- self); +- +- Py_RETURN_NONE; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The NPN extension requires OpenSSL 1.0.1 or later."); +- return NULL; +-#endif +-} +- +-#if HAVE_ALPN + static int + _selectALPN_cb(SSL *s, + const unsigned char **out, unsigned char *outlen, +@@ -3539,7 +3193,6 @@ _selectALPN_cb(SSL *s, + ctx->alpn_protocols, ctx->alpn_protocols_len, + client_protocols, client_protocols_len); + } +-#endif + + /*[clinic input] + _ssl._SSLContext._set_alpn_protocols +@@ -3552,7 +3205,6 @@ _ssl__SSLContext__set_alpn_protocols_imp + Py_buffer *protos) + /*[clinic end generated code: output=87599a7f76651a9b input=9bba964595d519be]*/ + { +-#if HAVE_ALPN + if ((size_t)protos->len > UINT_MAX) { + PyErr_Format(PyExc_OverflowError, + "protocols longer than %u bytes", UINT_MAX); +@@ -3571,11 +3223,6 @@ _ssl__SSLContext__set_alpn_protocols_imp + SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); + + Py_RETURN_NONE; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The ALPN extension requires OpenSSL 1.0.2 or later."); +- return NULL; +-#endif + } + + static PyObject * +@@ -3651,9 +3298,6 @@ set_verify_flags(PySSLContext *self, PyO + } + + /* Getter and setter for protocol version */ +-#if defined(SSL_CTRL_GET_MAX_PROTO_VERSION) +- +- + static int + set_min_max_proto_version(PySSLContext *self, PyObject *arg, int what) + { +@@ -3748,9 +3392,8 @@ set_maximum_version(PySSLContext *self, + { + return set_min_max_proto_version(self, arg, 1); + } +-#endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ + +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) ++#ifdef TLS1_3_VERSION + static PyObject * + get_num_tickets(PySSLContext *self, void *c) + { +@@ -3781,7 +3424,7 @@ set_num_tickets(PySSLContext *self, PyOb + + PyDoc_STRVAR(PySSLContext_num_tickets_doc, + "Control the number of TLSv1.3 session tickets"); +-#endif /* OpenSSL 1.1.1 */ ++#endif /* TLS1_3_VERSION */ + + static PyObject * + get_options(PySSLContext *self, void *c) +@@ -3799,13 +3442,7 @@ set_options(PySSLContext *self, PyObject + clear = opts & ~new_opts; + set = ~opts & new_opts; + if (clear) { +-#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS + SSL_CTX_clear_options(self->ctx, clear); +-#else +- PyErr_SetString(PyExc_ValueError, +- "can't clear options before OpenSSL 0.9.8m"); +- return -1; +-#endif + } + if (set) + SSL_CTX_set_options(self->ctx, set); +@@ -4503,7 +4140,6 @@ _ssl__SSLContext_set_default_verify_path + Py_RETURN_NONE; + } + +-#ifndef OPENSSL_NO_ECDH + /*[clinic input] + _ssl._SSLContext.set_ecdh_curve + name: object +@@ -4538,9 +4174,7 @@ _ssl__SSLContext_set_ecdh_curve(PySSLCon + EC_KEY_free(key); + Py_RETURN_NONE; + } +-#endif + +-#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) + static int + _servername_callback(SSL *s, int *al, void *args) + { +@@ -4644,7 +4278,6 @@ error: + PyGILState_Release(gstate); + return ret; + } +-#endif + + static PyObject * + get_sni_callback(PySSLContext *self, void *c) +@@ -4665,7 +4298,6 @@ set_sni_callback(PySSLContext *self, PyO + "sni_callback cannot be set on TLS_CLIENT context"); + return -1; + } +-#if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) + Py_CLEAR(self->set_sni_cb); + if (arg == Py_None) { + SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); +@@ -4683,13 +4315,6 @@ set_sni_callback(PySSLContext *self, PyO + SSL_CTX_set_tlsext_servername_arg(self->ctx, self); + } + return 0; +-#else +- PyErr_SetString(PyExc_NotImplementedError, +- "The TLS extension servername callback, " +- "SSL_CTX_set_tlsext_servername_callback, " +- "is not in the current OpenSSL library."); +- return -1; +-#endif + } + + /* Shim of X509_STORE_get1_objects API from OpenSSL 3.3 +@@ -4885,21 +4510,17 @@ static PyGetSetDef context_getsetlist[] + (setter) set_check_hostname, NULL}, + {"_host_flags", (getter) get_host_flags, + (setter) set_host_flags, NULL}, +-#if SSL_CTRL_GET_MAX_PROTO_VERSION + {"minimum_version", (getter) get_minimum_version, + (setter) set_minimum_version, NULL}, + {"maximum_version", (getter) get_maximum_version, + (setter) set_maximum_version, NULL}, +-#endif +-#ifdef HAVE_OPENSSL_KEYLOG + {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, + (setter) _PySSLContext_set_keylog_filename, NULL}, +-#endif + {"_msg_callback", (getter) _PySSLContext_get_msg_callback, + (setter) _PySSLContext_set_msg_callback, NULL}, + {"sni_callback", (getter) get_sni_callback, + (setter) set_sni_callback, PySSLContext_sni_callback_doc}, +-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) ++#ifdef TLS1_3_VERSION + {"num_tickets", (getter) get_num_tickets, + (setter) set_num_tickets, PySSLContext_num_tickets_doc}, + #endif +@@ -4926,7 +4547,6 @@ static struct PyMethodDef context_method + _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF + _SSL__SSLCONTEXT_SET_CIPHERS_METHODDEF + _SSL__SSLCONTEXT__SET_ALPN_PROTOCOLS_METHODDEF +- _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF + _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF + _SSL__SSLCONTEXT_LOAD_DH_PARAMS_METHODDEF + _SSL__SSLCONTEXT_LOAD_VERIFY_LOCATIONS_METHODDEF +@@ -5444,11 +5064,7 @@ PySSL_RAND(int len, int pseudo) + if (bytes == NULL) + return NULL; + if (pseudo) { +-#ifdef PY_OPENSSL_1_1_API + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +-#else +- ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +-#endif + if (ok == 0 || ok == 1) + return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); + } +@@ -6003,92 +5619,6 @@ static PyMethodDef PySSL_methods[] = { + }; + + +-#ifdef HAVE_OPENSSL_CRYPTO_LOCK +- +-/* an implementation of OpenSSL threading operations in terms +- * of the Python C thread library +- * Only used up to 1.0.2. OpenSSL 1.1.0+ has its own locking code. +- */ +- +-static PyThread_type_lock *_ssl_locks = NULL; +- +-#if OPENSSL_VERSION_NUMBER >= 0x10000000 +-/* use new CRYPTO_THREADID API. */ +-static void +-_ssl_threadid_callback(CRYPTO_THREADID *id) +-{ +- CRYPTO_THREADID_set_numeric(id, PyThread_get_thread_ident()); +-} +-#else +-/* deprecated CRYPTO_set_id_callback() API. */ +-static unsigned long +-_ssl_thread_id_function (void) { +- return PyThread_get_thread_ident(); +-} +-#endif +- +-static void _ssl_thread_locking_function +- (int mode, int n, const char *file, int line) { +- /* this function is needed to perform locking on shared data +- structures. (Note that OpenSSL uses a number of global data +- structures that will be implicitly shared whenever multiple +- threads use OpenSSL.) Multi-threaded applications will +- crash at random if it is not set. +- +- locking_function() must be able to handle up to +- CRYPTO_num_locks() different mutex locks. It sets the n-th +- lock if mode & CRYPTO_LOCK, and releases it otherwise. +- +- file and line are the file number of the function setting the +- lock. They can be useful for debugging. +- */ +- +- if ((_ssl_locks == NULL) || +- (n < 0) || ((unsigned)n >= _ssl_locks_count)) +- return; +- +- if (mode & CRYPTO_LOCK) { +- PyThread_acquire_lock(_ssl_locks[n], 1); +- } else { +- PyThread_release_lock(_ssl_locks[n]); +- } +-} +- +-static int _setup_ssl_threads(void) { +- +- unsigned int i; +- +- if (_ssl_locks == NULL) { +- _ssl_locks_count = CRYPTO_num_locks(); +- _ssl_locks = PyMem_Calloc(_ssl_locks_count, +- sizeof(PyThread_type_lock)); +- if (_ssl_locks == NULL) { +- PyErr_NoMemory(); +- return 0; +- } +- for (i = 0; i < _ssl_locks_count; i++) { +- _ssl_locks[i] = PyThread_allocate_lock(); +- if (_ssl_locks[i] == NULL) { +- unsigned int j; +- for (j = 0; j < i; j++) { +- PyThread_free_lock(_ssl_locks[j]); +- } +- PyMem_Free(_ssl_locks); +- return 0; +- } +- } +- CRYPTO_set_locking_callback(_ssl_thread_locking_function); +-#if OPENSSL_VERSION_NUMBER >= 0x10000000 +- CRYPTO_THREADID_set_callback(_ssl_threadid_callback); +-#else +- CRYPTO_set_id_callback(_ssl_thread_id_function); +-#endif +- } +- return 1; +-} +- +-#endif /* HAVE_OPENSSL_CRYPTO_LOCK for OpenSSL < 1.1.0 */ +- + PyDoc_STRVAR(module_doc, + "Implementation module for SSL socket operations. See the socket module\n\ + for documentation."); +@@ -6155,14 +5685,6 @@ PyInit__ssl(void) + return NULL; + PySocketModule = *socket_api; + +-#ifndef OPENSSL_VERSION_1_1 +- /* Load all algorithms and initialize cpuid */ +- OPENSSL_add_all_algorithms_noconf(); +- /* Init OpenSSL */ +- SSL_load_error_strings(); +- SSL_library_init(); +-#endif +- + #ifdef HAVE_OPENSSL_CRYPTO_LOCK + /* note that this will start threading if not already started */ + if (!_setup_ssl_threads()) { +@@ -6269,10 +5791,8 @@ PyInit__ssl(void) + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + PyModule_AddIntConstant(m, "VERIFY_X509_STRICT", + X509_V_FLAG_X509_STRICT); +-#ifdef X509_V_FLAG_TRUSTED_FIRST + PyModule_AddIntConstant(m, "VERIFY_X509_TRUSTED_FIRST", + X509_V_FLAG_TRUSTED_FIRST); +-#endif + + /* Alert Descriptions from ssl.h */ + /* note RESERVED constants no longer intended for use have been removed */ +@@ -6429,31 +5949,11 @@ PyInit__ssl(void) + PyModule_AddObject((m), (key), bool_obj); \ + } while (0) + +-#if HAVE_SNI + addbool(m, "HAS_SNI", 1); +-#else +- addbool(m, "HAS_SNI", 0); +-#endif +- + addbool(m, "HAS_TLS_UNIQUE", 1); +- +-#ifndef OPENSSL_NO_ECDH + addbool(m, "HAS_ECDH", 1); +-#else +- addbool(m, "HAS_ECDH", 0); +-#endif +- +-#if HAVE_NPN +- addbool(m, "HAS_NPN", 1); +-#else + addbool(m, "HAS_NPN", 0); +-#endif +- +-#if HAVE_ALPN + addbool(m, "HAS_ALPN", 1); +-#else +- addbool(m, "HAS_ALPN", 0); +-#endif + + #if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) + addbool(m, "HAS_SSLv2", 1); +--- a/Modules/_ssl/debughelpers.c ++++ b/Modules/_ssl/debughelpers.c +@@ -114,8 +114,6 @@ _PySSLContext_set_msg_callback(PySSLCont + return 0; + } + +-#ifdef HAVE_OPENSSL_KEYLOG +- + static void + _PySSL_keylog_callback(const SSL *ssl, const char *line) + { +@@ -219,5 +217,3 @@ _PySSLContext_set_keylog_filename(PySSLC + SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); + return 0; + } +- +-#endif +--- a/Modules/clinic/_hashopenssl.c.h ++++ b/Modules/clinic/_hashopenssl.c.h +@@ -420,7 +420,7 @@ exit: + return return_value; + } + +-#if (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) ++#if defined(PY_OPENSSL_HAS_SCRYPT) + + PyDoc_STRVAR(_hashlib_scrypt__doc__, + "scrypt($module, /, password, *, salt=None, n=None, r=None, p=None,\n" +@@ -548,7 +548,7 @@ exit: + return return_value; + } + +-#endif /* (OPENSSL_VERSION_NUMBER > 0x10100000L && !defined(OPENSSL_NO_SCRYPT) && !defined(LIBRESSL_VERSION_NUMBER)) */ ++#endif /* defined(PY_OPENSSL_HAS_SCRYPT) */ + + PyDoc_STRVAR(_hashlib_hmac_digest__doc__, + "hmac_digest($module, /, key, msg, digest)\n" +--- a/Modules/clinic/_ssl.c.h ++++ b/Modules/clinic/_ssl.c.h +@@ -139,29 +139,6 @@ _ssl__SSLSocket_version(PySSLSocket *sel + return _ssl__SSLSocket_version_impl(self); + } + +-#if (HAVE_NPN) +- +-PyDoc_STRVAR(_ssl__SSLSocket_selected_npn_protocol__doc__, +-"selected_npn_protocol($self, /)\n" +-"--\n" +-"\n"); +- +-#define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF \ +- {"selected_npn_protocol", (PyCFunction)_ssl__SSLSocket_selected_npn_protocol, METH_NOARGS, _ssl__SSLSocket_selected_npn_protocol__doc__}, +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol_impl(PySSLSocket *self); +- +-static PyObject * +-_ssl__SSLSocket_selected_npn_protocol(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +-{ +- return _ssl__SSLSocket_selected_npn_protocol_impl(self); +-} +- +-#endif /* (HAVE_NPN) */ +- +-#if (HAVE_ALPN) +- + PyDoc_STRVAR(_ssl__SSLSocket_selected_alpn_protocol__doc__, + "selected_alpn_protocol($self, /)\n" + "--\n" +@@ -179,8 +156,6 @@ _ssl__SSLSocket_selected_alpn_protocol(P + return _ssl__SSLSocket_selected_alpn_protocol_impl(self); + } + +-#endif /* (HAVE_ALPN) */ +- + PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__, + "compression($self, /)\n" + "--\n" +@@ -457,8 +432,6 @@ exit: + return return_value; + } + +-#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL) +- + PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__, + "get_ciphers($self, /)\n" + "--\n" +@@ -476,44 +449,6 @@ _ssl__SSLContext_get_ciphers(PySSLContex + return _ssl__SSLContext_get_ciphers_impl(self); + } + +-#endif /* (OPENSSL_VERSION_NUMBER >= 0x10002000UL) */ +- +-PyDoc_STRVAR(_ssl__SSLContext__set_npn_protocols__doc__, +-"_set_npn_protocols($self, protos, /)\n" +-"--\n" +-"\n"); +- +-#define _SSL__SSLCONTEXT__SET_NPN_PROTOCOLS_METHODDEF \ +- {"_set_npn_protocols", (PyCFunction)_ssl__SSLContext__set_npn_protocols, METH_O, _ssl__SSLContext__set_npn_protocols__doc__}, +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, +- Py_buffer *protos); +- +-static PyObject * +-_ssl__SSLContext__set_npn_protocols(PySSLContext *self, PyObject *arg) +-{ +- PyObject *return_value = NULL; +- Py_buffer protos = {NULL, NULL}; +- +- if (PyObject_GetBuffer(arg, &protos, PyBUF_SIMPLE) != 0) { +- goto exit; +- } +- if (!PyBuffer_IsContiguous(&protos, 'C')) { +- _PyArg_BadArgument("_set_npn_protocols", "argument", "contiguous buffer", arg); +- goto exit; +- } +- return_value = _ssl__SSLContext__set_npn_protocols_impl(self, &protos); +- +-exit: +- /* Cleanup for protos */ +- if (protos.obj) { +- PyBuffer_Release(&protos); +- } +- +- return return_value; +-} +- + PyDoc_STRVAR(_ssl__SSLContext__set_alpn_protocols__doc__, + "_set_alpn_protocols($self, protos, /)\n" + "--\n" +@@ -844,8 +779,6 @@ _ssl__SSLContext_set_default_verify_path + return _ssl__SSLContext_set_default_verify_paths_impl(self); + } + +-#if !defined(OPENSSL_NO_ECDH) +- + PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__, + "set_ecdh_curve($self, name, /)\n" + "--\n" +@@ -854,8 +787,6 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_c + #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF \ + {"set_ecdh_curve", (PyCFunction)_ssl__SSLContext_set_ecdh_curve, METH_O, _ssl__SSLContext_set_ecdh_curve__doc__}, + +-#endif /* !defined(OPENSSL_NO_ECDH) */ +- + PyDoc_STRVAR(_ssl__SSLContext_cert_store_stats__doc__, + "cert_store_stats($self, /)\n" + "--\n" +@@ -1455,22 +1386,6 @@ exit: + + #endif /* defined(_MSC_VER) */ + +-#ifndef _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF +- #define _SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF +-#endif /* !defined(_SSL__SSLSOCKET_SELECTED_NPN_PROTOCOL_METHODDEF) */ +- +-#ifndef _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF +- #define _SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF +-#endif /* !defined(_SSL__SSLSOCKET_SELECTED_ALPN_PROTOCOL_METHODDEF) */ +- +-#ifndef _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +- #define _SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF +-#endif /* !defined(_SSL__SSLCONTEXT_GET_CIPHERS_METHODDEF) */ +- +-#ifndef _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF +- #define _SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF +-#endif /* !defined(_SSL__SSLCONTEXT_SET_ECDH_CURVE_METHODDEF) */ +- + #ifndef _SSL_RAND_EGD_METHODDEF + #define _SSL_RAND_EGD_METHODDEF + #endif /* !defined(_SSL_RAND_EGD_METHODDEF) */ +--- a/Tools/ssl/multissltests.py ++++ b/Tools/ssl/multissltests.py +@@ -43,8 +43,6 @@ import tarfile + log = logging.getLogger("multissl") + + OPENSSL_OLD_VERSIONS = [ +- "1.0.2u", +- "1.1.0l", + ] + + OPENSSL_RECENT_VERSIONS = [ +@@ -53,11 +51,9 @@ OPENSSL_RECENT_VERSIONS = [ + ] + + LIBRESSL_OLD_VERSIONS = [ +- "2.9.2", + ] + + LIBRESSL_RECENT_VERSIONS = [ +- "3.1.0", + ] + + # store files in ../multissl +--- a/configure ++++ b/configure +@@ -88,6 +88,13 @@ fi + # splitting by setting IFS to empty value.) + IFS=" "" $as_nl" + ++# IFS ++# We need space, tab and new line, in precisely that order. Quoting is ++# there to prevent editors from complaining about space-tab. ++# (If _AS_PATH_WALK were called with IFS unset, it would disable word ++# splitting by setting IFS to empty value.) ++IFS=" "" $as_nl" ++ + # Find who we are. Look in the path if we contain no directory separator. + as_myself= + case $0 in #(( +@@ -17734,7 +17741,6 @@ as_fn_error () + as_fn_exit $as_status + } # as_fn_error + +- + # as_fn_set_status STATUS + # ----------------------- + # Set $? to STATUS, without forking. +@@ -18780,4 +18786,3 @@ if test "$Py_OPT" = 'false' -a "$Py_DEBU + echo "" >&6 + echo "" >&6 + fi +- +--- a/configure.ac ++++ b/configure.ac +@@ -5622,42 +5622,6 @@ ac_includes_default="$save_includes_defa + # Check for usable OpenSSL + AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no]) + +-if test "$have_openssl" = yes; then +- AC_MSG_CHECKING([for X509_VERIFY_PARAM_set1_host in libssl]) +- +- save_LIBS="$LIBS" +- save_LDFLAGS="$LDFLAGS" +- save_CPPFLAGS="$CPPFLAGS" +- LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" +- LIBS="$OPENSSL_LIBS $LIBS" +- CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS" +- +- AC_LINK_IFELSE([AC_LANG_PROGRAM([ +- [#include ] +- ], [ +- [X509_VERIFY_PARAM *p = X509_VERIFY_PARAM_new();] +- [X509_VERIFY_PARAM_set1_host(p, "localhost", 0);] +- [X509_VERIFY_PARAM_set1_ip_asc(p, "127.0.0.1");] +- [X509_VERIFY_PARAM_set_hostflags(p, 0);] +- ]) +- ], +- [ +- ac_cv_has_x509_verify_param_set1_host=yes +- ], +- [ +- ac_cv_has_x509_verify_param_set1_host=no +- ]) +- AC_MSG_RESULT($ac_cv_has_x509_verify_param_set1_host) +- if test "$ac_cv_has_x509_verify_param_set1_host" = "yes"; then +- AC_DEFINE(HAVE_X509_VERIFY_PARAM_SET1_HOST, 1, +- [Define if libssl has X509_VERIFY_PARAM_set1_host and related function]) +- fi +- +- CPPFLAGS="$save_CPPFLAGS" +- LDFLAGS="$save_LDFLAGS" +- LIBS="$save_LIBS" +-fi +- + # ssl module default cipher suite string + AH_TEMPLATE(PY_SSL_DEFAULT_CIPHERS, + [Default cipher suites list for ssl module. +--- a/pyconfig.h.in ++++ b/pyconfig.h.in +@@ -1335,9 +1335,6 @@ + /* Define to 1 if you have the `writev' function. */ + #undef HAVE_WRITEV + +-/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */ +-#undef HAVE_X509_VERIFY_PARAM_SET1_HOST +- + /* Define if the zlib library has inflateCopy */ + #undef HAVE_ZLIB_COPY + +--- a/setup.py ++++ b/setup.py +@@ -439,10 +439,7 @@ class PyBuildExt(build_ext): + for l in (self.missing, self.failed, self.failed_on_import)): + print() + print("Could not build the ssl module!") +- print("Python requires an OpenSSL 1.0.2 or 1.1 compatible " +- "libssl with X509_VERIFY_PARAM_set1_host().") +- print("LibreSSL 2.6.4 and earlier do not provide the necessary " +- "APIs, https://github.com/libressl-portable/portable/issues/381") ++ print("Python requires a OpenSSL 1.1.1 or newer") + print() + + def build_extension(self, ext): +@@ -2196,13 +2193,13 @@ class PyBuildExt(build_ext): + self.missing.extend(['_ssl', '_hashlib']) + return None, None + +- # OpenSSL 1.0.2 uses Kerberos for KRB5 ciphers +- krb5_h = find_file( +- 'krb5.h', self.inc_dirs, +- ['/usr/kerberos/include'] ++ self.add(Extension( ++ '_ssl', ['_ssl.c'], ++ include_dirs=openssl_includes, ++ library_dirs=openssl_libdirs, ++ libraries=openssl_libs, ++ depends=['socketmodule.h', '_ssl/debughelpers.c']) + ) +- if krb5_h: +- ssl_incs.extend(krb5_h) + + if config_vars.get("HAVE_X509_VERIFY_PARAM_SET1_HOST"): + self.add(Extension( +@@ -2217,8 +2214,6 @@ class PyBuildExt(build_ext): + '_ssl_data_111.h', + '_ssl_data_300.h', + ])) +- else: +- self.missing.append('_ssl') + + self.add(Extension('_hashlib', ['_hashopenssl.c'], + depends=['hashlib.h'], diff --git a/python38.changes b/python38.changes index 74935d0..9a0d410 100644 --- a/python38.changes +++ b/python38.changes @@ -7,6 +7,9 @@ Thu Aug 8 19:30:36 UTC 2024 - Matej Cepl - Add CVE-2024-6923-email-hdr-inject.patch to prevent email header injection due to unquoted newlines (bsc#1228780, CVE-2024-6923). +- Add CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch removing + support for anything but OpenSSL 1.1.1 or newer (bsc#1227233, + CVE-2024-5642). - %{profileopt} variable is set according to the variable %{do_profiling} (bsc#1227999) diff --git a/python38.spec b/python38.spec index 843c8c5..9698e2d 100644 --- a/python38.spec +++ b/python38.spec @@ -204,6 +204,9 @@ Patch46: bso1227999-reproducible-builds.patch # PATCH-FIX-UPSTREAM CVE-2024-6923-email-hdr-inject.patch bsc#1228780 mcepl@suse.com # prevent email header injection, patch from gh#python/cpython!122608 Patch47: CVE-2024-6923-email-hdr-inject.patch +# PATCH-FIX-UPSTREAM CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch bsc#1227233 mcepl@suse.com +# Remove for support for anything but OpenSSL 1.1.1 or newer +Patch48: CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch BuildRequires: autoconf-archive BuildRequires: automake BuildRequires: fdupes @@ -480,6 +483,7 @@ other applications. %patch -p1 -P 45 %patch -p1 -P 46 %patch -p1 -P 47 +%patch -p1 -P 48 # drop Autoconf version requirement sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac