1import functools 2import hashlib 3import unittest 4 5try: 6 import _hashlib 7except ImportError: 8 _hashlib = None 9 10 11def requires_hashdigest(digestname, openssl=None, usedforsecurity=True): 12 """Decorator raising SkipTest if a hashing algorithm is not available 13 14 The hashing algorithm could be missing or blocked by a strict crypto 15 policy. 16 17 If 'openssl' is True, then the decorator checks that OpenSSL provides 18 the algorithm. Otherwise the check falls back to built-in 19 implementations. The usedforsecurity flag is passed to the constructor. 20 21 ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS 22 ValueError: unsupported hash type md4 23 """ 24 def decorator(func): 25 @functools.wraps(func) 26 def wrapper(*args, **kwargs): 27 try: 28 if openssl and _hashlib is not None: 29 _hashlib.new(digestname, usedforsecurity=usedforsecurity) 30 else: 31 hashlib.new(digestname, usedforsecurity=usedforsecurity) 32 except ValueError: 33 raise unittest.SkipTest( 34 f"hash digest '{digestname}' is not available." 35 ) 36 return func(*args, **kwargs) 37 return wrapper 38 return decorator 39