From e980e80b2cc7f32ec91613a465f8e0911d278bac Mon Sep 17 00:00:00 2001 From: Pengyu Lee Date: Sun, 1 Nov 2026 07:27:07 +0800 Subject: [PATCH] =?UTF-8?q?gh-159387:=20Fix=20TLS=201.0=E2=80=931.2=20avai?= =?UTF-8?q?lability=20detection=20with=20OpenSSL=204.0=20(GH-159388)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix TLS 1.0–1.2 availability detection with OpenSSL 4.0 OpenSSL 4.0 removed the version-specific methods but still supports TLS 1.0–1.2 through TLS_method(). Stop reporting these versions as unavailable, and expose legacy PROTOCOL_TLSv1* constants only when their corresponding methods exist. (cherry picked from commit e7acd6a82f2feec196b84fdfc1d1533e37024221) Co-authored-by: Pengyu Lee --- Lib/test/test_ssl.py | 2 ++ .../2026-10-14-10-26-10.gh-issue-159387.xMbQbB.rst | 2 ++ Modules/_ssl.c | 11 +++++------ 3 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-10-14-10-26-10.gh-issue-159387.xMbQbB.rst diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d4f32bef3a277f..7cf47a7860a0dd 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4072,6 +4072,8 @@ def test_protocol_tlsv1_1(self): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) @requires_tls_version('TLSv1_2') + @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_TLSv1_2'), + 'needs ssl.PROTOCOL_TLSv1_2') def test_protocol_tlsv1_2(self): """Connecting to a TLSv1.2 server with various client options. Testing against older TLS versions.""" diff --git a/Misc/NEWS.d/next/Library/2026-10-14-10-26-10.gh-issue-159387.xMbQbB.rst b/Misc/NEWS.d/next/Library/2026-10-14-10-26-10.gh-issue-159387.xMbQbB.rst new file mode 100644 index 00000000000000..fddef6e097ba5c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-14-10-26-10.gh-issue-159387.xMbQbB.rst @@ -0,0 +1,2 @@ +Fix :mod:`ssl` reporting TLS 1.0, 1.1, and 1.2 as unavailable when built +with OpenSSL 4.0, despite support for these protocol versions. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 20e6d73c9aa412..d9f5d865e7497d 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -170,10 +170,9 @@ static void _PySSLFixErrno(void) { #endif #if (OPENSSL_VERSION_NUMBER >= 0x40000000L) +/* OpenSSL 4.0 removed SSLv3 and the version-specific methods, + * but TLS 1.0, 1.1 and 1.2 are still available via TLS_method(). */ # define OPENSSL_NO_SSL3 -# define OPENSSL_NO_TLS1 -# define OPENSSL_NO_TLS1_1 -# define OPENSSL_NO_TLS1_2 # define OPENSSL_NO_SSL3_METHOD # define OPENSSL_NO_TLS1_METHOD # define OPENSSL_NO_TLS1_1_METHOD @@ -7123,13 +7122,13 @@ sslmodule_init_constants(PyObject *m) ADD_INT_CONST("PROTOCOL_TLS", PY_SSL_VERSION_TLS); ADD_INT_CONST("PROTOCOL_TLS_CLIENT", PY_SSL_VERSION_TLS_CLIENT); ADD_INT_CONST("PROTOCOL_TLS_SERVER", PY_SSL_VERSION_TLS_SERVER); -#ifndef OPENSSL_NO_TLS1 +#if !defined(OPENSSL_NO_TLS1) && !defined(OPENSSL_NO_TLS1_METHOD) ADD_INT_CONST("PROTOCOL_TLSv1", PY_SSL_VERSION_TLS1); #endif -#ifndef OPENSSL_NO_TLS1_1 +#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1_METHOD) ADD_INT_CONST("PROTOCOL_TLSv1_1", PY_SSL_VERSION_TLS1_1); #endif -#ifndef OPENSSL_NO_TLS1_2 +#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2_METHOD) ADD_INT_CONST("PROTOCOL_TLSv1_2", PY_SSL_VERSION_TLS1_2); #endif