bpo-9216: Expose OpenSSL FIPS_mode() as _hashlib.get_fips_mode() (GH-19703)
test.pythoninfo logs OpenSSL FIPS_mode() and Linux /proc/sys/crypto/fips_enabled in a new "fips" section. Co-Authored-By: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
parent
e5963ee320
commit
e3dfb9b967
|
@ -720,6 +720,25 @@ def collect_windows(info_add):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def collect_fips(info_add):
|
||||||
|
try:
|
||||||
|
import _hashlib
|
||||||
|
except ImportError:
|
||||||
|
_hashlib = None
|
||||||
|
|
||||||
|
if _hashlib is not None:
|
||||||
|
call_func(info_add, 'fips.openssl_fips_mode', _hashlib, 'get_fips_mode')
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open("/proc/sys/crypto/fips_enabled", encoding="utf-8") as fp:
|
||||||
|
line = fp.readline().rstrip()
|
||||||
|
|
||||||
|
if line:
|
||||||
|
info_add('fips.linux_crypto_fips_enabled', line)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def collect_info(info):
|
def collect_info(info):
|
||||||
error = False
|
error = False
|
||||||
info_add = info.add
|
info_add = info.add
|
||||||
|
@ -735,6 +754,7 @@ def collect_info(info):
|
||||||
collect_datetime,
|
collect_datetime,
|
||||||
collect_decimal,
|
collect_decimal,
|
||||||
collect_expat,
|
collect_expat,
|
||||||
|
collect_fips,
|
||||||
collect_gdb,
|
collect_gdb,
|
||||||
collect_gdbm,
|
collect_gdbm,
|
||||||
collect_get_config,
|
collect_get_config,
|
||||||
|
|
|
@ -856,6 +856,11 @@ class HashLibTestCase(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(expected_hash, hasher.hexdigest())
|
self.assertEqual(expected_hash, hasher.hexdigest())
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(c_hashlib, 'get_fips_mode'),
|
||||||
|
'need _hashlib.get_fips_mode')
|
||||||
|
def test_get_fips_mode(self):
|
||||||
|
self.assertIsInstance(c_hashlib.get_fips_mode(), int)
|
||||||
|
|
||||||
|
|
||||||
class KDFTests(unittest.TestCase):
|
class KDFTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include "openssl/err.h"
|
#include "openssl/err.h"
|
||||||
|
|
||||||
|
#include <openssl/crypto.h> // FIPS_mode()
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||||
/* OpenSSL < 1.1.0 */
|
/* OpenSSL < 1.1.0 */
|
||||||
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||||
|
@ -1096,12 +1098,53 @@ generate_hash_name_list(void)
|
||||||
return state.set;
|
return state.set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* LibreSSL doesn't support FIPS:
|
||||||
|
https://marc.info/?l=openbsd-misc&m=139819485423701&w=2
|
||||||
|
|
||||||
|
Ted Unangst wrote: "I figured I should mention our current libressl policy
|
||||||
|
wrt FIPS mode. It's gone and it's not coming back." */
|
||||||
|
#ifndef LIBRESSL_VERSION_NUMBER
|
||||||
|
/*[clinic input]
|
||||||
|
_hashlib.get_fips_mode -> int
|
||||||
|
|
||||||
|
Determine the OpenSSL FIPS mode of operation.
|
||||||
|
|
||||||
|
Effectively any non-zero return value indicates FIPS mode;
|
||||||
|
values other than 1 may have additional significance.
|
||||||
|
|
||||||
|
See OpenSSL documentation for the FIPS_mode() function for details.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
_hashlib_get_fips_mode_impl(PyObject *module)
|
||||||
|
/*[clinic end generated code: output=87eece1bab4d3fa9 input=c2799c3132a36d6c]*/
|
||||||
|
|
||||||
|
{
|
||||||
|
ERR_clear_error();
|
||||||
|
int result = FIPS_mode();
|
||||||
|
if (result == 0) {
|
||||||
|
// "If the library was built without support of the FIPS Object Module,
|
||||||
|
// then the function will return 0 with an error code of
|
||||||
|
// CRYPTO_R_FIPS_MODE_NOT_SUPPORTED (0x0f06d065)."
|
||||||
|
// But 0 is also a valid result value.
|
||||||
|
unsigned long errcode = ERR_peek_last_error();
|
||||||
|
if (errcode) {
|
||||||
|
_setException(PyExc_ValueError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // !LIBRESSL_VERSION_NUMBER
|
||||||
|
|
||||||
|
|
||||||
/* List of functions exported by this module */
|
/* List of functions exported by this module */
|
||||||
|
|
||||||
static struct PyMethodDef EVP_functions[] = {
|
static struct PyMethodDef EVP_functions[] = {
|
||||||
EVP_NEW_METHODDEF
|
EVP_NEW_METHODDEF
|
||||||
PBKDF2_HMAC_METHODDEF
|
PBKDF2_HMAC_METHODDEF
|
||||||
_HASHLIB_SCRYPT_METHODDEF
|
_HASHLIB_SCRYPT_METHODDEF
|
||||||
|
_HASHLIB_GET_FIPS_MODE_METHODDEF
|
||||||
_HASHLIB_HMAC_DIGEST_METHODDEF
|
_HASHLIB_HMAC_DIGEST_METHODDEF
|
||||||
_HASHLIB_OPENSSL_MD5_METHODDEF
|
_HASHLIB_OPENSSL_MD5_METHODDEF
|
||||||
_HASHLIB_OPENSSL_SHA1_METHODDEF
|
_HASHLIB_OPENSSL_SHA1_METHODDEF
|
||||||
|
|
|
@ -725,7 +725,48 @@ exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(LIBRESSL_VERSION_NUMBER)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(_hashlib_get_fips_mode__doc__,
|
||||||
|
"get_fips_mode($module, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Determine the OpenSSL FIPS mode of operation.\n"
|
||||||
|
"\n"
|
||||||
|
"Effectively any non-zero return value indicates FIPS mode;\n"
|
||||||
|
"values other than 1 may have additional significance.\n"
|
||||||
|
"\n"
|
||||||
|
"See OpenSSL documentation for the FIPS_mode() function for details.");
|
||||||
|
|
||||||
|
#define _HASHLIB_GET_FIPS_MODE_METHODDEF \
|
||||||
|
{"get_fips_mode", (PyCFunction)_hashlib_get_fips_mode, METH_NOARGS, _hashlib_get_fips_mode__doc__},
|
||||||
|
|
||||||
|
static int
|
||||||
|
_hashlib_get_fips_mode_impl(PyObject *module);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_hashlib_get_fips_mode(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
int _return_value;
|
||||||
|
|
||||||
|
_return_value = _hashlib_get_fips_mode_impl(module);
|
||||||
|
if ((_return_value == -1) && PyErr_Occurred()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = PyLong_FromLong((long)_return_value);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
|
||||||
|
|
||||||
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
#ifndef _HASHLIB_SCRYPT_METHODDEF
|
||||||
#define _HASHLIB_SCRYPT_METHODDEF
|
#define _HASHLIB_SCRYPT_METHODDEF
|
||||||
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
|
#endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */
|
||||||
/*[clinic end generated code: output=acb22ccddb7043c7 input=a9049054013a1b77]*/
|
|
||||||
|
#ifndef _HASHLIB_GET_FIPS_MODE_METHODDEF
|
||||||
|
#define _HASHLIB_GET_FIPS_MODE_METHODDEF
|
||||||
|
#endif /* !defined(_HASHLIB_GET_FIPS_MODE_METHODDEF) */
|
||||||
|
/*[clinic end generated code: output=b0703dd5a043394d input=a9049054013a1b77]*/
|
||||||
|
|
Loading…
Reference in New Issue