Skip to content

Commit 48e2010

Browse files
authored
bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076)
1 parent c62b944 commit 48e2010

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

Lib/test/test_hashlib.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ def test_algorithms_guaranteed(self):
223223
def test_algorithms_available(self):
224224
self.assertTrue(set(hashlib.algorithms_guaranteed).
225225
issubset(hashlib.algorithms_available))
226+
# all available algorithms must be loadable, bpo-47101
227+
self.assertNotIn("undefined", hashlib.algorithms_available)
228+
for name in hashlib.algorithms_available:
229+
digest = hashlib.new(name, usedforsecurity=False)
226230

227231
def test_usedforsecurity_true(self):
228232
hashlib.new("sha256", usedforsecurity=True)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:const:`hashlib.algorithms_available` now lists only algorithms that are
2+
provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are
3+
not listed unless the legacy provider has been loaded into the default
4+
OSSL context.

Modules/_hashopenssl.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1836,15 +1836,21 @@ typedef struct _internal_name_mapper_state {
18361836

18371837
/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
18381838
static void
1839+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1840+
_openssl_hash_name_mapper(EVP_MD *md, void *arg)
1841+
#else
18391842
_openssl_hash_name_mapper(const EVP_MD *md, const char *from,
18401843
const char *to, void *arg)
1844+
#endif
18411845
{
18421846
_InternalNameMapperState *state = (_InternalNameMapperState *)arg;
18431847
PyObject *py_name;
18441848

18451849
assert(state != NULL);
1846-
if (md == NULL)
1850+
// ignore all undefined providers
1851+
if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) {
18471852
return;
1853+
}
18481854

18491855
py_name = py_digest_name(md);
18501856
if (py_name == NULL) {
@@ -1870,7 +1876,12 @@ hashlib_md_meth_names(PyObject *module)
18701876
return -1;
18711877
}
18721878

1879+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1880+
// get algorithms from all activated providers in default context
1881+
EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state);
1882+
#else
18731883
EVP_MD_do_all(&_openssl_hash_name_mapper, &state);
1884+
#endif
18741885

18751886
if (state.error) {
18761887
Py_DECREF(state.set);

0 commit comments

Comments
 (0)