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

(cherry picked from commit 48e2010d92)

Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
Miss Islington (bot) 2022-03-23 13:58:02 -07:00 committed by GitHub
parent e513b8188a
commit ec3589f59d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 1 deletions

View File

@ -223,6 +223,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)

View File

@ -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.

View File

@ -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);