mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 21:19:50 +01:00
build,src,test,doc: enable FIPS for OpenSSL 3.0
This commit enables FIPS when Node.js is dynamically linking against quictls/openssl-3.0. BUILDING.md has been updated with instructions to configure and build quictls/openssl 3.0.0-alpha-15 and includes a couple of work-arounds which I believe are fixed in alpha-16 and can be removed when alpha-16 is available. The information might be a little too detailed/verbose but I thought it would be helpful to at least initially include all the steps. PR-URL: https://github.com/nodejs/node/pull/38633 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
This commit is contained in:
parent
35b445d089
commit
0d7644fdda
130
BUILDING.md
130
BUILDING.md
@ -759,7 +759,135 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)
|
||||
|
||||
## Building Node.js with FIPS-compliant OpenSSL
|
||||
|
||||
The current version of Node.js does not support FIPS.
|
||||
The current version of Node.js does not support FIPS when statically linking
|
||||
(the default) with OpenSSL 1.1.1 but for dynamically linking it is possible
|
||||
to enable FIPS using the configuration flag `--openssl-is-fips`.
|
||||
|
||||
### Configuring and building quictls/openssl for FIPS
|
||||
|
||||
For quictls/openssl 3.0 it is possible to enable FIPS when dynamically linking.
|
||||
Node.js currently uses openssl-3.0.0+quic which can be configured as
|
||||
follows:
|
||||
```console
|
||||
$ git clone git@github.com:quictls/openssl.git
|
||||
$ cd openssl
|
||||
$ ./config --prefix=/path/to/install/dir/ shared enable-fips linux-x86_64
|
||||
```
|
||||
This can be compiled and installed using the following commands:
|
||||
```console
|
||||
$ make -j8
|
||||
$ make install_ssldirs
|
||||
$ make install_fips
|
||||
```
|
||||
|
||||
After the FIPS module and configuration file have been installed by the above
|
||||
instructions we also need to update `/path/to/install/dir/ssl/openssl.cnf` to
|
||||
use the generated FIPS configuration file (`fipsmodule.cnf`):
|
||||
```text
|
||||
.include fipsmodule.cnf
|
||||
|
||||
# List of providers to load
|
||||
[provider_sect]
|
||||
default = default_sect
|
||||
# The fips section name should match the section name inside the
|
||||
# included /path/to/install/dir/ssl/fipsmodule.cnf.
|
||||
fips = fips_sect
|
||||
|
||||
[default_sect]
|
||||
activate = 1
|
||||
```
|
||||
|
||||
In the above case OpenSSL is not installed in the default location so two
|
||||
environment variables need to be set, `OPENSSL_CONF`, and `OPENSSL_MODULES`
|
||||
which should point to the OpenSSL configuration file and the directory where
|
||||
OpenSSL modules are located:
|
||||
```console
|
||||
$ export OPENSSL_CONF=/path/to/install/dir/ssl/openssl.cnf
|
||||
$ export OPENSSL_MODULES=/path/to/install/dir/lib/ossl-modules
|
||||
```
|
||||
|
||||
Node.js can then be configured to enable FIPS:
|
||||
```console
|
||||
$ ./configure --shared-openssl --shared-openssl-libpath=/path/to/install/dir/lib --shared-openssl-includes=/path/to/install/dir/include --shared-openssl-libname=crypto,ssl --openssl-is-fips
|
||||
$ export LD_LIBRARY_PATH=/path/to/install/dir/lib
|
||||
$ make -j8
|
||||
```
|
||||
|
||||
Verify the produced executable:
|
||||
```console
|
||||
$ ldd ./node
|
||||
linux-vdso.so.1 (0x00007ffd7917b000)
|
||||
libcrypto.so.81.3 => /path/to/install/dir/lib/libcrypto.so.81.3 (0x00007fd911321000)
|
||||
libssl.so.81.3 => /path/to/install/dir/lib/libssl.so.81.3 (0x00007fd91125e000)
|
||||
libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007fd911232000)
|
||||
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd911039000)
|
||||
libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd910ef3000)
|
||||
libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd910ed9000)
|
||||
libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007fd910eb5000)
|
||||
libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd910cec000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007fd9117f2000)
|
||||
```
|
||||
If the `ldd` command says that `libcrypto` cannot be found one needs to set
|
||||
`LD_LIBRARY_PATH` to point to the directory used above for
|
||||
`--shared-openssl-libpath` (see previous step).
|
||||
|
||||
Verify the OpenSSL version:
|
||||
```console
|
||||
$ ./node -p process.versions.openssl
|
||||
3.0.0-alpha16+quic
|
||||
```
|
||||
|
||||
Verify that FIPS is available:
|
||||
```console
|
||||
$ ./node -p 'process.config.variables.openssl_is_fips'
|
||||
true
|
||||
$ ./node --enable-fips -p 'crypto.getFips()'
|
||||
1
|
||||
```
|
||||
|
||||
FIPS support can then be enable via the OpenSSL configuration file or
|
||||
using `--enable-fips` or `--force-fips` command line options to the Node.js
|
||||
executable. See sections
|
||||
[Enabling FIPS using Node.js options](#enabling-fips-using-node.js-options) and
|
||||
[Enabling FIPS using OpenSSL config](#enabling-fips-using-openssl-config) below.
|
||||
|
||||
### Enabling FIPS using Node.js options
|
||||
This is done using one of the Node.js options `--enable-fips` or
|
||||
`--force-fips`, for example:
|
||||
```console
|
||||
$ node --enable-fips -p 'crypto.getFips()'
|
||||
```
|
||||
|
||||
### Enabling FIPS using OpenSSL config
|
||||
This example show that using OpenSSL's configuration file, FIPS can be enabled
|
||||
without specifying the `--enable-fips` or `--force-fips` options by setting
|
||||
`default_properties = fips=yes` in the FIPS configuration file. See
|
||||
[link](https://github.com/openssl/openssl/blob/master/README-FIPS.md#loading-the-fips-module-at-the-same-time-as-other-providers)
|
||||
for details.
|
||||
|
||||
For this to work the OpenSSL configuration file (default openssl.cnf) needs to
|
||||
be updated. The following shows an example:
|
||||
```console
|
||||
openssl_conf = openssl_init
|
||||
|
||||
.include /path/to/install/dir/ssl/fipsmodule.cnf
|
||||
|
||||
[openssl_init]
|
||||
providers = prov
|
||||
alg_section = algorithm_sect
|
||||
|
||||
[prov]
|
||||
fips = fips_sect
|
||||
default = default_sect
|
||||
|
||||
[default_sect]
|
||||
activate = 1
|
||||
|
||||
[algorithm_sect]
|
||||
default_properties = fips=yes
|
||||
```
|
||||
After this change Node.js can be run without the `--enable-fips` or `--force-fips`
|
||||
options.
|
||||
|
||||
## Building Node.js with external core modules
|
||||
|
||||
|
@ -99,7 +99,7 @@
|
||||
'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a',
|
||||
}],
|
||||
['openssl_fips != ""', {
|
||||
'openssl_product': '<(STATIC_LIB_PREFIX)crypto<(STATIC_LIB_SUFFIX)',
|
||||
'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
|
||||
}, {
|
||||
'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
|
||||
}],
|
||||
|
@ -1456,6 +1456,12 @@ def configure_openssl(o):
|
||||
if options.openssl_fips or options.openssl_fips == '':
|
||||
error('FIPS is not supported in this version of Node.js')
|
||||
|
||||
if options.openssl_is_fips and not options.shared_openssl:
|
||||
error('--openssl-is-fips is only available with --shared-openssl')
|
||||
|
||||
if options.openssl_is_fips:
|
||||
o['defines'] += ['OPENSSL_FIPS']
|
||||
|
||||
if options.shared_openssl:
|
||||
variables['openssl_quic'] = b(getsharedopensslhasquic.get_has_quic(options.__dict__['shared_openssl_includes']))
|
||||
|
||||
|
@ -14,6 +14,12 @@
|
||||
|
||||
#include "math.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
#include "openssl/provider.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace node {
|
||||
|
||||
using v8::ArrayBuffer;
|
||||
@ -197,7 +203,16 @@ void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
#ifdef OPENSSL_FIPS
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
OSSL_PROVIDER* fips_provider = nullptr;
|
||||
if (OSSL_PROVIDER_available(nullptr, "fips")) {
|
||||
fips_provider = OSSL_PROVIDER_load(nullptr, "fips");
|
||||
}
|
||||
const auto enabled = fips_provider == nullptr ? 0 :
|
||||
OSSL_PROVIDER_self_test(fips_provider) ? 1 : 0;
|
||||
#else
|
||||
const auto enabled = FIPS_selftest() ? 1 : 0;
|
||||
#endif
|
||||
#else // OPENSSL_FIPS
|
||||
const auto enabled = 0;
|
||||
#endif // OPENSSL_FIPS
|
||||
|
@ -24,7 +24,7 @@
|
||||
#endif // !OPENSSL_NO_ENGINE
|
||||
// The FIPS-related functions are only available
|
||||
// when the OpenSSL itself was compiled with FIPS support.
|
||||
#ifdef OPENSSL_FIPS
|
||||
#if defined(OPENSSL_FIPS) && OPENSSL_VERSION_MAJOR < 3
|
||||
# include <openssl/fips.h>
|
||||
#endif // OPENSSL_FIPS
|
||||
|
||||
|
@ -66,6 +66,10 @@ testHelper(
|
||||
'require("crypto").getFips()',
|
||||
{ ...process.env, 'OPENSSL_CONF': '' });
|
||||
|
||||
// This should succeed for both FIPS and non-FIPS builds in combination with
|
||||
// OpenSSL 1.1.1 or OpenSSL 3.0
|
||||
const test_result = testFipsCrypto();
|
||||
assert.ok(test_result === 1 || test_result === 0);
|
||||
|
||||
// If Node was configured using --shared-openssl fips support might be
|
||||
// available depending on how OpenSSL was built. If fips support is
|
||||
@ -79,7 +83,7 @@ testHelper(
|
||||
// ("Error: Cannot set FIPS mode in a non-FIPS build.").
|
||||
// Due to this uncertainty the following tests are skipped when configured
|
||||
// with --shared-openssl.
|
||||
if (!sharedOpenSSL()) {
|
||||
if (!sharedOpenSSL() && !common.hasOpenSSL3) {
|
||||
// OpenSSL config file should be able to turn on FIPS mode
|
||||
testHelper(
|
||||
'stdout',
|
||||
|
Loading…
Reference in New Issue
Block a user