Closed
Description
hmac
won't fall back if OpenSSL is available, the requested algorithm isn't in OpenSSL, but the algorithm is in hashlib
.
If you [monkey]patch hashlib
to include a new algorithm, you can't use that algorithm from hmac
by name.
It appears that the OpenSSL implementation (known as _hashlib
from inside hashlib
, or _hashopenssl
from inside hmac
) doesn't actually return an UnsupportedDigestmodError
, but rather it's base class ValueError
.
MRE
# The following is MRE-specific to easily introduce a new name
# My use case involves a monkeypatch, but imagine any algorithm NOT implemented by OpenSSL, ONLY by hashlib
>>> hashlib.__builtin_constructor_cache['myhashalg'] = hashlib.md5
>>> hashlib.new('myhashalg', b'').digest().hex() # confirm hashlib can use that name
'd41d8cd98f00b204e9800998ecf8427e'
>>> hmac.digest(b'key', b'message', 'myhashalg')
Traceback (most recent call last):
File "<pyshell#nnn>", line 1, in <module>
hmac.digest(b'key', b'message', 'myhashalg')
File "C:\Python311\Lib\hmac.py", line 198, in digest
return _hashopenssl.hmac_digest(key, msg, digest)
ValueError: unsupported hash type myhashalg
The exception goes unhandled at
Line 199 in 933dfd7
hashlib
handle it.
This also shows up in the stateful (non-oneshot) code at
Line 61 in 933dfd7
Passing a callable works as intended with my monkeypatch, so I have a workaround. However, I'd argue that either
hmac
is trying to catch the wrong thing, or OpenSSL is throwing the wrong thing, so some sort of fix is called for.
Environment
Windows 10 64-bit
Python 3.11.2
Possible fixes
- Change
_hashopenssl.hmac_digest
to correctly raise anUnsupportedDigestmodError
(this looks like what was intended, given bpo-40645: use C implementation of HMAC #24920) - Catch a
ValueError
instead (asUnsupportedDigestmodError
is derived fromValueError
this would work, but may not be what is truly intended) - Something closer to what existed before like https://github.com/tiran/cpython/blob/837f9e42e3a1ad03b340661afe85e67d2719334f/Lib/hmac.py#L181 ??