From ec3589f59d2c8456591f33656639bcc303eb7bd5 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 23 Mar 2022 13:58:02 -0700 Subject: bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (cherry picked from commit 48e2010d92076b472922fa632fffc98ee150004f) Co-authored-by: Christian Heimes --- Lib/test/test_hashlib.py | 4 ++++ .../next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst | 4 ++++ Modules/_hashopenssl.c | 13 ++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 214bc3c..f845c7a 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -223,6 +223,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, 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 0000000..1a65024 --- /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 4873bb1..4db058c 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1860,15 +1860,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) { @@ -1894,7 +1900,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); -- cgit v0.12