[Python-checkins] [3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085)

tiran webhook-mailer at python.org
Wed Mar 23 17:15:34 EDT 2022


https://github.com/python/cpython/commit/1b6acaad9a18b2498386c60f24351ab749061e3a
commit: 1b6acaad9a18b2498386c60f24351ab749061e3a
branch: 3.10
author: Christian Heimes <christian at python.org>
committer: tiran <christian at python.org>
date: 2022-03-23T22:15:25+01:00
summary:

[3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085)

Co-authored-by: Christian Heimes <christian at python.org>

files:
A Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst
M Lib/test/test_hashlib.py
M Modules/_hashopenssl.c

diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
index ea31f8be2cb82..535f4aa3e04ca 100644
--- a/Lib/test/test_hashlib.py
+++ b/Lib/test/test_hashlib.py
@@ -221,6 +221,10 @@ def test_algorithms_guaranteed(self):
     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, usedforsecurity=False)
 
     def test_usedforsecurity_true(self):
         hashlib.new("sha256", usedforsecurity=True)
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 0000000000000..1a65024e69fbd
--- /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 65538f63f7bf4..75063fa15369a 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -1836,15 +1836,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) {
@@ -1870,7 +1876,12 @@ hashlib_md_meth_names(PyObject *module)
         return -1;
     }
 
+#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);



More information about the Python-checkins mailing list