Skip to content

Instantly share code, notes, and snippets.

@davidrapin
Last active March 28, 2024 15:22
Show Gist options
  • Save davidrapin/d71e0fbb3c4739c2b9d753d521f37fc3 to your computer and use it in GitHub Desktop.
Save davidrapin/d71e0fbb3c4739c2b9d753d521f37fc3 to your computer and use it in GitHub Desktop.
Install FIPS for Node.js
#!/bin/bash
set -e
# resources:
# https://github.com/openssl/openssl/blob/master/README-FIPS.md#installing-the-fips-provider-and-using-it-with-the-latest-release
# https://nodejs.org/docs/latest/api/all.html#all_crypto_fips-mode
# https://nodejs.org/api/cli.html#--enable-fips
# parse command line options
if [ -z "$1" ]; then
BUILD_OPENSSL=1
elif [ "$1" == "--skip-make" ]; then
BUILD_OPENSSL=0
else
echo "Unknown parameter: $1 (use '--skip-make' to skip downloading and building OpenSSL)"
exit 1
fi
NODEJS_PATH=$(which node)
echo "* Note: this only works for Node.js v16 and later (found version is $($NODEJS_PATH -v))"
OPENSSL_VERSION=$($NODEJS_PATH -e 'console.log(process.versions.openssl.split("+")[0])')
echo "* Installing FIPS for OpenSSL $OPENSSL_VERSION"
if [ "$BUILD_OPENSSL" == "1" ]; then
echo "* Downloading OpenSSL..."
curl -q -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz
echo "* Decompressing OpenSSL archive..."
tar -xf openssl-${OPENSSL_VERSION}.tar.gz
cd openssl-${OPENSSL_VERSION}
echo "* Configuring FIPS build"
./Configure enable-fips
echo "* Building FIPS modules"
make
else
echo "* Downloading and building OpenSSL skipped (assuming already downloaded annd build)"
cd openssl-${OPENSSL_VERSION}
fi
echo "* Copying FIPS provider artifacts (fips.so & fipsmodule.cnf) to known locations"
FILES=$(sudo make install_fips)
# did not work?
# echo "Checking that FIPS is enabled"
# ./util/wrap.pl -fips apps/openssl list -provider-path providers -provider fips -providers
# extract .cnf file path
CNF_FILE=$(echo "$FILES" | grep '.cnf' | sed 's/.*-> \(.*\)/\1/')
# extract .dylib folder/file path
DYLIB_FOLDER=$(echo "$FILES" | grep '/fips\.' | sed 's/.*-> \(.*\)\/fips\..*/\1/')
DYLIB_FILE=$(echo "$FILES" | grep '/fips\.' | sed 's/.*-> \(.*\)/\1/')
echo "* Copied FIPS configuration to: $CNF_FILE"
echo "* Copied FIPS shared binary to: $DYLIB_FILE"
cd ..
NODEJS_CNF="$(pwd)/nodejs.cnf"
cat <<EOT >$NODEJS_CNF
nodejs_conf = nodejs_init
.include $CNF_FILE
[nodejs_init]
providers = provider_sect
[provider_sect]
default = default_sect
# The fips section name should match the section name inside the
# included fipsmodule.cnf.
fips = fips_sect
[default_sect]
activate = 1
EOT
echo "* Generated Node.js OpenSSL FIPS configuration file in: $NODEJS_CNF"
# store the env vars (if we run this script with a "." prefix it will export these)
export OPENSSL_CONF="$NODEJS_CNF"
export OPENSSL_MODULES="$DYLIB_FOLDER"
NODEJS_FIPS_OK=$($NODEJS_PATH --enable-fips -e 'console.log(crypto.getFips())')
if [ "$NODEJS_FIPS_OK" == "1" ]; then
# https://nodejs.org/api/tls.html#tlsgetciphers
echo "* Node.js default Ciphers: $($NODEJS_PATH -e 'console.log(crypto.getCiphers().length)')"
echo "* Node.js FIPS Ciphers : $($NODEJS_PATH --enable-fips -e 'console.log(crypto.getCiphers().length)')"
else
echo "* Node.js FIPS does not work"
fi
echo "* Please set the following env vars for Node.js and use the '--enable_fips' command-line flag:"
echo " \"OPENSSL_CONF\": \"$OPENSSL_CONF\""
echo " \"OPENSSL_MODULES\": \"$OPENSSL_MODULES\""
echo "e.g. try running:"
echo "OPENSSL_CONF=\"$OPENSSL_CONF\" OPENSSL_MODULES=\"$OPENSSL_MODULES\" node --enable-fips -e 'console.log(crypto.getFips())'"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment