mirror of
https://github.com/python/cpython
synced 2024-09-04 15:56:13 +00:00
bpo-43669: PEP 644: Require OpenSSL 1.1.1 or newer (GH-23014)
- 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
This commit is contained in:
parent
b467d9a240
commit
39258d3595
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -177,7 +177,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
openssl_ver: [1.0.2u, 1.1.0l, 1.1.1k, 3.0.0-alpha14]
|
||||
openssl_ver: [1.1.1k, 3.0.0-alpha14]
|
||||
env:
|
||||
OPENSSL_VER: ${{ matrix.openssl_ver }}
|
||||
MULTISSL_DIR: ${{ github.workspace }}/multissl
|
||||
|
|
|
@ -135,6 +135,7 @@ some Unices may not have the :program:`env` command, so you may need to hardcode
|
|||
|
||||
To use shell commands in your Python scripts, look at the :mod:`subprocess` module.
|
||||
|
||||
.. _unix_custom_openssl:
|
||||
|
||||
Custom OpenSSL
|
||||
==============
|
||||
|
|
|
@ -65,6 +65,7 @@ Summary -- Release highlights
|
|||
|
||||
.. PEP-sized items next.
|
||||
|
||||
* :pep:`644`, require OpenSSL 1.1.1 or newer
|
||||
|
||||
|
||||
New Features
|
||||
|
@ -1438,6 +1439,10 @@ CPython bytecode changes
|
|||
Build Changes
|
||||
=============
|
||||
|
||||
* :pep:`644`: Python now requires OpenSSL 1.1.1 or newer. OpenSSL 1.0.2 is no
|
||||
longer supported.
|
||||
(Contributed by Christian Heimes in :issue:`43669`.)
|
||||
|
||||
* The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now required
|
||||
to build Python.
|
||||
(Contributed by Victor Stinner in :issue:`36020`.)
|
||||
|
@ -1483,7 +1488,6 @@ Build Changes
|
|||
(Contributed by Christian Heimes in :issue:`43466`.)
|
||||
|
||||
|
||||
|
||||
C API Changes
|
||||
=============
|
||||
|
||||
|
|
10
Lib/ssl.py
10
Lib/ssl.py
|
@ -909,15 +909,12 @@ def selected_npn_protocol(self):
|
|||
"""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,
|
||||
|
@ -1126,10 +1123,7 @@ def getpeercert(self, binary_form=False):
|
|||
@_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):
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
|
||||
HOST = socket_helper.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')
|
||||
|
@ -270,18 +269,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
|
||||
|
@ -372,17 +359,15 @@ def test_constants(self):
|
|||
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):
|
||||
|
@ -1161,7 +1146,6 @@ def test_python_ciphers(self):
|
|||
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')
|
||||
|
@ -1181,15 +1165,11 @@ def test_options(self):
|
|||
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)
|
||||
|
@ -1327,8 +1307,6 @@ def test_security_level(self):
|
|||
}
|
||||
self.assertIn(ctx.security_level, security_level_range)
|
||||
|
||||
@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
|
||||
|
@ -1797,7 +1775,6 @@ class MySSLObject(ssl.SSLObject):
|
|||
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)
|
||||
|
@ -2956,8 +2933,6 @@ def test_getpeercert(self):
|
|||
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")
|
||||
|
@ -3859,12 +3834,7 @@ def test_version_basic(self):
|
|||
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)
|
||||
|
||||
|
@ -3966,8 +3936,6 @@ def test_default_ecdh_curve(self):
|
|||
# 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))
|
||||
|
@ -4099,15 +4067,11 @@ def test_ecdh_curve(self):
|
|||
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.
|
||||
|
@ -4117,7 +4081,6 @@ def test_selected_alpn_protocol(self):
|
|||
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()
|
||||
|
@ -4127,7 +4090,6 @@ def test_selected_alpn_protocol_if_server_uses_alpn(self):
|
|||
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 = [
|
||||
|
@ -4150,22 +4112,17 @@ def test_alpn_protocols(self):
|
|||
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
|
||||
|
@ -4175,31 +4132,8 @@ def test_selected_npn_protocol(self):
|
|||
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)
|
||||
|
@ -4369,8 +4303,7 @@ def test_session(self):
|
|||
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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Implement :pep:`644`. Python now requires OpenSSL 1.1.1 or newer.
|
|
@ -207,11 +207,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).
|
||||
|
|
|
@ -38,51 +38,12 @@
|
|||
# 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
|
||||
|
||||
HMAC_CTX *
|
||||
HMAC_CTX_new(void)
|
||||
{
|
||||
HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
|
||||
if (ctx != NULL) {
|
||||
memset(ctx, 0, sizeof(HMAC_CTX));
|
||||
HMAC_CTX_init(ctx);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL) {
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
HMAC_CTX_get_md(const HMAC_CTX *ctx)
|
||||
{
|
||||
return ctx->md;
|
||||
}
|
||||
#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
|
||||
|
||||
static PyModuleDef _hashlibmodule;
|
||||
|
||||
|
@ -1252,8 +1213,7 @@ pbkdf2_hmac_impl(PyObject *module, const char *hash_name,
|
|||
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
|
||||
|
@ -1376,7 +1336,7 @@ _hashlib_scrypt_impl(PyObject *module, Py_buffer *password, Py_buffer *salt,
|
|||
}
|
||||
return key_obj;
|
||||
}
|
||||
#endif
|
||||
#endif /* PY_OPENSSL_HAS_SCRYPT */
|
||||
|
||||
/* Fast HMAC for hmac.digest()
|
||||
*/
|
||||
|
@ -1844,12 +1804,6 @@ hashlib_md_meth_names(PyObject *module)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* LibreSSL doesn't support FIPS:
|
||||
https://marc.info/?l=openbsd-misc&m=139819485423701&w=2
|
||||
|
||||
Ted Unangst wrote: "I figured I should mention our current libressl policy
|
||||
wrt FIPS mode. It's gone and it's not coming back." */
|
||||
#ifndef LIBRESSL_VERSION_NUMBER
|
||||
/*[clinic input]
|
||||
_hashlib.get_fips_mode -> int
|
||||
|
||||
|
@ -1887,7 +1841,6 @@ _hashlib_get_fips_mode_impl(PyObject *module)
|
|||
return result;
|
||||
#endif
|
||||
}
|
||||
#endif // !LIBRESSL_VERSION_NUMBER
|
||||
|
||||
|
||||
static int
|
||||
|
@ -2067,17 +2020,6 @@ hashlib_free(void *m)
|
|||
}
|
||||
|
||||
/* Py_mod_exec functions */
|
||||
static int
|
||||
hashlib_openssl_legacy_init(PyObject *module)
|
||||
{
|
||||
#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
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hashlib_init_evptype(PyObject *module)
|
||||
{
|
||||
|
@ -2200,8 +2142,6 @@ hashlib_exception(PyObject *module)
|
|||
|
||||
|
||||
static PyModuleDef_Slot hashlib_slots[] = {
|
||||
/* OpenSSL 1.0.2 and LibreSSL */
|
||||
{Py_mod_exec, hashlib_openssl_legacy_init},
|
||||
{Py_mod_exec, hashlib_init_evptype},
|
||||
{Py_mod_exec, hashlib_init_evpxoftype},
|
||||
{Py_mod_exec, hashlib_init_hmactype},
|
||||
|
|
537
Modules/_ssl.c
537
Modules/_ssl.c
|
@ -29,9 +29,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);
|
||||
|
@ -62,16 +62,6 @@ static PySocketModule_APIObject PySocketModule;
|
|||
#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
|
||||
|
@ -142,15 +132,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
|
||||
|
@ -161,129 +143,12 @@ extern const SSL_METHOD *TLSv1_1_method(void);
|
|||
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
|
||||
|
||||
/* 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
|
||||
|
||||
#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
|
||||
|
@ -395,24 +260,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 */
|
||||
|
@ -422,17 +273,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.
|
||||
|
@ -443,10 +286,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 {
|
||||
|
@ -652,23 +493,18 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno,
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -1995,7 +1831,6 @@ cipher_to_tuple(const SSL_CIPHER *cipher)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000UL
|
||||
static PyObject *
|
||||
cipher_to_dict(const SSL_CIPHER *cipher)
|
||||
{
|
||||
|
@ -2004,10 +1839,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);
|
||||
|
@ -2020,7 +1853,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;
|
||||
|
@ -2030,13 +1862,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,
|
||||
|
@ -2044,16 +1873,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
|
||||
|
@ -2124,28 +1950,6 @@ _ssl__SSLSocket_version_impl(PySSLSocket *self)
|
|||
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]*/
|
||||
|
@ -2163,7 +1967,6 @@ _ssl__SSLSocket_selected_alpn_protocol_impl(PySSLSocket *self)
|
|||
Py_RETURN_NONE;
|
||||
return PyUnicode_FromStringAndSize((char *)out, outlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*[clinic input]
|
||||
_ssl._SSLSocket.compression
|
||||
|
@ -2200,11 +2003,6 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value,
|
|||
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);
|
||||
|
@ -2213,7 +2011,6 @@ static int PySSL_set_context(PySSLSocket *self, PyObject *value,
|
|||
self->ssl,
|
||||
self->ctx->msg_cb ? _PySSL_msg_callback : NULL
|
||||
);
|
||||
#endif
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "The value must be a SSLContext");
|
||||
return -1;
|
||||
|
@ -2840,8 +2637,6 @@ _ssl__SSLSocket_verify_client_post_handshake_impl(PySSLSocket *self)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_VERSION_1_1
|
||||
|
||||
static SSL_SESSION*
|
||||
_ssl_session_dup(SSL_SESSION *session) {
|
||||
SSL_SESSION *newsession = NULL;
|
||||
|
@ -2882,7 +2677,6 @@ _ssl_session_dup(SSL_SESSION *session) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
PySSL_get_session(PySSLSocket *self, void *closure) {
|
||||
|
@ -2891,7 +2685,6 @@ PySSL_get_session(PySSLSocket *self, void *closure) {
|
|||
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 */
|
||||
|
@ -2901,12 +2694,10 @@ PySSL_get_session(PySSLSocket *self, void *closure) {
|
|||
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);
|
||||
|
@ -2925,9 +2716,7 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value,
|
|||
void *closure)
|
||||
{
|
||||
PySSLSession *pysess;
|
||||
#ifdef OPENSSL_VERSION_1_1
|
||||
SSL_SESSION *session;
|
||||
#endif
|
||||
int result;
|
||||
|
||||
if (!PySSLSession_Check(value)) {
|
||||
|
@ -2951,7 +2740,6 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value,
|
|||
"Cannot set session after handshake.");
|
||||
return -1;
|
||||
}
|
||||
#ifdef OPENSSL_VERSION_1_1
|
||||
/* duplicate session */
|
||||
if ((session = _ssl_session_dup(pysess->session)) == NULL) {
|
||||
return -1;
|
||||
|
@ -2959,9 +2747,6 @@ static int PySSL_set_session(PySSLSocket *self, PyObject *value,
|
|||
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;
|
||||
|
@ -3012,7 +2797,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
|
||||
|
@ -3089,9 +2873,6 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
|||
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) {
|
||||
|
@ -3156,19 +2937,10 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
|||
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;
|
||||
|
@ -3230,37 +3002,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
|||
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,
|
||||
|
@ -3268,11 +3012,9 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
|||
#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
|
||||
|
@ -3286,9 +3028,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
|
|||
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;
|
||||
}
|
||||
|
@ -3296,11 +3036,8 @@ context_traverse(PySSLContext *self, visitproc visit, void *arg)
|
|||
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
|
||||
|
@ -3308,7 +3045,6 @@ context_clear(PySSLContext *self)
|
|||
PySSL_END_ALLOW_THREADS
|
||||
self->keylog_bio = NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3320,12 +3056,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
|
||||
PyMem_FREE(self->alpn_protocols);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
Py_DECREF(tp);
|
||||
}
|
||||
|
@ -3353,7 +3084,6 @@ _ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000UL
|
||||
/*[clinic input]
|
||||
_ssl._SSLContext.get_ciphers
|
||||
[clinic start generated code]*/
|
||||
|
@ -3396,10 +3126,8 @@ _ssl__SSLContext_get_ciphers_impl(PySSLContext *self)
|
|||
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,
|
||||
|
@ -3423,77 +3151,7 @@ do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
|
|||
|
||||
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,
|
||||
|
@ -3505,7 +3163,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
|
||||
|
@ -3518,7 +3175,6 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self,
|
|||
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);
|
||||
|
@ -3537,11 +3193,6 @@ _ssl__SSLContext__set_alpn_protocols_impl(PySSLContext *self,
|
|||
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 *
|
||||
|
@ -3617,9 +3268,6 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -3714,9 +3362,8 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -3747,16 +3394,14 @@ set_num_tickets(PySSLContext *self, PyObject *arg, void *c)
|
|||
|
||||
PyDoc_STRVAR(PySSLContext_num_tickets_doc,
|
||||
"Control the number of TLSv1.3 session tickets");
|
||||
#endif /* OpenSSL 1.1.1 */
|
||||
#endif /* TLS1_3_VERSION */
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
static PyObject *
|
||||
get_security_level(PySSLContext *self, void *c)
|
||||
{
|
||||
return PyLong_FromLong(SSL_CTX_get_security_level(self->ctx));
|
||||
}
|
||||
PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level");
|
||||
#endif /* OpenSSL 1.1.0 */
|
||||
|
||||
static PyObject *
|
||||
get_options(PySSLContext *self, void *c)
|
||||
|
@ -3774,13 +3419,7 @@ set_options(PySSLContext *self, PyObject *arg, void *c)
|
|||
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);
|
||||
|
@ -4468,7 +4107,6 @@ _ssl__SSLContext_set_default_verify_paths_impl(PySSLContext *self)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
/*[clinic input]
|
||||
_ssl._SSLContext.set_ecdh_curve
|
||||
name: object
|
||||
|
@ -4503,9 +4141,7 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name)
|
|||
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)
|
||||
{
|
||||
|
@ -4609,7 +4245,6 @@ _servername_callback(SSL *s, int *al, void *args)
|
|||
PyGILState_Release(gstate);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
get_sni_callback(PySSLContext *self, void *c)
|
||||
|
@ -4630,7 +4265,6 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
|
|||
"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);
|
||||
|
@ -4648,13 +4282,6 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c)
|
|||
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
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(PySSLContext_sni_callback_doc,
|
||||
|
@ -4779,21 +4406,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
|
||||
|
@ -4812,10 +4435,8 @@ static PyGetSetDef context_getsetlist[] = {
|
|||
(setter) set_verify_flags, NULL},
|
||||
{"verify_mode", (getter) get_verify_mode,
|
||||
(setter) set_verify_mode, NULL},
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
{"security_level", (getter) get_security_level,
|
||||
NULL, PySSLContext_security_level_doc},
|
||||
#endif
|
||||
{NULL}, /* sentinel */
|
||||
};
|
||||
|
||||
|
@ -4824,7 +4445,6 @@ static struct PyMethodDef context_methods[] = {
|
|||
_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
|
||||
|
@ -5281,11 +4901,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);
|
||||
}
|
||||
|
@ -5840,92 +5456,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 */
|
||||
|
||||
static int
|
||||
sslmodule_init_types(PyObject *module)
|
||||
{
|
||||
|
@ -6205,10 +5735,8 @@ sslmodule_init_constants(PyObject *m)
|
|||
X509_V_FLAG_X509_STRICT);
|
||||
PyModule_AddIntConstant(m, "VERIFY_ALLOW_PROXY_CERTS",
|
||||
X509_V_FLAG_ALLOW_PROXY_CERTS);
|
||||
#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 */
|
||||
|
@ -6365,31 +5893,11 @@ sslmodule_init_constants(PyObject *m)
|
|||
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);
|
||||
|
@ -6430,29 +5938,6 @@ sslmodule_init_constants(PyObject *m)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sslmodule_legacy(PyObject *module)
|
||||
{
|
||||
#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()) {
|
||||
return 0;
|
||||
}
|
||||
#elif OPENSSL_VERSION_1_1
|
||||
/* OpenSSL 1.1.0 builtin thread support is enabled */
|
||||
_ssl_locks_count++;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(module_doc,
|
||||
"Implementation module for SSL socket operations. See the socket module\n\
|
||||
for documentation.");
|
||||
|
@ -6491,8 +5976,6 @@ PyInit__ssl(void)
|
|||
return NULL;
|
||||
if (sslmodule_init_versioninfo(m) != 0)
|
||||
return NULL;
|
||||
if (sslmodule_legacy(m) != 0)
|
||||
return NULL;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -114,8 +114,6 @@ _PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) {
|
|||
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(PySSLContext *self, PyObject *arg, void *c) {
|
|||
SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
14
Modules/clinic/_hashopenssl.c.h
generated
14
Modules/clinic/_hashopenssl.c.h
generated
|
@ -950,7 +950,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"
|
||||
|
@ -1068,7 +1068,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_singleshot__doc__,
|
||||
"hmac_digest($module, /, key, msg, digest)\n"
|
||||
|
@ -1275,8 +1275,6 @@ _hashlib_HMAC_hexdigest(HMACobject *self, PyObject *Py_UNUSED(ignored))
|
|||
return _hashlib_HMAC_hexdigest_impl(self);
|
||||
}
|
||||
|
||||
#if !defined(LIBRESSL_VERSION_NUMBER)
|
||||
|
||||
PyDoc_STRVAR(_hashlib_get_fips_mode__doc__,
|
||||
"get_fips_mode($module, /)\n"
|
||||
"--\n"
|
||||
|
@ -1312,8 +1310,6 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
|
||||
|
||||
PyDoc_STRVAR(_hashlib_compare_digest__doc__,
|
||||
"compare_digest($module, a, b, /)\n"
|
||||
"--\n"
|
||||
|
@ -1389,8 +1385,4 @@ exit:
|
|||
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
||||
#define _HASHLIB_SCRYPT_METHODDEF
|
||||
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
|
||||
|
||||
#ifndef _HASHLIB_GET_FIPS_MODE_METHODDEF
|
||||
#define _HASHLIB_GET_FIPS_MODE_METHODDEF
|
||||
#endif /* !defined(_HASHLIB_GET_FIPS_MODE_METHODDEF) */
|
||||
/*[clinic end generated code: output=980087de1b03ad42 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=162369cb9d43f1cc input=a9049054013a1b77]*/
|
||||
|
|
87
Modules/clinic/_ssl.c.h
generated
87
Modules/clinic/_ssl.c.h
generated
|
@ -139,29 +139,6 @@ _ssl__SSLSocket_version(PySSLSocket *self, PyObject *Py_UNUSED(ignored))
|
|||
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(PySSLSocket *self, PyObject *Py_UNUSED(ig
|
|||
return _ssl__SSLSocket_selected_alpn_protocol_impl(self);
|
||||
}
|
||||
|
||||
#endif /* (HAVE_ALPN) */
|
||||
|
||||
PyDoc_STRVAR(_ssl__SSLSocket_compression__doc__,
|
||||
"compression($self, /)\n"
|
||||
"--\n"
|
||||
|
@ -452,8 +427,6 @@ exit:
|
|||
return return_value;
|
||||
}
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10002000UL)
|
||||
|
||||
PyDoc_STRVAR(_ssl__SSLContext_get_ciphers__doc__,
|
||||
"get_ciphers($self, /)\n"
|
||||
"--\n"
|
||||
|
@ -471,44 +444,6 @@ _ssl__SSLContext_get_ciphers(PySSLContext *self, PyObject *Py_UNUSED(ignored))
|
|||
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"
|
||||
|
@ -829,8 +764,6 @@ _ssl__SSLContext_set_default_verify_paths(PySSLContext *self, PyObject *Py_UNUSE
|
|||
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"
|
||||
|
@ -839,8 +772,6 @@ PyDoc_STRVAR(_ssl__SSLContext_set_ecdh_curve__doc__,
|
|||
#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"
|
||||
|
@ -1420,22 +1351,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) */
|
||||
|
@ -1447,4 +1362,4 @@ exit:
|
|||
#ifndef _SSL_ENUM_CRLS_METHODDEF
|
||||
#define _SSL_ENUM_CRLS_METHODDEF
|
||||
#endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */
|
||||
/*[clinic end generated code: output=2bb53a80040c9b35 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=9468e58904a565a2 input=a9049054013a1b77]*/
|
||||
|
|
|
@ -43,21 +43,17 @@
|
|||
log = logging.getLogger("multissl")
|
||||
|
||||
OPENSSL_OLD_VERSIONS = [
|
||||
"1.0.2u",
|
||||
"1.1.0l",
|
||||
]
|
||||
|
||||
OPENSSL_RECENT_VERSIONS = [
|
||||
"1.1.1k",
|
||||
# "3.0.0-alpha14"
|
||||
"3.0.0-alpha14"
|
||||
]
|
||||
|
||||
LIBRESSL_OLD_VERSIONS = [
|
||||
"2.9.2",
|
||||
]
|
||||
|
||||
LIBRESSL_RECENT_VERSIONS = [
|
||||
"3.2.4",
|
||||
]
|
||||
|
||||
# store files in ../multissl
|
||||
|
|
36
configure.ac
36
configure.ac
|
@ -5781,42 +5781,6 @@ ac_includes_default="$save_includes_default"
|
|||
# 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
|
||||
|
||||
# rpath to libssl and libcrypto
|
||||
AC_MSG_CHECKING(for --with-openssl-rpath)
|
||||
AC_ARG_WITH(openssl-rpath,
|
||||
|
|
|
@ -1356,9 +1356,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
|
||||
|
||||
|
|
41
setup.py
41
setup.py
|
@ -551,10 +551,7 @@ def print_three_column(lst):
|
|||
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")
|
||||
if sysconfig.get_config_var("OPENSSL_LDFLAGS"):
|
||||
print("Custom linker flags may require --with-openssl-rpath=auto")
|
||||
print()
|
||||
|
@ -2431,13 +2428,13 @@ def split_var(name, sep):
|
|||
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 openssl_rpath == 'auto':
|
||||
runtime_library_dirs = openssl_libdirs[:]
|
||||
|
@ -2468,24 +2465,14 @@ def split_var(name, sep):
|
|||
# don't link OpenSSL shared libraries.
|
||||
openssl_extension_kwargs["libraries"] = []
|
||||
|
||||
if config_vars.get("HAVE_X509_VERIFY_PARAM_SET1_HOST"):
|
||||
self.add(
|
||||
Extension(
|
||||
'_ssl',
|
||||
['_ssl.c'],
|
||||
depends=[
|
||||
'socketmodule.h',
|
||||
'_ssl/debughelpers.c',
|
||||
'_ssl_data.h',
|
||||
'_ssl_data_111.h',
|
||||
'_ssl_data_300.h',
|
||||
],
|
||||
**openssl_extension_kwargs
|
||||
)
|
||||
self.add(
|
||||
Extension(
|
||||
'_ssl',
|
||||
['_ssl.c'],
|
||||
depends=['socketmodule.h', '_ssl/debughelpers.c'],
|
||||
**openssl_extension_kwargs
|
||||
)
|
||||
else:
|
||||
self.missing.append('_ssl')
|
||||
|
||||
)
|
||||
self.add(
|
||||
Extension(
|
||||
'_hashlib',
|
||||
|
|
Loading…
Reference in a new issue