From 282d4c90c8b4256967b96a1c07b008e7d99edc80 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Mon, 1 Jun 2015 23:49:43 +0200 Subject: [PATCH 1/7] crypto: support FIPS mode of OpenSSL Support building and running with FIPS-compliant OpenSSL. The process is following: 1. Download and verify `openssl-fips-x.x.x.tar.gz` from https://www.openssl.org/source/ 2. Extract source to `openssl-fips` folder 3. `cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out` 4. `make -j && make install` 5. Get into io.js checkout folder 6. `./configure --openssl-fips=/path/to/openssl-fips/out` 7. Build io.js with `make -j` Fix: https://github.com/joyent/node/issues/25463 --- common.gypi | 5 +++++ configure | 28 +++++++++++++++++++++++++++- deps/openssl/doc/FIPS.md | 19 +++++++++++++++++++ deps/openssl/fips/fipscc | 14 ++++++++++++++ deps/openssl/fips/fipsld | 8 ++++++++ deps/openssl/openssl.gyp | 23 +++++++++++++++++++++++ node.gyp | 4 ++-- src/node_crypto.cc | 10 ++++++++++ 8 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 deps/openssl/doc/FIPS.md create mode 100755 deps/openssl/fips/fipscc create mode 100755 deps/openssl/fips/fipsld diff --git a/common.gypi b/common.gypi index ea7779ee097a69..4c1b90b29ad2ca 100644 --- a/common.gypi +++ b/common.gypi @@ -38,6 +38,11 @@ 'OBJ_DIR': '<(PRODUCT_DIR)/obj.target', 'V8_BASE': '<(PRODUCT_DIR)/obj.target/deps/v8/tools/gyp/libv8_base.a', }], + ['openssl_fips != ""', { + 'OPENSSL_PRODUCT': 'libcrypto.a', + }, { + 'OPENSSL_PRODUCT': 'libopenssl.a', + }], ['OS=="mac"', { 'clang%': 1, }, { diff --git a/configure b/configure index 5c9b29bf2c2d40..6e031cfe0632f4 100755 --- a/configure +++ b/configure @@ -88,6 +88,11 @@ parser.add_option("--openssl-no-asm", dest="openssl_no_asm", help="Do not build optimized assembly for OpenSSL") +parser.add_option("--openssl-fips", + action="store", + dest="openssl_fips", + help="Build OpenSSL using FIPS canister .o file in supplied folder") + shared_optgroup.add_option('--shared-http-parser', action='store_true', dest='shared_http_parser', @@ -720,6 +725,16 @@ def configure_openssl(o): o['variables']['node_use_openssl'] = b(not options.without_ssl) o['variables']['node_shared_openssl'] = b(options.shared_openssl) o['variables']['openssl_no_asm'] = 1 if options.openssl_no_asm else 0 + if options.openssl_fips: + o['variables']['openssl_fips'] = options.openssl_fips + fips_dir = os.path.join(root_dir, 'deps', 'openssl', 'fips') + fips_ld = os.path.abspath(os.path.join(fips_dir, 'fipsld')) + o['make_global_settings'] = [ + ['LINK', fips_ld + ' <(openssl_fips)/bin/fipsld'], + ] + else: + o['variables']['openssl_fips'] = '' + if options.without_ssl: return @@ -1025,10 +1040,21 @@ configure_fullystatic(output) # move everything else to target_defaults variables = output['variables'] del output['variables'] + +# make_global_settings should be a root level element too +if 'make_global_settings' in output: + make_global_settings = output['make_global_settings'] + del output['make_global_settings'] +else: + make_global_settings = False + output = { 'variables': variables, - 'target_defaults': output + 'target_defaults': output, } +if make_global_settings: + output['make_global_settings'] = make_global_settings + pprint.pprint(output, indent=2) write('config.gypi', do_not_edit + diff --git a/deps/openssl/doc/FIPS.md b/deps/openssl/doc/FIPS.md new file mode 100644 index 00000000000000..770a3abb08805e --- /dev/null +++ b/deps/openssl/doc/FIPS.md @@ -0,0 +1,19 @@ +# Building io.js with FIPS-compliant OpenSSL + +It is possible to build io.js with [OpenSSL FIPS module][0]. + +Instructions: + +1. Download and verify `openssl-fips-x.x.x.tar.gz` from + https://www.openssl.org/source/ +2. Extract source to `openssl-fips` folder +3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out`` + (NOTE: On OS X, you may want to run + ``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to + build x64-mode io.js) +4. `make -j && make install` +5. Get into io.js checkout folder +6. `./configure --openssl-fips=/path/to/openssl-fips/out` +7. Build io.js with `make -j` + +[0]: https://www.openssl.org/docs/fips/fipsnotes.html diff --git a/deps/openssl/fips/fipscc b/deps/openssl/fips/fipscc new file mode 100755 index 00000000000000..731c1a659b406c --- /dev/null +++ b/deps/openssl/fips/fipscc @@ -0,0 +1,14 @@ +#!/bin/sh +ARGS= + +while [ "x$1" != "x" ]; do + ARG=$1 + shift + case $ARG in + *fips_premain.c) ARGS="$ARGS -x c $ARG -x none";; + *) ARGS="$ARGS $ARG";; + esac +done + +echo $CXX $ARGS +${CXX} $ARGS diff --git a/deps/openssl/fips/fipsld b/deps/openssl/fips/fipsld new file mode 100755 index 00000000000000..513982aa96ed80 --- /dev/null +++ b/deps/openssl/fips/fipsld @@ -0,0 +1,8 @@ +#!/bin/sh + +# NOTE: Just a wrapper around normal fipsld +FIPSLD=$1 +shift + +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +FIPSLD_CC=$DIR/fipscc $FIPSLD $@ diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 5a3dc9b6c74210..d5bb16e5e388f6 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -9,6 +9,7 @@ 'openssl_no_asm%': 0, 'llvm_version%': 0, 'gas_version%': 0, + 'openssl_fips%': 'false', }, 'targets': [ { @@ -21,6 +22,28 @@ ['exclude', 'store/.*$'] ], 'conditions': [ + # FIPS + ['openssl_fips != ""', { + 'defines': [ + 'OPENSSL_FIPS', + ], + 'include_dirs': [ + '<(openssl_fips)/include', + ], + + # Trick fipsld, it expects to see libcrypto.a + 'product_name': 'crypto', + + 'direct_dependent_settings': { + 'defines': [ + 'OPENSSL_FIPS', + ], + 'include_dirs': [ + '<(openssl_fips)/include', + ], + }, + }], + ['openssl_no_asm!=0', { # Disable asm 'defines': [ diff --git a/node.gyp b/node.gyp index de0e47ec2e400d..e098e08906f802 100644 --- a/node.gyp +++ b/node.gyp @@ -233,13 +233,13 @@ [ 'node_target_type!="static_library"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ - '-Wl,-force_load,<(PRODUCT_DIR)/libopenssl.a', + '-Wl,-force_load,<(PRODUCT_DIR)/<(OPENSSL_PRODUCT)', ], }, 'conditions': [ ['OS in "linux freebsd"', { 'ldflags': [ - '-Wl,--whole-archive <(PRODUCT_DIR)/libopenssl.a', + '-Wl,--whole-archive <(PRODUCT_DIR)/<(OPENSSL_PRODUCT)', '-Wl,--no-whole-archive', ], }], diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e2c478a510be84..269855be6ff29c 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5071,6 +5071,16 @@ void InitCryptoOnce() { CRYPTO_set_locking_callback(crypto_lock_cb); CRYPTO_THREADID_set_callback(crypto_threadid_cb); +#ifdef OPENSSL_FIPS + if (!FIPS_mode_set(1)) { + int r; + r = ERR_get_error(); + fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(r, NULL)); + UNREACHABLE(); + } +#endif // OPENSSL_FIPS + + // Turn off compression. Saves memory and protects against CRIME attacks. #if !defined(OPENSSL_NO_COMP) #if OPENSSL_VERSION_NUMBER < 0x00908000L From c836aba52f4b93ec8a7f6a1653adde36a2aca30b Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 4 Jun 2015 23:10:11 +0200 Subject: [PATCH 2/7] fix --- src/node_crypto.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 269855be6ff29c..29de05aaf0f8e4 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5073,9 +5073,8 @@ void InitCryptoOnce() { #ifdef OPENSSL_FIPS if (!FIPS_mode_set(1)) { - int r; - r = ERR_get_error(); - fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(r, NULL)); + int err = ERR_get_error(); + fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, NULL)); UNREACHABLE(); } #endif // OPENSSL_FIPS From c425e479ce2b16ae65e1335ef7ecf3751f0ed668 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Tue, 9 Jun 2015 23:33:19 +0200 Subject: [PATCH 3/7] another fix --- deps/openssl/fips/fipsld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/openssl/fips/fipsld b/deps/openssl/fips/fipsld index 513982aa96ed80..b261376757fdeb 100755 --- a/deps/openssl/fips/fipsld +++ b/deps/openssl/fips/fipsld @@ -4,5 +4,5 @@ FIPSLD=$1 shift -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +DIR=`dirname $0` FIPSLD_CC=$DIR/fipscc $FIPSLD $@ From c5932ad7f327e1254412a4cef76a7dd0de0f56ea Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 10 Jun 2015 12:33:19 +0200 Subject: [PATCH 4/7] fixes --- deps/openssl/doc/FIPS.md | 3 +++ deps/openssl/fips/fipscc | 1 + 2 files changed, 4 insertions(+) diff --git a/deps/openssl/doc/FIPS.md b/deps/openssl/doc/FIPS.md index 770a3abb08805e..6840c60d91298b 100644 --- a/deps/openssl/doc/FIPS.md +++ b/deps/openssl/doc/FIPS.md @@ -15,5 +15,8 @@ Instructions: 5. Get into io.js checkout folder 6. `./configure --openssl-fips=/path/to/openssl-fips/out` 7. Build io.js with `make -j` +8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`) + +NOTE: Windows is not yet supported [0]: https://www.openssl.org/docs/fips/fipsnotes.html diff --git a/deps/openssl/fips/fipscc b/deps/openssl/fips/fipscc index 731c1a659b406c..0af46f56bb2573 100755 --- a/deps/openssl/fips/fipscc +++ b/deps/openssl/fips/fipscc @@ -1,5 +1,6 @@ #!/bin/sh ARGS= +CXX=${CXX:-gcc} while [ "x$1" != "x" ]; do ARG=$1 From d0bb37e7155ab9b2a9017e5410300c304737f4e9 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 10 Jun 2015 12:41:38 +0200 Subject: [PATCH 5/7] fix --- deps/openssl/fips/fipscc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/openssl/fips/fipscc b/deps/openssl/fips/fipscc index 0af46f56bb2573..af30629e3319de 100755 --- a/deps/openssl/fips/fipscc +++ b/deps/openssl/fips/fipscc @@ -1,6 +1,6 @@ #!/bin/sh ARGS= -CXX=${CXX:-gcc} +CXX=${CXX:-g++} while [ "x$1" != "x" ]; do ARG=$1 From 8cfe4ab2dce4cd252a139d2262bf11bdc01abb63 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 10 Jun 2015 12:46:35 +0200 Subject: [PATCH 6/7] fix --- README.md | 23 +++++++++++++++++++++++ deps/openssl/doc/FIPS.md | 22 ---------------------- 2 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 deps/openssl/doc/FIPS.md diff --git a/README.md b/README.md index a5d59e80e709c1..3852ec5e432be5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + io.js ===== @@ -249,6 +250,28 @@ as `deps/icu` (You'll have: `deps/icu/source/...`) > vcbuild full-icu ``` +# Building io.js with FIPS-compliant OpenSSL + +NOTE: Windows is not yet supported + +It is possible to build io.js with +[OpenSSL FIPS module](https://www.openssl.org/docs/fips/fipsnotes.html). + +Instructions: + +1. Download and verify `openssl-fips-x.x.x.tar.gz` from + https://www.openssl.org/source/ +2. Extract source to `openssl-fips` folder +3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out`` + (NOTE: On OS X, you may want to run + ``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to + build x64-mode io.js) +4. `make -j && make install` +5. Get into io.js checkout folder +6. `./configure --openssl-fips=/path/to/openssl-fips/out` +7. Build io.js with `make -j` +8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`) + ## Resources for Newcomers * [CONTRIBUTING.md](./CONTRIBUTING.md) diff --git a/deps/openssl/doc/FIPS.md b/deps/openssl/doc/FIPS.md deleted file mode 100644 index 6840c60d91298b..00000000000000 --- a/deps/openssl/doc/FIPS.md +++ /dev/null @@ -1,22 +0,0 @@ -# Building io.js with FIPS-compliant OpenSSL - -It is possible to build io.js with [OpenSSL FIPS module][0]. - -Instructions: - -1. Download and verify `openssl-fips-x.x.x.tar.gz` from - https://www.openssl.org/source/ -2. Extract source to `openssl-fips` folder -3. ``cd openssl-fips && ./config fipscanisterbuild --prefix=`pwd`/out`` - (NOTE: On OS X, you may want to run - ``./Configure darwin64-x86_64-cc --prefix=`pwd`/out`` if you are going to - build x64-mode io.js) -4. `make -j && make install` -5. Get into io.js checkout folder -6. `./configure --openssl-fips=/path/to/openssl-fips/out` -7. Build io.js with `make -j` -8. Verify with `node -p "process.versions.openssl"` (`1.0.2a-fips`) - -NOTE: Windows is not yet supported - -[0]: https://www.openssl.org/docs/fips/fipsnotes.html From 566a6f7b7cf2fc27262045cf9072bd656a6c4716 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 10 Jun 2015 15:45:02 +0200 Subject: [PATCH 7/7] fix --- configure | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 6e031cfe0632f4..ae994e5d49f27f 100755 --- a/configure +++ b/configure @@ -88,10 +88,10 @@ parser.add_option("--openssl-no-asm", dest="openssl_no_asm", help="Do not build optimized assembly for OpenSSL") -parser.add_option("--openssl-fips", - action="store", - dest="openssl_fips", - help="Build OpenSSL using FIPS canister .o file in supplied folder") +parser.add_option('--openssl-fips', + action='store', + dest='openssl_fips', + help='Build OpenSSL using FIPS canister .o file in supplied folder') shared_optgroup.add_option('--shared-http-parser', action='store_true',