39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
|
import functools
|
||
|
import hashlib
|
||
|
import unittest
|
||
|
|
||
|
try:
|
||
|
import _hashlib
|
||
|
except ImportError:
|
||
|
_hashlib = None
|
||
|
|
||
|
|
||
|
def requires_hashdigest(digestname, openssl=None, usedforsecurity=True):
|
||
|
"""Decorator raising SkipTest if a hashing algorithm is not available
|
||
|
|
||
|
The hashing algorithm could be missing or blocked by a strict crypto
|
||
|
policy.
|
||
|
|
||
|
If 'openssl' is True, then the decorator checks that OpenSSL provides
|
||
|
the algorithm. Otherwise the check falls back to built-in
|
||
|
implementations. The usedforsecurity flag is passed to the constructor.
|
||
|
|
||
|
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
|
||
|
ValueError: unsupported hash type md4
|
||
|
"""
|
||
|
def decorator(func):
|
||
|
@functools.wraps(func)
|
||
|
def wrapper(*args, **kwargs):
|
||
|
try:
|
||
|
if openssl and _hashlib is not None:
|
||
|
_hashlib.new(digestname, usedforsecurity=usedforsecurity)
|
||
|
else:
|
||
|
hashlib.new(digestname, usedforsecurity=usedforsecurity)
|
||
|
except ValueError:
|
||
|
raise unittest.SkipTest(
|
||
|
f"hash digest '{digestname}' is not available."
|
||
|
)
|
||
|
return func(*args, **kwargs)
|
||
|
return wrapper
|
||
|
return decorator
|