Repository navigation
FIPS 140-2 compliancy using existing certified libraries #37072
Description
Activity
It is possible to dynamically link against OpenSSL as long as it is a compatible OpenSSL version. We currently use OpenSSL 1.1.1 only, which does not have FIPS certification. The next OpenSSL build with FIPS certification will likely be 3.x, so it is going to be a while longer. I don't think it's realistic to link current Node.js versions against OpenSSL older than 1.1.1.
@tniessen thanks for the feedback, especially your comments that OpenSSL 1.1.1 can be used - and that's exactly the version that I'm looking for. My question is: how do you build with that FIPS support, considering the documentation states that it's not an option?
@tniessen thanks for the feedback, especially your comments that OpenSSL 1.1.1 can be used - and that's exactly the version that I'm looking for. My question is: how do you build with that FIPS support, considering the documentation states that it's not an option?
nodejs/build#2176 has the steps to build for UBI 8.1.
There's also #36341 which aims to rework some of this.
- addedopensslIssues and PRs related to the OpenSSL dependency.Issues and PRs related to the OpenSSL dependency.
on Jan 27, 2021 Finally managed to carve out some time to test this. I'm moving forward cautiously as I don't want to mess anything up, but I guess I managed to fall at the first hurdle, attempting this on Ubuntu 18.04LTS:
$ lsb_release -d && uname -r && cat /proc/sys/crypto/fips_enabled && openssl version Description: Ubuntu 18.04.5 LTS 4.15.0-1052-fips 1 OpenSSL 1.1.1 11 Sep 2018 $ sudo apt install -y build-essential libssl-dev curl git-core clang $ git clone https://github.com/nodejs/node.git $ cd node $ export OPENSSL_ENABLE_MD5_VERIFY=true $ ./configure --shared-openssl --shared-openssl-includes=/usr/include/openssl --openssl-is-fips Traceback (most recent call last): File "./configure", line 21, in <module> from distutils.spawn import find_executable ModuleNotFoundError: No module named 'distutils.spawn'Am I trying this too early? From nodejs/build#2176 it discusses the use of a UBI, but that's appears to be using RedHat which I don't have access to.
Can anyone provide some insight for me please?
See #30189 for the
ModuleNotFoundError: No module named 'distutils.spawn'error.UBI is a container (for use in e.g. docker, podman) and doesn't require a RHEL subscription to use.
Reacted by Dave Monk@richardlau thank you for the pointer (and so quickly) ... I'm
makeing at the moment...So I've tried this with three branches of node (latest, v14.x and v12.x) and I'm failing on what appears to be the #35213 issue. @mscdex states that the version of OpenSSL to be used has to be the same, or newer, than the version bundled with node, stating that v14.x uses v1.1.1. I do have that version (
1.1.1-1ubuntu2.fips.2.1~18.04.7.1) and yet I'm still getting caught. At the very least, v12.x should work shouldn't it?Latest / v14.x snippet
g++ -o /home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto_clienthello.o ../src/node_crypto_clienthello.cc '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D__STDC_FORMAT_MACROS' '-DNODE_ARCH="x64"' '-DNODE_PLATFORM="linux"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_OPENSSL_SYSTEM_CERT_PATH=""' '-DHAVE_INSPECTOR=1' '-DNODE_ENABLE_LARGE_CODE_PAGES=1' '-D__POSIX__' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DHAVE_OPENSSL=1' '-DNODE_FIPS_MODE' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_POSIX_C_SOURCE=200112' '-DNGHTTP2_STATICLIB' -I/usr/include/openssl -I../src -I/home/vroot/buildNode/node/out/Release/obj/gen -I/home/vroot/buildNode/node/out/Release/obj/gen/include -I/home/vroot/buildNode/node/out/Release/obj/gen/src -I../deps/histogram/src -I../deps/uvwasi/include -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/zlib -I../deps/llhttp/include -I../deps/cares/include -I../deps/uv/include -I../deps/nghttp2/lib/includes -I../deps/brotli/c/include -Wall -Wextra -Wno-unused-parameter -pthread -Wall -Wextra -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/buildNode/node/out/Release/.deps//home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto_clienthello.o.d.raw -c In file included from /usr/include/openssl/x509.h:25:0, from /usr/include/openssl/ssl.h:20, from ../src/node_crypto.h:39, from ../src/node_crypto.cc:22: ../src/node_crypto.cc: In member function ‘virtual bool node::crypto::RSAPSSKeyPairGenerationConfig::Configure(const EVPKeyCtxPointer&)’: ../src/node_crypto.cc:6102:11: error: ‘EVP_PKEY_OP_TYPE_KEYGEN’ was not declared in this scope if (EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), md_) <= 0) ^ ../src/node_crypto.cc:6102:11: note: suggested alternative: ‘EVP_PKEY_OP_TYPE_NOGEN’ ../src/node_crypto.cc: In function ‘void node::crypto::InitCryptoOnce()’: ../src/node_crypto.cc:6858:5: error: ‘OPENSSL_INIT_set_config_filename’ was not declared in this scope OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/node_crypto.cc:6858:5: note: suggested alternative: ‘OPENSSL_INIT_set_config_appname’ OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OPENSSL_INIT_set_config_appname g++ -o /home/vroot/buildNode/node/out/Release/obj.target/libnode/src/tls_wrap.o ../src/tls_wrap.cc '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D__STDC_FORMAT_MACROS' '-DNODE_ARCH="x64"' '-DNODE_PLATFORM="linux"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_OPENSSL_SYSTEM_CERT_PATH=""' '-DHAVE_INSPECTOR=1' '-DNODE_ENABLE_LARGE_CODE_PAGES=1' '-D__POSIX__' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DHAVE_OPENSSL=1' '-DNODE_FIPS_MODE' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_POSIX_C_SOURCE=200112' '-DNGHTTP2_STATICLIB' -I/usr/include/openssl -I../src -I/home/vroot/buildNode/node/out/Release/obj/gen -I/home/vroot/buildNode/node/out/Release/obj/gen/include -I/home/vroot/buildNode/node/out/Release/obj/gen/src -I../deps/histogram/src -I../deps/uvwasi/include -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/zlib -I../deps/llhttp/include -I../deps/cares/include -I../deps/uv/include -I../deps/nghttp2/lib/includes -I../deps/brotli/c/include -Wall -Wextra -Wno-unused-parameter -pthread -Wall -Wextra -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/buildNode/node/out/Release/.deps//home/vroot/buildNode/node/out/Release/obj.target/libnode/src/tls_wrap.o.d.raw -c libnode.target.mk:343: recipe for target '/home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto.o' failed make[2]: *** [/home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto.o] Error 1 make[2]: *** Waiting for unfinished jobs.... rm e014ff45c4b1291c4b8161570c459e918f066695.intermediate 90cf649cf91580905fe985c1558b332a3148873a.intermediate Makefile:104: recipe for target 'node' failed make[1]: *** [node] Error 2 Makefile:1127: recipe for target 'node-v14.15.6-linux-x64.tar' failed make: *** [node-v14.15.6-linux-x64.tar] Error 2The v12.x build has an additional warning at the end...
g++ -o /home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto_clienthello.o ../src/node_crypto_clienthello.cc '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D__STDC_FORMAT_MACROS' '-DNODE_ARCH="x64"' '-DNODE_PLATFORM="linux"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_OPENSSL_SYSTEM_CERT_PATH=""' '-DHAVE_INSPECTOR=1' '-DNODE_ENABLE_LARGE_CODE_PAGES=1' '-D__POSIX__' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DNODE_HAVE_SMALL_ICU=1' '-DHAVE_OPENSSL=1' '-DNODE_FIPS_MODE' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' '-DHTTP_PARSER_STRICT=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_POSIX_C_SOURCE=200112' '-DNGHTTP2_STATICLIB' -I/usr/include/openssl -I../src -I/home/vroot/buildNode/node/out/Release/obj/gen -I/home/vroot/buildNode/node/out/Release/obj/gen/include -I/home/vroot/buildNode/node/out/Release/obj/gen/src -I../deps/histogram/src -I../deps/uvwasi/include -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/zlib -I../deps/http_parser -I../deps/llhttp/include -I../deps/cares/include -I../deps/uv/include -I../deps/nghttp2/lib/includes -I../deps/brotli/c/include -Wall -Wextra -Wno-unused-parameter -pthread -Wall -Wextra -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/buildNode/node/out/Release/.deps//home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto_clienthello.o.d.raw -c In file included from /usr/include/openssl/x509.h:25:0, from /usr/include/openssl/ssl.h:20, from ../src/node_crypto.h:38, from ../src/node_crypto.cc:22: ../src/node_crypto.cc: In member function ‘virtual bool node::crypto::RSAPSSKeyPairGenerationConfig::Configure(const EVPKeyCtxPointer&)’: ../src/node_crypto.cc:6128:11: error: ‘EVP_PKEY_OP_TYPE_KEYGEN’ was not declared in this scope if (EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx.get(), md_) <= 0) ^ ../src/node_crypto.cc:6128:11: note: suggested alternative: ‘EVP_PKEY_OP_TYPE_NOGEN’ ../src/node_crypto.cc: In function ‘void node::crypto::InitCryptoOnce()’: ../src/node_crypto.cc:6884:5: error: ‘OPENSSL_INIT_set_config_filename’ was not declared in this scope OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/node_crypto.cc:6884:5: note: suggested alternative: ‘OPENSSL_INIT_set_config_appname’ OPENSSL_INIT_set_config_filename(settings, conf); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OPENSSL_INIT_set_config_appname g++ -o /home/vroot/buildNode/node/out/Release/obj.target/libnode/src/tls_wrap.o ../src/tls_wrap.cc '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D__STDC_FORMAT_MACROS' '-DNODE_ARCH="x64"' '-DNODE_PLATFORM="linux"' '-DNODE_WANT_INTERNALS=1' '-DV8_DEPRECATION_WARNINGS=1' '-DNODE_OPENSSL_SYSTEM_CERT_PATH=""' '-DHAVE_INSPECTOR=1' '-DNODE_ENABLE_LARGE_CODE_PAGES=1' '-D__POSIX__' '-DNODE_USE_V8_PLATFORM=1' '-DNODE_HAVE_I18N_SUPPORT=1' '-DNODE_HAVE_SMALL_ICU=1' '-DHAVE_OPENSSL=1' '-DNODE_FIPS_MODE' '-DUCONFIG_NO_SERVICE=1' '-DU_ENABLE_DYLOAD=0' '-DU_STATIC_IMPLEMENTATION=1' '-DU_HAVE_STD_STRING=1' '-DUCONFIG_NO_BREAK_ITERATION=0' '-DHTTP_PARSER_STRICT=0' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_POSIX_C_SOURCE=200112' '-DNGHTTP2_STATICLIB' -I/usr/include/openssl -I../src -I/home/vroot/buildNode/node/out/Release/obj/gen -I/home/vroot/buildNode/node/out/Release/obj/gen/include -I/home/vroot/buildNode/node/out/Release/obj/gen/src -I../deps/histogram/src -I../deps/uvwasi/include -I../deps/v8/include -I../deps/icu-small/source/i18n -I../deps/icu-small/source/common -I../deps/zlib -I../deps/http_parser -I../deps/llhttp/include -I../deps/cares/include -I../deps/uv/include -I../deps/nghttp2/lib/includes -I../deps/brotli/c/include -Wall -Wextra -Wno-unused-parameter -pthread -Wall -Wextra -Wno-unused-parameter -m64 -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -MMD -MF /home/vroot/buildNode/node/out/Release/.deps//home/vroot/buildNode/node/out/Release/obj.target/libnode/src/tls_wrap.o.d.raw -c libnode.target.mk:348: recipe for target '/home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto.o' failed make[2]: *** [/home/vroot/buildNode/node/out/Release/obj.target/libnode/src/node_crypto.o] Error 1 make[2]: *** Waiting for unfinished jobs.... ../src/tls_wrap.cc: In static member function ‘static unsigned int node::TLSWrap::PskClientCallback(SSL*, const char*, char*, unsigned int, unsigned char*, unsigned int)’: ../src/tls_wrap.cc:1192:70: warning: ‘static v8::Local<v8::String> v8::String::NewFromUtf8(v8::Isolate*, const char*, v8::String::NewStringType, int)’ is deprecated: Use maybe version [-Wdeprecated-declarations] MaybeLocal<String> maybe_hint = String::NewFromUtf8(isolate, hint); ^ In file included from ../deps/v8/include/v8-internal.h:14:0, from ../deps/v8/include/v8.h:27, from ../src/util.h:31, from ../src/util-inl.h:29, from ../src/aliased_buffer.h:7, from ../src/env.h:27, from ../src/node_crypto.h:30, from ../src/tls_wrap.h:27, from ../src/tls_wrap.cc:22: ../deps/v8/include/v8.h:3032:21: note: declared here Local<String> NewFromUtf8(Isolate* isolate, const char* data, ^ ../deps/v8/include/v8config.h:328:3: note: in definition of macro ‘V8_DEPRECATED’ declarator __attribute__((deprecated(message))) ^~~~~~~~~~ rm ea69077d368c9695b17786cc0274f9a324f9afc1.intermediate e014ff45c4b1291c4b8161570c459e918f066695.intermediate e214d22584df5b3dfc4c1b7b232e8eb7d00c500a.intermediate 90cf649cf91580905fe985c1558b332a3148873a.intermediate Makefile:104: recipe for target 'node' failed make[1]: *** [node] Error 2 Makefile:1132: recipe for target 'node-v12.20.3-linux-x64.tar' failed make: *** [node-v12.20.3-linux-x64.tar] Error 2I have this all scripted and working using the shared (certified) library in Ubuntu 16.04 / OpenSSL 1.0.2g but I also had to amend
node_version.h's NODE_VERSION_IS_RELEASE from0to1which I've tested with latest, v14.x and v12.x but it still doesn't get me any further.My existing script
sudo apt install -y build-essential libssl-dev curl git-core clang python3-distutils snap version && make -v && gcc -v && g++ -v && clang -v && python -c 'import sys; print(sys.version_info[:])' && python3 -c 'import sys; print(sys.version_info[:])' #2.48.3+18.04, 4.1, 7.5.0, 7.5.0, 6.0.0, (2, 7, 17, 'final', 0), (3, 6, 9, 'final', 0) git clone https://github.com/nodejs/node.git #git clone -b v12.x https://github.com/nodejs/node.git # this pulls branch: v12.x cd node export OPENSSL_ENABLE_MD5_VERIFY=true ./configure --shared-openssl --shared-openssl-includes=/usr/include/openssl --openssl-is-fips sed -i 's/#define NODE_VERSION_IS_RELEASE 0/#define NODE_VERSION_IS_RELEASE 1/' ./src/node_version.h git config user.email myEmail@address.com git commit -m "Amended node header to release for binary build" ./src/node_version.h CONFIG_FLAGS="--shared-openssl --shared-openssl-includes=/usr/include/openssl --openssl-is-fips" make -j4 binaryI feel as if I'm incredibly close, but just can't get over this last hurdle?
As a follow up to this, I was posed a question this evening and it sparked a separate thought.
If I have a system that has a FIPS compliant OpenSSL module installed upon it and running in FIPS mode, then install NodeJS (which obviously comes with it's own OpenSSL libraries), NodeJS wouldn't be FIPS compliant. However, now that everything is installed on the system, is there any way of altering the running config of NodeJS to use the FIPS module available, rather than those it came with?
I've always assumed that one had to build NodeJS linking to that external library, but you know what they say about "assume" ... :)
I know this is long after your question, but just came across this issue.
You can't alter the community Node.js binaries to use the dynamic link library, as you mention you have to rebuild.
Not sure what system you are running on but if it is RHEL, then the RHEL Node.js rpms that you can install already do exactly what you were suggesting -> link against the shared openssl on the RHEL system whichi is FIPs certified.
And having said that I believe it may be changing with OpenSSL 3 in 18.x. In that case it may be possible to configured FIPs providers with the existing binary. @richardlau may have more specific info.
Can we enable FIPS in NodeJS 18 using crypto.setFips, without building NodeJS?
Can we enable FIPS in NodeJS 18 using crypto.setFips, without building NodeJS?
It will get enabled but throws errors for me. I believe that you still have to build from source, but the cool part is that it is FIPS validated due to OpenSSL 3, just you have to build your own runtime bins :-/
Reacted by Orie SteeleI've opened a pull request to update the Node.js documentation for enabling FIPS support with OpenSSL 3: #48194
The short answer is that you do not need to rebuild Node.js 18 or later from source, you can use the binaries from nodejs.org. You will however need the OpenSSL 3 FIPS provider, which you will have to obtain separately.
Reacted by Elliot Huffmangithub-actions commented
on Jun 27, 2026 on Jun 27, 2026 – with GitHub ActionsContributorMore actionsThis issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jun 27, 2026 github-actions commented
on Jul 28, 2026 on Jul 28, 2026 – with GitHub ActionsContributorMore actionsThis issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.
Is your feature request related to a problem? Please describe.
A number of applications that could be FIPS 140-2 compliant simply can't be because the last version of NodeJS that supports being built with certified OpenSSL libraries was v8.x (using the 1.02g libraries). Although I can't find it, I had read a couple of years ago that there was strong consideration of NodeJS v13 being able to be either certified or compliant, but all of the searching that I've done hasn't come up with any mention of that (or any later version) having that capability.
As stated, I'm already using NodeJS v8 in order to run applications that require NodeJS, and so far that has worked out remarkably well considering the age of v8: even newer changes to the upper stack of applications appear to run just fine on this long in the tooth version. However, of course v8 has a number of CVEs that have been addressed in latter versions: but those latter versions can't be compiled using the OpenSSL 1.02g libraries. Added to this is the fact that 1.02g doesn't support TLS1.2+ and with modern browsers no longer supporting TLS1.0/1.1 from March 2021 ... you can see the predicament.
Describe the solution you'd like
I'm not a programmer first and foremost, but I've assisted other projects in the same sort of vein, and that is: if I'm running an OS that has gone through FIPS 140-2 certification of the OpenSSL libraries, those other projects have altered their build scripts to be able to compile by linking to the existing libraries already on the system, thereby making their project FIPS compliant. To maintain certification, the OpenSSL libraries can't be re-compiled when on a host, but a program's build script that can be adjusted to compile using those libraries, can be classed as compliant. I'm sure you're aware, the distinction between certified and compliant is significant: the former one has to pony up the finances and go through months worth of work, testing and validation; the latter is free and only (?!) requires the work of altering the build script of the project in question.
Describe alternatives you've considered
Are there alternatives to NodeJS? ;) Seriously though, NodeJS has such a solid base and it's reliability is (IMHO) unchallenged, there really isn't another alternative.
For my upper stack of applications I could simply use a newer version of NodeJS, but then they wouldn't be FIPS compliant and that restricts me considerably. I spent months (literally) working through all the versions of NodeJS until I got to the version that could be compiled with the OpenSSL libraries making NodeJS compliant, but AFAIK v8.x was the last version that had this capability. I would love to be told that there's a latter version that can also be used, but I don't believe that to be the case.
FWIW, I'm currently using Ubuntu 16 with the 1.02g OpenSSL libraries but due to the security issues (CVEs etc) I have to look for an alternative. I would love to use Ubuntu 18 and the set of OpenSSL v1.1.1 libraries that Canonical have certified under their Advantage program...
I appreciate the time spent reading through all of this - and keenly look forward to (hopefully good?) news regarding this.
Thank you.