Block a hash algorithm for both hashing and HMAC. Be careful with this helper as a function may be allowed, but can still raise a ValueError at runtime if the OpenSSL security policy disables it, e.g., if allow_openssl=True and FIPS mode is on.
(name, *, allow_openssl=False, allow_builtin=False)
| 1016 | |
| 1017 | @contextlib.contextmanager |
| 1018 | def block_algorithm(name, *, allow_openssl=False, allow_builtin=False): |
| 1019 | """Block a hash algorithm for both hashing and HMAC. |
| 1020 | |
| 1021 | Be careful with this helper as a function may be allowed, but can |
| 1022 | still raise a ValueError at runtime if the OpenSSL security policy |
| 1023 | disables it, e.g., if allow_openssl=True and FIPS mode is on. |
| 1024 | """ |
| 1025 | with contextlib.ExitStack() as stack: |
| 1026 | if not (allow_openssl or allow_builtin): |
| 1027 | # Named constructors have a different behavior in the sense |
| 1028 | # that they are either built-ins or OpenSSL ones, but not |
| 1029 | # "agile" ones (namely once "hashlib" has been imported, |
| 1030 | # they are fixed). |
| 1031 | # |
| 1032 | # If OpenSSL is not available, hashes fall back to built-in ones, |
| 1033 | # in which case we don't need to block the explicit public hashes |
| 1034 | # as they will call a mocked one. |
| 1035 | # |
| 1036 | # If OpenSSL is available, hashes fall back to "openssl_*" ones, |
| 1037 | # except for BLAKE2b and BLAKE2s. |
| 1038 | stack.enter_context(_block_hashlib_hash_constructor(name)) |
| 1039 | elif ( |
| 1040 | # In FIPS mode, hashlib.<name>() functions may raise if they use |
| 1041 | # the OpenSSL implementation, except with usedforsecurity=False. |
| 1042 | # However, blocking such functions also means blocking them |
| 1043 | # so we again need to block them if we want to. |
| 1044 | (_hashlib := _import_module("_hashlib")) |
| 1045 | and _hashlib.get_fips_mode() |
| 1046 | and not allow_openssl |
| 1047 | ) or ( |
| 1048 | # Without OpenSSL, hashlib.<name>() functions are aliases |
| 1049 | # to built-in functions, so both of them must be blocked |
| 1050 | # as the module may have been imported before the HACL ones. |
| 1051 | not (_hashlib := _import_module("_hashlib")) |
| 1052 | and not allow_builtin |
| 1053 | ): |
| 1054 | stack.enter_context(_block_hashlib_hash_constructor(name)) |
| 1055 | |
| 1056 | if not allow_openssl: |
| 1057 | # _hashlib.new() |
| 1058 | stack.enter_context(_block_openssl_hash_new(name)) |
| 1059 | # _hashlib.openssl_*() |
| 1060 | stack.enter_context(_block_openssl_hash_constructor(name)) |
| 1061 | # _hashlib.hmac_new() |
| 1062 | stack.enter_context(_block_openssl_hmac_new(name)) |
| 1063 | # _hashlib.hmac_digest() |
| 1064 | stack.enter_context(_block_openssl_hmac_digest(name)) |
| 1065 | |
| 1066 | if not allow_builtin: |
| 1067 | # __get_builtin_constructor(name) |
| 1068 | stack.enter_context(_block_builtin_hash_new(name)) |
| 1069 | # <built-in module>.<built-in name>() |
| 1070 | stack.enter_context(_block_builtin_hash_constructor(name)) |
| 1071 | # _hmac.new(..., name) |
| 1072 | stack.enter_context(_block_builtin_hmac_new(name)) |
| 1073 | # _hmac.compute_<name>() |
| 1074 | stack.enter_context(_block_builtin_hmac_constructor(name)) |
| 1075 | # _hmac.compute_digest(..., name) |
no test coverage detected
searching dependent graphs…