-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfips_status.py
More file actions
121 lines (111 loc) · 4.77 KB
/
Copy pathfips_status.py
File metadata and controls
121 lines (111 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# -*- coding: utf-8 -*-
"""
OpenSSL FIPS provider status helper.
Returns provider status and certificate information when the module is built
with GR_LINUX_CRYPTO_FIPS=ON and the FIPS provider is available.
"""
import ctypes
from typing import Any, Dict, Optional
def fips_status() -> Dict[str, Any]:
"""
Return OpenSSL FIPS provider status and certificate information.
Uses ctypes to query libcrypto. When the FIPS provider is not available
or the module was not built with FIPS support, returns a dict with
fips_active=False and an optional error message.
Returns:
Dict with at least:
- fips_active (bool): True if FIPS mode is enabled and active
- provider_loaded (bool): True if the FIPS provider loaded successfully
- openssl_version (str): OpenSSL version string if available
- certificate_info (str or None): FIPS certificate/validation info if available
- error (str or None): Error message if status could not be determined
"""
result: Dict[str, Any] = {
"fips_active": False,
"provider_loaded": False,
"openssl_version": None,
"certificate_info": None,
"error": None,
}
try:
libcrypto = _load_libcrypto()
if libcrypto is None:
result["error"] = "libcrypto not found"
return result
version = _get_openssl_version(libcrypto)
if version:
result["openssl_version"] = version
# OpenSSL 3.x: load FIPS provider and enable FIPS mode
try:
OSSL_PROVIDER_load = getattr(libcrypto, "OSSL_PROVIDER_load", None)
OSSL_PROVIDER_unload = getattr(libcrypto, "OSSL_PROVIDER_unload", None)
EVP_default_properties_enable_fips = getattr(
libcrypto, "EVP_default_properties_enable_fips", None
)
EVP_default_properties_is_fips_enabled = getattr(
libcrypto, "EVP_default_properties_is_fips_enabled", None
)
except AttributeError:
result["error"] = "OpenSSL 3 FIPS API not found"
return result
if (
OSSL_PROVIDER_load is None
or EVP_default_properties_enable_fips is None
):
result["error"] = "OpenSSL 3 provider API not available"
return result
# OSSL_PROVIDER_load(ctx, name) - ctx is void* (NULL)
OSSL_PROVIDER_load.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
OSSL_PROVIDER_load.restype = ctypes.c_void_p
EVP_default_properties_enable_fips.argtypes = [ctypes.c_void_p, ctypes.c_int]
EVP_default_properties_enable_fips.restype = ctypes.c_int
provider = OSSL_PROVIDER_load(None, b"fips")
if provider is None or provider == 0:
result["error"] = "FIPS provider could not be loaded"
return result
result["provider_loaded"] = True
if EVP_default_properties_enable_fips(None, 1) != 1:
if OSSL_PROVIDER_unload:
OSSL_PROVIDER_unload.argtypes = [ctypes.c_void_p]
OSSL_PROVIDER_unload.restype = ctypes.c_int
OSSL_PROVIDER_unload(provider)
result["error"] = "FIPS mode could not be enabled"
return result
if EVP_default_properties_is_fips_enabled:
EVP_default_properties_is_fips_enabled.argtypes = [ctypes.c_void_p]
EVP_default_properties_is_fips_enabled.restype = ctypes.c_int
result["fips_active"] = (
EVP_default_properties_is_fips_enabled(None) == 1
)
else:
result["fips_active"] = True
# Certificate info: FIPS 140-2/3 validation; OpenSSL does not expose
# this easily via a single API; document that it comes from the build
result["certificate_info"] = (
"FIPS provider loaded; validation status depends on OpenSSL build. "
"See OpenSSL FIPS documentation and your distribution."
)
return result
except Exception as e: # pylint: disable=broad-except
result["error"] = str(e)
return result
def _load_libcrypto() -> Optional[Any]:
for name in ("libcrypto.so.3", "libcrypto.so.1.1", "libcrypto.so"):
try:
return ctypes.CDLL(name)
except OSError:
continue
return None
def _get_openssl_version(libcrypto: Any) -> Optional[str]:
OpenSSL_version = getattr(libcrypto, "OpenSSL_version", None) or getattr(
libcrypto, "SSLeay_version", None
)
if OpenSSL_version is None:
return None
OpenSSL_version.argtypes = [ctypes.c_int]
OpenSSL_version.restype = ctypes.c_char_p
# OPENSSL_VERSION (0)
try:
return OpenSSL_version(0).decode("utf-8", errors="replace")
except Exception: # pylint: disable=broad-except
return None