| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3d0fad3 commit 4296591
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -759,7 +759,135 @@ as `deps/icu` (You'll have: `deps/icu/source/...`) | |||
| 759 | 759 | ||
| 760 | 760 | ## Building Node.js with FIPS-compliant OpenSSL | |
| 761 | 761 | ||
| 762 | - The current version of Node.js does not support FIPS. | ||
| 762 | + The current version of Node.js does not support FIPS when statically linking | ||
| 763 | + (the default) with OpenSSL 1.1.1 but for dynamically linking it is possible | ||
| 764 | + to enable FIPS using the configuration flag `--openssl-is-fips`. | ||
| 765 | + | ||
| 766 | + ### Configuring and building quictls/openssl for FIPS | ||
| 767 | + | ||
| 768 | + For quictls/openssl 3.0 it is possible to enable FIPS when dynamically linking. | ||
| 769 | + Node.js currently uses openssl-3.0.0+quic which can be configured as | ||
| 770 | + follows: | ||
| 771 | + ```console | ||
| 772 | + $ git clone git@github.com:quictls/openssl.git | ||
| 773 | + $ cd openssl | ||
| 774 | + $ ./config --prefix=/path/to/install/dir/ shared enable-fips linux-x86_64 | ||
| 775 | + ``` | ||
| 776 | + This can be compiled and installed using the following commands: | ||
| 777 | + ```console | ||
| 778 | + $ make -j8 | ||
| 779 | + $ make install_ssldirs | ||
| 780 | + $ make install_fips | ||
| 781 | + ``` | ||
| 782 | + | ||
| 783 | + After the FIPS module and configuration file have been installed by the above | ||
| 784 | + instructions we also need to update `/path/to/install/dir/ssl/openssl.cnf` to | ||
| 785 | + use the generated FIPS configuration file (`fipsmodule.cnf`): | ||
| 786 | + ```text | ||
| 787 | + .include fipsmodule.cnf | ||
| 788 | + | ||
| 789 | + # List of providers to load | ||
| 790 | + [provider_sect] | ||
| 791 | + default = default_sect | ||
| 792 | + # The fips section name should match the section name inside the | ||
| 793 | + # included /path/to/install/dir/ssl/fipsmodule.cnf. | ||
| 794 | + fips = fips_sect | ||
| 795 | + | ||
| 796 | + [default_sect] | ||
| 797 | + activate = 1 | ||
| 798 | + ``` | ||
| 799 | + | ||
| 800 | + In the above case OpenSSL is not installed in the default location so two | ||
| 801 | + environment variables need to be set, `OPENSSL_CONF`, and `OPENSSL_MODULES` | ||
| 802 | + which should point to the OpenSSL configuration file and the directory where | ||
| 803 | + OpenSSL modules are located: | ||
| 804 | + ```console | ||
| 805 | + $ export OPENSSL_CONF=/path/to/install/dir/ssl/openssl.cnf | ||
| 806 | + $ export OPENSSL_MODULES=/path/to/install/dir/lib/ossl-modules | ||
| 807 | + ``` | ||
| 808 | + | ||
| 809 | + Node.js can then be configured to enable FIPS: | ||
| 810 | + ```console | ||
| 811 | + $ ./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 | ||
| 812 | + $ export LD_LIBRARY_PATH=/path/to/install/dir/lib | ||
| 813 | + $ make -j8 | ||
| 814 | + ``` | ||
| 815 | + | ||
| 816 | + Verify the produced executable: | ||
| 817 | + ```console | ||
| 818 | + $ ldd ./node | ||
| 819 | + linux-vdso.so.1 (0x00007ffd7917b000) | ||
| 820 | + libcrypto.so.81.3 => /path/to/install/dir/lib/libcrypto.so.81.3 (0x00007fd911321000) | ||
| 821 | + libssl.so.81.3 => /path/to/install/dir/lib/libssl.so.81.3 (0x00007fd91125e000) | ||
| 822 | + libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007fd911232000) | ||
| 823 | + libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd911039000) | ||
| 824 | + libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd910ef3000) | ||
| 825 | + libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd910ed9000) | ||
| 826 | + libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007fd910eb5000) | ||
| 827 | + libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd910cec000) | ||
| 828 | + /lib64/ld-linux-x86-64.so.2 (0x00007fd9117f2000) | ||
| 829 | + ``` | ||
| 830 | + If the `ldd` command says that `libcrypto` cannot be found one needs to set | ||
| 831 | + `LD_LIBRARY_PATH` to point to the directory used above for | ||
| 832 | + `--shared-openssl-libpath` (see previous step). | ||
| 833 | + | ||
| 834 | + Verify the OpenSSL version: | ||
| 835 | + ```console | ||
| 836 | + $ ./node -p process.versions.openssl | ||
| 837 | + 3.0.0-alpha16+quic | ||
| 838 | + ``` | ||
| 839 | + | ||
| 840 | + Verify that FIPS is available: | ||
| 841 | + ```console | ||
| 842 | + $ ./node -p 'process.config.variables.openssl_is_fips' | ||
| 843 | + true | ||
| 844 | + $ ./node --enable-fips -p 'crypto.getFips()' | ||
| 845 | + 1 | ||
| 846 | + ``` | ||
| 847 | + | ||
| 848 | + FIPS support can then be enable via the OpenSSL configuration file or | ||
| 849 | + using `--enable-fips` or `--force-fips` command line options to the Node.js | ||
| 850 | + executable. See sections | ||
| 851 | + [Enabling FIPS using Node.js options](#enabling-fips-using-node.js-options) and | ||
| 852 | + [Enabling FIPS using OpenSSL config](#enabling-fips-using-openssl-config) below. | ||
| 853 | + | ||
| 854 | + ### Enabling FIPS using Node.js options | ||
| 855 | + This is done using one of the Node.js options `--enable-fips` or | ||
| 856 | + `--force-fips`, for example: | ||
| 857 | + ```console | ||
| 858 | + $ node --enable-fips -p 'crypto.getFips()' | ||
| 859 | + ``` | ||
| 860 | + | ||
| 861 | + ### Enabling FIPS using OpenSSL config | ||
| 862 | + This example show that using OpenSSL's configuration file, FIPS can be enabled | ||
| 863 | + without specifying the `--enable-fips` or `--force-fips` options by setting | ||
| 864 | + `default_properties = fips=yes` in the FIPS configuration file. See | ||
| 865 | + [link](https://github.com/openssl/openssl/blob/master/README-FIPS.md#loading-the-fips-module-at-the-same-time-as-other-providers) | ||
| 866 | + for details. | ||
| 867 | + | ||
| 868 | + For this to work the OpenSSL configuration file (default openssl.cnf) needs to | ||
| 869 | + be updated. The following shows an example: | ||
| 870 | + ```console | ||
| 871 | + openssl_conf = openssl_init | ||
| 872 | + | ||
| 873 | + .include /path/to/install/dir/ssl/fipsmodule.cnf | ||
| 874 | + | ||
| 875 | + [openssl_init] | ||
| 876 | + providers = prov | ||
| 877 | + alg_section = algorithm_sect | ||
| 878 | + | ||
| 879 | + [prov] | ||
| 880 | + fips = fips_sect | ||
| 881 | + default = default_sect | ||
| 882 | + | ||
| 883 | + [default_sect] | ||
| 884 | + activate = 1 | ||
| 885 | + | ||
| 886 | + [algorithm_sect] | ||
| 887 | + default_properties = fips=yes | ||
| 888 | + ``` | ||
| 889 | + After this change Node.js can be run without the `--enable-fips` or `--force-fips` | ||
| 890 | + options. | ||
| 763 | 891 | ||
| 764 | 892 | ## Building Node.js with external core modules | |
| 765 | 893 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,7 +99,7 @@ | |||
| 99 | 99 | 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', | |
| 100 | 100 | }], | |
| 101 | 101 | ['openssl_fips != ""', { | |
| 102 | - 'openssl_product': '<(STATIC_LIB_PREFIX)crypto<(STATIC_LIB_SUFFIX)', | ||
| 102 | + 'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)', | ||
| 103 | 103 | }, { | |
| 104 | 104 | 'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)', | |
| 105 | 105 | }], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1456,6 +1456,12 @@ def without_ssl_error(option): | |||
| 1456 | 1456 | if options.openssl_fips or options.openssl_fips == '': | |
| 1457 | 1457 | error('FIPS is not supported in this version of Node.js') | |
| 1458 | 1458 | ||
| 1459 | + if options.openssl_is_fips and not options.shared_openssl: | ||
| 1460 | + error('--openssl-is-fips is only available with --shared-openssl') | ||
| 1461 | + | ||
| 1462 | + if options.openssl_is_fips: | ||
| 1463 | + o['defines'] += ['OPENSSL_FIPS'] | ||
| 1464 | + | ||
| 1459 | 1465 | if options.shared_openssl: | |
| 1460 | 1466 | variables['openssl_quic'] = b(getsharedopensslhasquic.get_has_quic(options.__dict__['shared_openssl_includes'])) | |
| 1461 | 1467 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,12 @@ | |||
| 14 | 14 | ||
| 15 | 15 | #include "math.h" | |
| 16 | 16 | ||
| 17 | + #ifdef OPENSSL_FIPS | ||
| 18 | + #if OPENSSL_VERSION_MAJOR >= 3 | ||
| 19 | + #include "openssl/provider.h" | ||
| 20 | + #endif | ||
| 21 | + #endif | ||
| 22 | + | ||
| 17 | 23 | namespace node { | |
| 18 | 24 | ||
| 19 | 25 | using v8::ArrayBuffer; | |
@@ -197,7 +203,16 @@ void SetFipsCrypto(const FunctionCallbackInfo<Value>& args) { | |||
| 197 | 203 | ||
| 198 | 204 | void TestFipsCrypto(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
| 199 | 205 | #ifdef OPENSSL_FIPS | |
| 206 | + #if OPENSSL_VERSION_MAJOR >= 3 | ||
| 207 | + OSSL_PROVIDER* fips_provider = nullptr; | ||
| 208 | + if (OSSL_PROVIDER_available(nullptr, "fips")) { | ||
| 209 | + fips_provider = OSSL_PROVIDER_load(nullptr, "fips"); | ||
| 210 | + } | ||
| 211 | + const auto enabled = fips_provider == nullptr ? 0 : | ||
| 212 | + OSSL_PROVIDER_self_test(fips_provider) ? 1 : 0; | ||
| 213 | + #else | ||
| 200 | 214 | const auto enabled = FIPS_selftest() ? 1 : 0; | |
| 215 | + #endif | ||
| 201 | 216 | #else // OPENSSL_FIPS | |
| 202 | 217 | const auto enabled = 0; | |
| 203 | 218 | #endif // OPENSSL_FIPS | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ | |||
| 24 | 24 | #endif // !OPENSSL_NO_ENGINE | |
| 25 | 25 | // The FIPS-related functions are only available | |
| 26 | 26 | // when the OpenSSL itself was compiled with FIPS support. | |
| 27 | - #ifdef OPENSSL_FIPS | ||
| 27 | + #if defined(OPENSSL_FIPS) && OPENSSL_VERSION_MAJOR < 3 | ||
| 28 | 28 | # include <openssl/fips.h> | |
| 29 | 29 | #endif // OPENSSL_FIPS | |
| 30 | 30 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,6 +66,10 @@ testHelper( | |||
| 66 | 66 | 'require("crypto").getFips()', | |
| 67 | 67 | { ...process.env, 'OPENSSL_CONF': '' }); | |
| 68 | 68 | ||
| 69 | + // This should succeed for both FIPS and non-FIPS builds in combination with | ||
| 70 | + // OpenSSL 1.1.1 or OpenSSL 3.0 | ||
| 71 | + const test_result = testFipsCrypto(); | ||
| 72 | + assert.ok(test_result === 1 || test_result === 0); | ||
| 69 | 73 | ||
| 70 | 74 | // If Node was configured using --shared-openssl fips support might be | |
| 71 | 75 | // available depending on how OpenSSL was built. If fips support is | |
@@ -79,7 +83,7 @@ testHelper( | |||
| 79 | 83 | // ("Error: Cannot set FIPS mode in a non-FIPS build."). | |
| 80 | 84 | // Due to this uncertainty the following tests are skipped when configured | |
| 81 | 85 | // with --shared-openssl. | |
| 82 | - if (!sharedOpenSSL()) { | ||
| 86 | + if (!sharedOpenSSL() && !common.hasOpenSSL3) { | ||
| 83 | 87 | // OpenSSL config file should be able to turn on FIPS mode | |
| 84 | 88 | testHelper( | |
| 85 | 89 | 'stdout', | |
| Back | FazBrowse Home | New Git URL |
0 commit comments