summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md23
-rw-r--r--common.gypi5
-rwxr-xr-xconfigure28
-rwxr-xr-xdeps/openssl/fips/fipscc15
-rwxr-xr-xdeps/openssl/fips/fipsld8
-rw-r--r--deps/openssl/openssl.gyp23
-rw-r--r--node.gyp4
-rw-r--r--src/node_crypto.cc9
8 files changed, 112 insertions, 3 deletions
diff --git a/README.md b/README.md
index 9b7f5b0f17..91215810ad 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/common.gypi b/common.gypi
index ea7779ee09..4c1b90b29a 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 5c9b29bf2c..ae994e5d49 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/fips/fipscc b/deps/openssl/fips/fipscc
new file mode 100755
index 0000000000..af30629e33
--- /dev/null
+++ b/deps/openssl/fips/fipscc
@@ -0,0 +1,15 @@
+#!/bin/sh
+ARGS=
+CXX=${CXX:-g++}
+
+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 0000000000..b261376757
--- /dev/null
+++ b/deps/openssl/fips/fipsld
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# NOTE: Just a wrapper around normal fipsld
+FIPSLD=$1
+shift
+
+DIR=`dirname $0`
+FIPSLD_CC=$DIR/fipscc $FIPSLD $@
diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp
index 5a3dc9b6c7..d5bb16e5e3 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 cbc536d730..2b530f15f1 100644
--- a/node.gyp
+++ b/node.gyp
@@ -234,13 +234,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 51914b8cd7..3888a84baf 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -5097,6 +5097,15 @@ 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 err = ERR_get_error();
+ fprintf(stderr, "openssl fips failed: %s\n", ERR_error_string(err, 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