aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2022-03-23 23:15:25 +0200
committerMichał Górny <mgorny@gentoo.org>2022-05-16 10:49:46 +0200
commit5c8dc10d3125ca0a70ada2daee38859bbd0cf39e (patch)
treebc951ee692b634ec09e2f8eb3f6f44d1dc7e755b
parent[3.9] bpo-46114: Fix OpenSSL version check for 3.0.1 (GH-30170) (GH-30173) (diff)
downloadcpython-5c8dc10d3125ca0a70ada2daee38859bbd0cf39e.tar.gz
cpython-5c8dc10d3125ca0a70ada2daee38859bbd0cf39e.tar.bz2
cpython-5c8dc10d3125ca0a70ada2daee38859bbd0cf39e.zip
[3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085)gentoo-3.8.13_p1
Co-authored-by: Christian Heimes <christian@python.org> (rebased for 3.8 by Michał Górny)
-rw-r--r--Lib/test/test_hashlib.py4
-rw-r--r--Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst4
-rw-r--r--Modules/_hashopenssl.c13
3 files changed, 20 insertions, 1 deletions
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index 8b53d23ef52..88fbc0cee97 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -203,6 +203,10 @@ class HashLibTestCase(unittest.TestCase):
def test_algorithms_available(self):
self.assertTrue(set(hashlib.algorithms_guaranteed).
issubset(hashlib.algorithms_available))
+ # all available algorithms must be loadable, bpo-47101
+ self.assertNotIn("undefined", hashlib.algorithms_available)
+ for name in hashlib.algorithms_available:
+ digest = hashlib.new(name)
def test_unknown_hash(self):
self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst
new file mode 100644
index 00000000000..1a65024e69f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst
@@ -0,0 +1,4 @@
+:const:`hashlib.algorithms_available` now lists only algorithms that are
+provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are
+not listed unless the legacy provider has been loaded into the default
+OSSL context.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index d518f586e1d..18f8c5c21e9 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -1038,15 +1038,21 @@ typedef struct _internal_name_mapper_state {
/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
static void
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+_openssl_hash_name_mapper(EVP_MD *md, void *arg)
+#else
_openssl_hash_name_mapper(const EVP_MD *md, const char *from,
const char *to, void *arg)
+#endif
{
_InternalNameMapperState *state = (_InternalNameMapperState *)arg;
PyObject *py_name;
assert(state != NULL);
- if (md == NULL)
+ // ignore all undefined providers
+ if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) {
return;
+ }
py_name = py_digest_name(md);
if (py_name == NULL) {
@@ -1070,7 +1076,12 @@ generate_hash_name_list(void)
return NULL;
state.error = 0;
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ // get algorithms from all activated providers in default context
+ EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state);
+#else
EVP_MD_do_all(&_openssl_hash_name_mapper, &state);
+#endif
if (state.error) {
Py_DECREF(state.set);