python38/CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch

1743 lines
58 KiB
Diff
Raw Permalink Normal View History

From 3ddf7fa83b19463e710b75ae6e8a28831e575f3d Mon Sep 17 00:00:00 2001
From: Christian Heimes <christian@python.org>
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 <openssl/x509_vfy.h>]
- ], [
- [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'],