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

Co-authored-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes 2022-03-23 23:15:25 +02:00 committed by GitHub
parent 4298114e1d
commit 1b6acaad9a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 1 deletions

View file

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

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

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