diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 3638aa51371f54..24460e9f5bcc97 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -247,8 +247,9 @@ jobs: # the matrix-selected nixpkgs attribute (e.g. `openssl_3_6`). All # other shared libs (brotli, cares, libuv, …) keep their defaults. # `permittedInsecurePackages` whitelists just the matrix-selected - # release (e.g. `openssl-1.1.1w`) so EOL-with-extended-support - # cycles evaluate without relaxing nixpkgs' meta check globally. + # releases so EOL-with-extended-support cycles evaluate without + # relaxing nixpkgs' meta check globally. It is empty while every + # matrix entry is a supported release. extra-nix-flags: | --arg useSeparateDerivationForV8 ${{ needs.build-aarch64-linux-v8.outputs.local-cache && '"$(nix-store --import < libv8-aarch64-linux.nar)"' || 'true' }} \ --arg sharedLibDeps "(import $TAR_DIR/tools/nix/sharedLibDeps.nix {}) // { diff --git a/BUILDING.md b/BUILDING.md index 5473f823cafbbf..f05762945f9ad7 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -206,7 +206,7 @@ on your Linux distribution. #### OpenSSL asm support -OpenSSL-1.1.1 requires the following assembler version for use of asm +OpenSSL requires the following assembler version for use of asm support on x86\_64 and ia32. For use of AVX-512, @@ -214,8 +214,6 @@ For use of AVX-512, * gas (GNU assembler) version 2.26 or higher * nasm version 2.11.8 or higher in Windows -AVX-512 is disabled for Skylake-X by OpenSSL-1.1.1. - For use of AVX2, * gas (GNU assembler) version 2.23 or higher @@ -223,7 +221,7 @@ For use of AVX2, * llvm version 3.3 or higher * nasm version 2.10 or higher in Windows -Please refer to for details. +Please refer to for details. If compiling without one of the above, use `configure` with the `--openssl-no-asm` flag. Otherwise, `configure` will fail. @@ -1032,7 +1030,7 @@ as `deps/icu` (You'll have: `deps/icu/source/...`) ### Configure OpenSSL appname Node.js can use an OpenSSL configuration file by specifying the environment -variable `OPENSSL_CONF`, or using the command line option `--openssl-conf`, and +variable `OPENSSL_CONF`, or using the command line option `--openssl-config`, and if none of those are specified will default to reading the default OpenSSL configuration file `openssl.cnf`. Node.js will only read a section that is by default named `nodejs_conf`, but this name can be overridden using the following @@ -1044,12 +1042,20 @@ configure option: ## Building Node.js with FIPS-compliant OpenSSL -Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via -[OpenSSL's provider model](https://docs.openssl.org/3.0/man7/crypto/#OPENSSL-PROVIDERS). -It is not necessary to rebuild Node.js to enable support for FIPS. +Node.js can use an OpenSSL FIPS provider via +[OpenSSL's provider model](https://docs.openssl.org/master/man7/crypto/#openssl-providers), +whether OpenSSL is linked statically or dynamically. It is not necessary to +rebuild Node.js to do so; the provider and the OpenSSL configuration that +activates it are supplied at runtime. + +Node.js does not build a FIPS provider. OpenSSL requires that a FIPS provider +be built from a release that carries a FIPS certificate, so a provider built +as part of the Node.js build would have no validation status. -See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to -enable FIPS support in Node.js. +`./configure --openssl-is-fips` only records that the OpenSSL being linked is +FIPS capable, and requires `--shared-openssl`. + +See [FIPS mode](doc/api/crypto.md#fips-mode) for how to configure it. ## Building Node.js with Temporal support @@ -1133,6 +1139,10 @@ A number of `configure` options are provided to support this use case. provide the ability to set the path to an external JavaScript file for the dependency to be used at runtime. +When building with `--shared-openssl`, Node.js requires OpenSSL 3.0 or later. +Support for building against OpenSSL 1.x was removed in Node.js 27.0.0, and +`configure` fails if an older version is detected. + It is the responsibility of any distribution shipping with these options to: diff --git a/configure.py b/configure.py index def52c6fb22f73..28e7264c5834df 100755 --- a/configure.py +++ b/configure.py @@ -268,7 +268,8 @@ action='store_true', dest='openssl_is_fips', default=None, - help='specifies that the OpenSSL library is FIPS compatible') + help='specifies that the shared OpenSSL library is FIPS capable ' + '(requires --shared-openssl)') parser.add_argument('--openssl-use-def-ca-store', action='store_true', @@ -1523,7 +1524,7 @@ def get_openssl_version(o): return version_number - except (OSError, ValueError, subprocess.SubprocessError) as e: + except (OSError, TypeError, ValueError, subprocess.SubprocessError) as e: warn(f'Failed to determine OpenSSL version from header: {e}') return 0 @@ -2275,7 +2276,6 @@ def configure_openssl(o): variables['node_shared_ngtcp2'] = b(options.shared_ngtcp2) variables['node_shared_nghttp3'] = b(options.shared_nghttp3) variables['openssl_is_fips'] = b(options.openssl_is_fips) - variables['node_fipsinstall'] = b(False) if options.openssl_no_asm: variables['openssl_no_asm'] = 1 @@ -2330,17 +2330,25 @@ def without_ssl_error(option): if options.openssl_no_asm and options.shared_openssl: error('--openssl-no-asm is incompatible with --shared-openssl') + if options.openssl_is_fips and not options.shared_openssl: + error('--openssl-is-fips is only available with --shared-openssl') + if options.openssl_is_fips: o['defines'] += ['OPENSSL_FIPS'] - if options.openssl_is_fips and not options.shared_openssl: - variables['node_fipsinstall'] = b(True) - configure_library('openssl', o) o['variables']['openssl_version'] = get_openssl_version(o) o['variables']['openssl_is_boringssl'] = get_openssl_is_boringssl(o) + # BoringSSL identifies itself as OpenSSL 1.1.1 and is exempt from this check. + # A version of 0 means detection failed, which is already warned about in + # get_openssl_version() and is caught at compile time by ncrypto.h. + openssl_version = o['variables']['openssl_version'] + if o['variables']['openssl_is_boringssl'] == 'false' and \ + 0 < openssl_version < 0x30000000: + error('OpenSSL 1.x is no longer supported, v3.0.0 or later is required.') + def configure_lief(o): if options.without_lief: if options.shared_lief: diff --git a/deps/ncrypto/engine.cc b/deps/ncrypto/engine.cc index a8e64e25049183..6b9514b8565e39 100644 --- a/deps/ncrypto/engine.cc +++ b/deps/ncrypto/engine.cc @@ -1,8 +1,7 @@ #include "ncrypto.h" -#if !defined(OPENSSL_NO_ENGINE) && \ - ((defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT) || \ - NCRYPTO_USE_LEGACY_OPENSSL) +#if !defined(OPENSSL_NO_ENGINE) && defined(NCRYPTO_ENGINE_COMPAT) && \ + NCRYPTO_ENGINE_COMPAT #include #endif diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index bed4d48d118d51..15bd3ec4dfcc81 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -17,7 +17,7 @@ #include #include #include -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include #include #include @@ -59,17 +59,6 @@ constexpr static PQCMapping pqc_mappings[] = { #endif -// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e. -#if OPENSSL_VERSION_NUMBER < 0x1010105fL -#define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \ - EVP_PKEY_CTX_ctrl((ctx), \ - EVP_PKEY_DSA, \ - EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, \ - (qbits), \ - nullptr) -#endif - namespace ncrypto { namespace { using BignumCtxPointer = DeleteFnPtr; @@ -515,27 +504,26 @@ DataPointer DataPointer::resize(size_t len) { // ============================================================================ bool isFipsEnabled() { ClearErrorOnReturn clear_error_on_return; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL return EVP_default_properties_is_fips_enabled(nullptr) == 1; #else return FIPS_mode() == 1; #endif } -bool setFipsEnabled(bool enable, CryptoErrorList* errors) { - if (isFipsEnabled() == enable) return true; - ClearErrorOnReturn clearErrorOnReturn(errors); -#if OPENSSL_VERSION_MAJOR >= 3 - return EVP_default_properties_enable_fips(nullptr, enable ? 1 : 0) == 1 && - EVP_default_properties_is_fips_enabled(nullptr); +bool setFipsEnabled() { + if (isFipsEnabled()) return true; + ClearErrorOnReturn clearErrorOnReturn; +#ifndef OPENSSL_IS_BORINGSSL + return EVP_default_properties_enable_fips(nullptr, 1) == 1; #else - return FIPS_mode_set(enable ? 1 : 0) == 1; + return FIPS_mode_set(1) == 1; #endif } bool testFipsEnabled() { ClearErrorOnReturn clear_error_on_return; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL OSSL_PROVIDER* fips_provider = nullptr; if (OSSL_PROVIDER_available(nullptr, "fips")) { fips_provider = OSSL_PROVIDER_load(nullptr, "fips"); @@ -802,7 +790,7 @@ bool CSPRNG(void* buffer, size_t length) { auto buf = reinterpret_cast(buffer); do { if (1 == RAND_status()) { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (1 == RAND_bytes_ex(nullptr, buf, length, 0)) { return true; } @@ -815,7 +803,7 @@ bool CSPRNG(void* buffer, size_t length) { return true; #endif } -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL const auto code = ERR_peek_last_error(); // A misconfigured OpenSSL 3 installation may report 1 from RAND_poll() // and RAND_status() but fail in RAND_bytes() if it cannot look up @@ -1112,7 +1100,7 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { BIO_printf(out.get(), (j == 0) ? "%X" : ":%X", pair); } } else { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL BIO_printf(out.get(), "", ip_len); #else BIO_printf(out.get(), ""); @@ -1131,9 +1119,9 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { // awkward, especially when passed to translatePeerCertificate. bool unicode = true; const char* prefix = nullptr; - // OpenSSL 1.1.1 does not support othername in GENERAL_NAME_print and may + // BoringSSL does not support othername in GENERAL_NAME_print and may // not define these NIDs. -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int nid = OBJ_obj2nid(gen->d.otherName->type_id); switch (nid) { case NID_id_on_SmtpUTF8Mailbox: @@ -1153,7 +1141,7 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { prefix = "NAIRealm"; break; } -#endif // OPENSSL_VERSION_MAJOR >= 3 +#endif // !OPENSSL_IS_BORINGSSL int val_type = gen->d.otherName->value->type; if (prefix == nullptr || (unicode && val_type != V_ASN1_UTF8STRING) || (!unicode && val_type != V_ASN1_IA5STRING)) { @@ -1244,7 +1232,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, const X509_EXTENSION* ext) { } sk_ACCESS_DESCRIPTION_pop_free(descs, ACCESS_DESCRIPTION_free); -#if OPENSSL_VERSION_MAJOR < 3 +#ifdef OPENSSL_IS_BORINGSSL BIO_write(out.get(), "\n", 1); #endif @@ -3679,12 +3667,8 @@ Result EVPKeyPointer::writePrivateKey( cipher, passphrase); } -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const RSA* rsa = EVP_PKEY_get0_RSA(get()); #else RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif switch (config.format) { case PKFormatType::PEM: { err = PEM_write_bio_RSAPrivateKey( @@ -3754,12 +3738,8 @@ Result EVPKeyPointer::writePrivateKey( "type-specific", cipher, passphrase); -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); #else EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); -#endif switch (config.format) { case PKFormatType::PEM: { err = PEM_write_bio_ECPrivateKey( @@ -3820,12 +3800,8 @@ Result EVPKeyPointer::writePublicKey( mark_pop_error_on_return.peekError()); } return bio; -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const RSA* rsa = EVP_PKEY_get0_RSA(get()); #else RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { // Encode PKCS#1 as PEM. if (PEM_write_bio_RSAPublicKey(bio.get(), rsa) != 1) { @@ -3953,14 +3929,7 @@ EVPKeyPointer::operator Rsa() const { #if NCRYPTO_USE_OPENSSL3_PROVIDER return Rsa(get()); #else - // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL - // versions older than 1.1.1e via FIPS / dynamic linking. - OSSL3_CONST RSA* rsa; - if (OPENSSL_VERSION_NUMBER >= 0x1010105fL) { - rsa = EVP_PKEY_get0_RSA(get()); - } else { - rsa = static_cast(EVP_PKEY_get0(get())); - } + OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get()); if (rsa == nullptr) return {}; return Rsa(rsa); #endif @@ -3982,7 +3951,7 @@ EVPKeyPointer::operator Dsa() const { bool EVPKeyPointer::validateDsaParameters() const { if (!pkey_) return false; /* Validate DSA2 parameters from FIPS 186-4 */ -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (EVP_default_properties_is_fips_enabled(nullptr) && EVP_PKEY_DSA == id()) { #else if (FIPS_mode() && EVP_PKEY_DSA == id()) { @@ -5391,11 +5360,7 @@ EVPKeyPointer EVPKeyCtxPointer::paramgen() const { bool EVPKeyCtxPointer::publicCheck() const { if (!ctx_) return false; #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 return EVP_PKEY_public_check_quick(ctx_.get()) == 1; -#else - return EVP_PKEY_public_check(ctx_.get()) == 1; -#endif #else // OPENSSL_IS_BORINGSSL // Boringssl appears not to support this operation. // TODO(jasnell): Is there an alternative approach that Boringssl does @@ -5994,7 +5959,7 @@ struct CipherCallbackContext { void operator()(const char* name) { cb(name); } }; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL template = 3 +#ifndef OPENSSL_IS_BORINGSSL array_push_back= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], }], ], }, 'sources': [ '<@(ncrypto_sources)' ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], 'dependencies': [ 'ncrypto_engine', ], }], - ['openssl_is_boringssl=="false" and openssl_version < 0x3000000f', { - 'sources': [ '<@(ncrypto_engine_sources)' ], - }], ['node_shared_openssl=="false"', { 'dependencies': [ '../openssl/openssl.gyp:openssl' @@ -63,7 +55,7 @@ }, ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { + ['openssl_is_boringssl=="false"', { 'targets': [ { 'target_name': 'ncrypto_engine', diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 6fb6b384fd4fa4..a9f59ff4ed0fc5 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -29,6 +29,11 @@ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20))) #endif +// BoringSSL reports itself as OpenSSL 1.1.1, so it has to be excluded here. +#if !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_VERSION_PREREQ(3, 0) +#error "OpenSSL 1.x is no longer supported, v3.0.0 or later is required." +#endif + // BoringSSL declares the EVP_*_do_all* APIs, but their implementation may // live in libdecrepit. This matches standalone ncrypto's build flag. #ifndef NCRYPTO_BSSL_LIBDECREPIT_MISSING @@ -43,31 +48,17 @@ // Backend split: // - OpenSSL >= 3 uses provider APIs and hides deprecated low-level objects. -// - BoringSSL has its own API-compatible branch. -// - OpenSSL < 3 remains the legacy fallback branch. -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0) -#define NCRYPTO_USE_OPENSSL3_PROVIDER 1 -#else -#define NCRYPTO_USE_OPENSSL3_PROVIDER 0 -#endif - +// - BoringSSL has its own API-compatible branch and keeps using the legacy +// low-level key types. #ifdef OPENSSL_IS_BORINGSSL #define NCRYPTO_USE_BORINGSSL 1 +#define NCRYPTO_USE_OPENSSL3_PROVIDER 0 #else #define NCRYPTO_USE_BORINGSSL 0 +#define NCRYPTO_USE_OPENSSL3_PROVIDER 1 #endif -#if !NCRYPTO_USE_OPENSSL3_PROVIDER && !NCRYPTO_USE_BORINGSSL -#define NCRYPTO_USE_LEGACY_OPENSSL 1 -#else -#define NCRYPTO_USE_LEGACY_OPENSSL 0 -#endif - -#if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_LEGACY_OPENSSL -#define NCRYPTO_USE_LEGACY_KEY_TYPES 1 -#else -#define NCRYPTO_USE_LEGACY_KEY_TYPES 0 -#endif +#define NCRYPTO_USE_LEGACY_KEY_TYPES NCRYPTO_USE_BORINGSSL #if NCRYPTO_USE_OPENSSL3_PROVIDER #include @@ -75,13 +66,7 @@ #include #endif -// The FIPS-related functions are only available -// when the OpenSSL itself was compiled with FIPS support. -#if defined(OPENSSL_FIPS) && !OPENSSL_VERSION_PREREQ(3, 0) -#include -#endif // OPENSSL_FIPS - -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_OCB 1 #else #define OPENSSL_WITH_AES_OCB 0 @@ -93,13 +78,9 @@ #define OPENSSL_WITH_ARGON2 0 #endif -#if OPENSSL_VERSION_PREREQ(3, 0) || defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_KEM 1 -#else -#define OPENSSL_WITH_KEM 0 -#endif -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_EVP_MAC 1 #else #define OPENSSL_WITH_EVP_MAC 0 @@ -152,7 +133,7 @@ #define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024 #endif -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OSSL3_CONST const #else #define OSSL3_CONST @@ -1842,7 +1823,11 @@ class EnginePointer final { // FIPS bool isFipsEnabled(); -bool setFipsEnabled(bool enabled, CryptoErrorList* errors); +// Restricts the default library context to FIPS-approved implementations. +// This only narrows the default property query; it neither loads nor +// activates the FIPS provider. Callers are expected to have established +// that a FIPS provider is active first, e.g. via testFipsEnabled(). +bool setFipsEnabled(); bool testFipsEnabled(); diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 4e16412a028340..61234b5c6c4d8f 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -97,35 +97,6 @@ }, }], ] - }, { - # openssl-fipsmodule target - 'target_name': 'openssl-fipsmodule', - 'type': 'shared_library', - 'dependencies': ['openssl-cli'], - 'includes': ['./openssl_common.gypi'], - 'include_dirs+': ['openssl/apps/include'], - 'cflags': [ '-fPIC' ], - #'ldflags': [ '-o', 'fips.so' ], - #'ldflags': [ '-Wl,--version-script=providers/fips.ld',], - 'conditions': [ - [ 'openssl_no_asm==1', { - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'target_arch=="arm64" and OS=="win"', { - # VC-WIN64-ARM inherits from VC-noCE-common that has no asms. - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'gas_version and v(gas_version) >= v("2.26") or ' - 'nasm_version and v(nasm_version) >= v("2.11.8")', { - # Require AVX512IFMA supported. See - # https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html - # Currently crypto/poly1305/asm/poly1305-x86_64.pl requires AVX512IFMA. - 'includes': ['./openssl-fips_asm.gypi'], - }, { - 'includes': ['./openssl-fips_asm_avx2.gypi'], - }], - ], - 'direct_dependent_settings': { - 'include_dirs': [ 'openssl/include', 'openssl/crypto/include'] - } - }, + }, ] } diff --git a/doc/api/cli.md b/doc/api/cli.md index 5d59844d4cbc72..876f0577a22475 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1562,15 +1562,6 @@ added: v12.12.0 Disable loading native addons that are not [context-aware][]. -### `--force-fips` - - - -Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.) -(Same requirements as `--enable-fips`.) - ### `--force-node-api-uncaught-exceptions-policy` Load an OpenSSL configuration file on startup. Among other uses, this can be -used to enable FIPS-compliant crypto if Node.js is built with -`./configure --openssl-fips`. +used to enable FIPS-compliant crypto if Node.js is built against +FIPS-enabled OpenSSL. If the [`--openssl-config`][] command-line option is used, the environment variable is ignored. diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 4770e0c36c3948..a1664dca6fa760 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -4190,7 +4190,7 @@ Key decapsulation using a KEM algorithm with a private key. Supported key types and their KEM algorithms are: -* `'rsa'`[^openssl30] RSA Secret Value Encapsulation +* `'rsa'`[^noboringssl] RSA Secret Value Encapsulation * `'ec'`[^openssl32] DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256) * `'x25519'`[^openssl32] DHKEM(X25519, HKDF-SHA256) * `'x448'`[^openssl32] DHKEM(X448, HKDF-SHA512) @@ -4262,7 +4262,7 @@ Key encapsulation using a KEM algorithm with a public key. Supported key types and their KEM algorithms are: -* `'rsa'`[^openssl30] RSA Secret Value Encapsulation +* `'rsa'`[^noboringssl] RSA Secret Value Encapsulation * `'ec'`[^openssl32] DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA256), DHKEM(P-521, HKDF-SHA256) * `'x25519'`[^openssl32] DHKEM(X25519, HKDF-SHA256) * `'x448'`[^openssl32] DHKEM(X448, HKDF-SHA512) @@ -4275,21 +4275,6 @@ passed to [`crypto.createPublicKey()`][]. If the `callback` function is provided this function uses libuv's threadpool. -### `crypto.fips` - - - -> Stability: 0 - Deprecated - -Property for checking and controlling whether a FIPS compliant crypto provider -is currently in use. Setting to true requires a FIPS build of Node.js. - -This property is deprecated. Please use `crypto.setFips()` and -`crypto.getFips()` instead. - ### `crypto.generateKey(type, options, callback)` -* Returns: {number} `1` if and only if a FIPS compliant crypto provider is - currently in use, `0` otherwise. A future semver-major release may change - the return type of this API to a {boolean}. +* Returns: {number} `1` if the default OpenSSL library context restricts + algorithm selection to FIPS-approved implementations, `0` otherwise. A future + semver-major release may change the return type of this API to a {boolean}. + +This reports whether the default property query is `fips=yes`. It is a +statement of intent, not proof: it does not establish that a FIPS provider is +loaded, nor that any provider in use is FIPS validated. See [FIPS mode][]. ### `crypto.getHashes()` @@ -6167,17 +6156,6 @@ is a bit field taking one of or a mix of the following flags (defined in * `crypto.constants.ENGINE_METHOD_ALL` * `crypto.constants.ENGINE_METHOD_NONE` -### `crypto.setFips(bool)` - - - -* `bool` {boolean} `true` to enable FIPS mode. - -Enables the FIPS compliant crypto provider in a FIPS-enabled Node.js build. -Throws an error if FIPS mode is not available. - ### `crypto.sign(algorithm, data, key[, callback])` -Type: Runtime +Type: End-of-Life -The [`crypto.fips`][] property is deprecated. Please use `crypto.setFips()` -and `crypto.getFips()` instead. +The `crypto.fips` property has been removed. Use [`crypto.getFips()`][] to read +whether the default OpenSSL library context is restricted to FIPS-approved +implementations. Changing that at runtime is no longer possible; configure the +FIPS provider through OpenSSL and use [`--enable-fips`][] to require at startup +that one is active. See [FIPS mode][] for details. An automated migration is available ([source](https://github.com/nodejs/userland-migrations/tree/main/recipes/crypto-fips-to-getFips)). @@ -4696,6 +4702,7 @@ successfully before the response closed. [DEP0142]: #dep0142-repl_builtinlibs [DEP0156]: #dep0156-aborted-property-and-abort-aborted-event-in-http +[FIPS mode]: crypto.md#fips-mode [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 [RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4 @@ -4703,6 +4710,7 @@ successfully before the response closed. [WHATWG URL API]: url.md#the-whatwg-url-api [`"exports"` or `"main"` entry]: packages.md#main-entry-point-export [`'uncaughtException'`]: process.md#event-uncaughtexception +[`--enable-fips`]: cli.md#--enable-fips [`--force-node-api-uncaught-exceptions-policy`]: cli.md#--force-node-api-uncaught-exceptions-policy [`--pending-deprecation`]: cli.md#--pending-deprecation [`--throw-deprecation`]: cli.md#--throw-deprecation @@ -4739,7 +4747,7 @@ successfully before the response closed. [`crypto.createDecipheriv()`]: crypto.md#cryptocreatedecipherivalgorithm-key-iv-options [`crypto.createHash()`]: crypto.md#cryptocreatehashalgorithm-options [`crypto.createHmac()`]: crypto.md#cryptocreatehmacalgorithm-key-options -[`crypto.fips`]: crypto.md#cryptofips +[`crypto.getFips()`]: crypto.md#cryptogetfips [`crypto.pbkdf2()`]: crypto.md#cryptopbkdf2password-salt-iterations-keylen-digest-callback [`crypto.randomBytes()`]: crypto.md#cryptorandombytessize-callback [`crypto.scrypt()`]: crypto.md#cryptoscryptpassword-salt-keylen-options-callback diff --git a/doc/api/errors.md b/doc/api/errors.md index a7a7e6549f68e6..1b833d9c99c25b 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -911,20 +911,6 @@ key lies outside of the elliptic curve. An invalid crypto engine identifier was passed to [`require('node:crypto').setEngine()`][]. - - -### `ERR_CRYPTO_FIPS_FORCED` - -The [`--force-fips`][] command-line argument was used but there was an attempt -to enable or disable FIPS mode in the `node:crypto` module. - - - -### `ERR_CRYPTO_FIPS_UNAVAILABLE` - -An attempt was made to enable or disable FIPS mode, but FIPS mode was not -available. - ### `ERR_CRYPTO_HASH_FINALIZED` @@ -3768,6 +3754,28 @@ removed: v15.0.0 The native call from `process.cpuUsage` could not be processed. + + +### `ERR_CRYPTO_FIPS_FORCED` + + + +The `--force-fips` command-line argument was used but there was an attempt +to enable or disable FIPS mode in the `node:crypto` module. + + + +### `ERR_CRYPTO_FIPS_UNAVAILABLE` + + + +An attempt was made to enable or disable FIPS mode, but FIPS mode was not +available. + ### `ERR_CRYPTO_HASH_DIGEST_NO_UTF16` @@ -4592,7 +4600,6 @@ An error occurred trying to allocate memory. This should never happen. [`"imports"`]: packages.md#imports [`'uncaughtException'`]: process.md#event-uncaughtexception [`--disable-proto=throw`]: cli.md#--disable-protomode -[`--force-fips`]: cli.md#--force-fips [`--no-addons`]: cli.md#--no-addons [`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode [`BoundSocket`]: net.md#class-netboundsocket diff --git a/doc/api/tls.md b/doc/api/tls.md index ae3de645eaa3b6..5e7bb70587f432 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -182,8 +182,8 @@ On the client connection, a custom `checkServerIdentity` should be passed because the default one will fail in the absence of a certificate. According to the [RFC 4279][], PSK identities up to 128 bytes in length and -PSKs up to 64 bytes in length must be supported. As of OpenSSL 1.1.0 -maximum identity size is 128 bytes, and maximum PSK length is 256 bytes. +PSKs up to 64 bytes in length must be supported. In OpenSSL the maximum +identity size is 128 bytes, and the maximum PSK length is 256 bytes. The current implementation doesn't support asynchronous PSK callbacks due to the limitations of the underlying OpenSSL API. @@ -1195,7 +1195,7 @@ For example, a TLSv1.2 protocol with AES256-SHA cipher: ``` See -[SSL\_CIPHER\_get\_name](https://www.openssl.org/docs/man1.1.1/man3/SSL_CIPHER_get_name.html) +[SSL\_CIPHER\_get\_name](https://www.openssl.org/docs/man3.0/man3/SSL_CIPHER_get_name.html) for more information. ### `tlsSocket.getEphemeralKeyInfo()` @@ -1447,7 +1447,7 @@ added: v12.11.0 the client in the order of decreasing preference. See -[SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_shared_sigalgs.html) +[SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man3.0/man3/SSL_get_shared_sigalgs.html) for more information. ### `tlsSocket.getTLSTicket()` @@ -2034,7 +2034,7 @@ changes: The list can contain digest algorithms (`SHA256`, `MD5` etc.), public key algorithms (`RSA-PSS`, `ECDSA` etc.), combination of both (e.g 'RSA+SHA384') or TLS v1.3 scheme names (e.g. `rsa_pss_pss_sha512`). - See [OpenSSL man pages](https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set1_sigalgs_list.html) + See [OpenSSL man pages](https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set1_sigalgs_list.html) for more info. * `ciphers` {string} Cipher suite specification, replacing the default. For more information, see [Modifying the default TLS cipher suite][]. Permitted @@ -2539,7 +2539,7 @@ added: v0.11.3 [RFC 5077]: https://tools.ietf.org/html/rfc5077 [RFC 5929]: https://tools.ietf.org/html/rfc5929 [RFC 8879]: https://tools.ietf.org/html/rfc8879 -[SSL_METHODS]: https://www.openssl.org/docs/man1.1.1/man7/ssl.html#Dealing-with-Protocol-Methods +[SSL_METHODS]: https://www.openssl.org/docs/man3.0/man7/ssl.html#Dealing-with-Protocol-Methods [Session Resumption]: #session-resumption [Stream]: stream.md#stream [TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS @@ -2556,8 +2556,8 @@ added: v0.11.3 [`Duplex`]: stream.md#class-streamduplex [`NODE_EXTRA_CA_CERTS`]: cli.md#node_extra_ca_certsfile [`NODE_OPTIONS`]: cli.md#node_optionsoptions -[`SSL_export_keying_material`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_export_keying_material.html -[`SSL_get_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html +[`SSL_export_keying_material`]: https://www.openssl.org/docs/man3.0/man3/SSL_export_keying_material.html +[`SSL_get_version`]: https://www.openssl.org/docs/man3.0/man3/SSL_get_version.html [`crypto.getCurves()`]: crypto.md#cryptogetcurves [`import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [`net.Server.address()`]: net.md#serveraddress @@ -2591,6 +2591,6 @@ added: v0.11.3 [`x509.checkHost()`]: crypto.md#x509checkhostname-options [asn1.js]: https://www.npmjs.com/package/asn1.js [certificate object]: #certificate-object -[cipher list format]: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html#CIPHER-LIST-FORMAT +[cipher list format]: https://www.openssl.org/docs/man3.0/man1/ciphers.html#CIPHER-LIST-FORMAT [forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy [perfect forward secrecy]: #perfect-forward-secrecy diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 12d21ae05e73a9..2d11a9b1505c20 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -119,15 +119,15 @@ WICG proposal: Algorithms: -* `'AES-OCB'`[^openssl30] +* `'AES-OCB'`[^noboringssl] * `'Argon2d'`[^openssl32] * `'Argon2i'`[^openssl32] * `'Argon2id'`[^openssl32] * `'ChaCha20-Poly1305'` * `'cSHAKE128'` * `'cSHAKE256'` -* `'KMAC128'`[^openssl30] -* `'KMAC256'`[^openssl30] +* `'KMAC128'`[^noboringssl] +* `'KMAC256'`[^noboringssl] * `'KT128'` * `'KT256'` * `'ML-DSA-44'`[^openssl35] @@ -2715,7 +2715,7 @@ added: [^modern-algos]: See [Modern Algorithms in the Web Cryptography API][] -[^openssl30]: Requires OpenSSL >= 3.0 +[^noboringssl]: Not available when Node.js is built against BoringSSL [^openssl32]: Requires OpenSSL >= 3.2 diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 116f0c28681816..cbb6654f2d90d8 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -191,7 +191,7 @@ }, "enable-fips": { "type": "boolean", - "description": "enable FIPS crypto at startup" + "description": "require an active OpenSSL FIPS provider at startup" }, "enable-source-maps": { "type": "boolean", @@ -284,10 +284,6 @@ "type": "boolean", "description": "disable loading non-context-aware addons" }, - "force-fips": { - "type": "boolean", - "description": "force FIPS crypto (cannot be disabled)" - }, "force-node-api-uncaught-exceptions-policy": { "type": "boolean", "description": "enforces 'uncaughtException' event on Node API asynchronous callbacks" diff --git a/doc/node.1 b/doc/node.1 index cc51fde7661ac3..72f4fb62328bbc 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -834,10 +834,6 @@ if (globalThis.gc) { .It Fl -force-context-aware Disable loading native addons that are not context-aware. . -.It Fl -force-fips -Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.) -(Same requirements as \fB--enable-fips\fR.) -. .It Fl -force-node-api-uncaught-exceptions-policy Enforces \fBuncaughtException\fR event on Node-API asynchronous callbacks. To prevent from an existing add-on from crashing the process, this flag is not @@ -1993,8 +1989,6 @@ one is included in the list below. .It \fB--force-context-aware\fR .It -\fB--force-fips\fR -.It \fB--force-node-api-uncaught-exceptions-policy\fR .It \fB--frozen-intrinsics\fR @@ -2345,8 +2339,8 @@ environment variable is arbitrary. . .It Ev OPENSSL_CONF Ar file Load an OpenSSL configuration file on startup. Among other uses, this can be -used to enable FIPS-compliant crypto if Node.js is built with -\fB./configure --openssl-fips\fR. +used to enable FIPS-compliant crypto if Node.js is built against +FIPS-enabled OpenSSL. If the \fB--openssl-config\fR command-line option is used, the environment variable is ignored. . diff --git a/lib/crypto.js b/lib/crypto.js index ac4b0a33efb8ab..fd6405740b5a4a 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -35,15 +35,10 @@ const { } = require('internal/util'); assertCrypto(); -const { - ERR_CRYPTO_FIPS_FORCED, - ERR_WORKER_UNSUPPORTED_OPERATION, -} = require('internal/errors').codes; const constants = internalBinding('constants').crypto; const { getOptionValue } = require('internal/options'); const { getFipsCrypto, - setFipsCrypto, timingSafeEqual, } = internalBinding('crypto'); const { @@ -134,12 +129,6 @@ function lazyWebCrypto() { return webcrypto; } -let ownsProcessState; -function lazyOwnsProcessState() { - ownsProcessState ??= require('internal/worker').ownsProcessState; - return ownsProcessState; -} - // These helper functions are needed because the constructors can // use new, in which case V8 cannot inline the recursive constructor call function createHash(algorithm, options) { @@ -228,7 +217,6 @@ module.exports = { setEngine, timingSafeEqual, getFips, - setFips, verify: verifyOneShot, hash, encapsulate, @@ -251,19 +239,7 @@ module.exports = { }; function getFips() { - return getOptionValue('--force-fips') ? 1 : getFipsCrypto(); -} - -function setFips(val) { - if (getOptionValue('--force-fips')) { - if (val) return; - throw new ERR_CRYPTO_FIPS_FORCED(); - } else { - if (!lazyOwnsProcessState()) { - throw new ERR_WORKER_UNSUPPORTED_OPERATION('Calling crypto.setFips()'); - } - setFipsCrypto(val); - } + return getFipsCrypto(); } function getRandomValues(array) { @@ -340,13 +316,6 @@ function getRandomBytesAlias(key) { } ObjectDefineProperties(module.exports, { - fips: { - __proto__: null, - get: deprecate(getFips, 'The crypto.fips is deprecated. ' + - 'Please use crypto.getFips()', 'DEP0093'), - set: deprecate(setFips, 'The crypto.fips is deprecated. ' + - 'Please use crypto.setFips()', 'DEP0093'), - }, constants: { __proto__: null, configurable: false, diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 1b5487849169cb..d0e6761b9e355b 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1175,10 +1175,6 @@ E('ERR_CRYPTO_ECDH_INVALID_FORMAT', 'Invalid ECDH format: %s', TypeError); E('ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY', 'Public key is not valid for specified curve', Error); E('ERR_CRYPTO_ENGINE_UNKNOWN', 'Engine "%s" was not found', Error); -E('ERR_CRYPTO_FIPS_FORCED', - 'Cannot set FIPS mode, it was forced with --force-fips at startup.', Error); -E('ERR_CRYPTO_FIPS_UNAVAILABLE', 'Cannot set FIPS mode in a non-FIPS build.', - Error); E('ERR_CRYPTO_HASH_FINALIZED', 'Digest already called', Error); E('ERR_CRYPTO_HASH_UPDATE_FAILED', 'Hash update failed', Error); E('ERR_CRYPTO_INCOMPATIBLE_KEY', 'Incompatible %s: %s', Error); diff --git a/node.gyp b/node.gyp index e88bac122b93d4..9a3691388360a1 100644 --- a/node.gyp +++ b/node.gyp @@ -790,87 +790,22 @@ ] }], - ['node_fipsinstall=="true"', { - 'variables': { - 'openssl-cli': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)openssl-cli<(EXECUTABLE_SUFFIX)', - 'provider_name': 'libopenssl-fipsmodule', - 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', - 'conditions': [ - ['GENERATOR == "ninja"', { - 'fipsmodule_internal': '<(PRODUCT_DIR)/lib/<(provider_name).so', - 'fipsmodule': '<(PRODUCT_DIR)/obj/lib/openssl-modules/fips.so', - 'fipsconfig': '<(PRODUCT_DIR)/obj/lib/fipsmodule.cnf', - 'opensslconfig_internal': '<(PRODUCT_DIR)/obj/lib/openssl.cnf', - }, { - 'fipsmodule_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/<(provider_name).so', - 'fipsmodule': '<(PRODUCT_DIR)/obj.target/deps/openssl/lib/openssl-modules/fips.so', - 'fipsconfig': '<(PRODUCT_DIR)/obj.target/deps/openssl/fipsmodule.cnf', - 'opensslconfig_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/openssl.cnf', - }], - ], - }, - 'actions': [ - { - 'action_name': 'fipsinstall', - 'process_outputs_as_sources': 1, - 'inputs': [ - '<(fipsmodule_internal)', - ], - 'outputs': [ - '<(fipsconfig)', - ], - 'action': [ - '<(openssl-cli)', 'fipsinstall', - '-provider_name', '<(provider_name)', - '-module', '<(fipsmodule_internal)', - '-out', '<(fipsconfig)', - #'-quiet', - ], - }, - { - 'action_name': 'copy_fips_module', - 'inputs': [ - '<(fipsmodule_internal)', - ], - 'outputs': [ - '<(fipsmodule)', - ], - 'action': [ - '<(python)', 'tools/copyfile.py', - '<(fipsmodule_internal)', - '<(fipsmodule)', - ], - }, - { - 'action_name': 'copy_openssl_cnf_and_include_fips_cnf', - 'inputs': [ '<(opensslconfig)', ], - 'outputs': [ '<(opensslconfig_internal)', ], - 'action': [ - '<(python)', 'tools/enable_fips_include.py', - '<(opensslconfig)', - '<(opensslconfig_internal)', - '<(fipsconfig)', - ], - }, + ], + 'variables': { + 'opensslconfig_internal': '<(obj_dir)/deps/openssl/openssl.cnf', + 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', + }, + 'actions': [ + { + 'action_name': 'reset_openssl_cnf', + 'inputs': [ '<(opensslconfig)', ], + 'outputs': [ '<(opensslconfig_internal)', ], + 'action': [ + '<(python)', 'tools/copyfile.py', + '<(opensslconfig)', + '<(opensslconfig_internal)', ], - }, { - 'variables': { - 'opensslconfig_internal': '<(obj_dir)/deps/openssl/openssl.cnf', - 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', - }, - 'actions': [ - { - 'action_name': 'reset_openssl_cnf', - 'inputs': [ '<(opensslconfig)', ], - 'outputs': [ '<(opensslconfig_internal)', ], - 'action': [ - '<(python)', 'tools/copyfile.py', - '<(opensslconfig)', - '<(opensslconfig_internal)', - ], - }, - ], - }], + }, ], }, # node_core_target_name { @@ -1053,7 +988,7 @@ ], }, 'conditions': [ - ['openssl_is_fips!=""', { + ['openssl_is_fips=="true"', { 'variables': { 'mkssldef_flags': ['-DOPENSSL_FIPS'] }, }], ], diff --git a/src/crypto/README.md b/src/crypto/README.md index cc5093a385cad3..aae3c3b74080f6 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -96,8 +96,8 @@ using CipherCtxPointer = DeleteFnPtr; Examples of these being used are pervasive through the `src/crypto` code. `HMACCtxPointer` is a dedicated HMAC state wrapper rather than a plain -`DeleteFnPtr` alias. On OpenSSL 3 and later it owns the provider-backed -`EVP_MAC`/`EVP_MAC_CTX` state. On OpenSSL 1.1.1 and BoringSSL it owns the +`DeleteFnPtr` alias. On OpenSSL it owns the provider-backed +`EVP_MAC`/`EVP_MAC_CTX` state. On BoringSSL it owns the legacy `HMAC_CTX` state. HMAC call sites should use `HMACCtxPointer::New()`, `init()`, `update()`, and `digest()`/`digestInto()` so the backend selection stays contained in ncrypto. diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index a165e8e3409d6f..759c2dfd883a39 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -719,8 +719,8 @@ bool CipherBase::Final(std::unique_ptr* out) { static_cast(ctx_.getBlockSize()), BackingStoreInitializationMode::kUninitialized); -#if !OPENSSL_VERSION_PREREQ(3, 0) - // OpenSSL v1.x doesn't verify the presence of the auth tag so do +#ifdef OPENSSL_IS_BORINGSSL + // BoringSSL doesn't verify the presence of the auth tag so do // it ourselves, see https://github.com/nodejs/node/issues/45874. if (kind_ == kDecipher && ctx_.isChaCha20Poly1305() && auth_tag_state_ != kAuthTagSetByUser) { diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 5447de596f98ec..aff44b56f4e5f8 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1645,7 +1645,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.) SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2); SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_ALLOW_CLIENT_RENEGOTIATION); #endif @@ -2361,7 +2361,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { // TODO(@jasnell): Should this use ThrowCryptoError? unsigned long err = ERR_get_error(); // NOLINT(runtime/int) -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { // OpenSSL's "unsupported" error without any context is very // common and not very helpful, so we override it: diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index a824e4e0ce90d2..4975dc54228c8c 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -92,20 +92,14 @@ MaybeLocal DataPointerToBuffer(Environment* env, DataPointer&& data) { void PutDhError(int reason) { #ifdef OPENSSL_IS_BORINGSSL OPENSSL_PUT_ERROR(DH, reason); -#elif NCRYPTO_USE_OPENSSL3_PROVIDER - ERR_raise(ERR_LIB_DH, reason); #else - ERR_put_error(ERR_LIB_DH, 0, reason, __FILE__, __LINE__); + ERR_raise(ERR_LIB_DH, reason); #endif } -#if defined(OPENSSL_IS_BORINGSSL) || !NCRYPTO_USE_OPENSSL3_PROVIDER -void PutBnError(int reason) { #ifdef OPENSSL_IS_BORINGSSL +void PutBnError(int reason) { OPENSSL_PUT_ERROR(BN, reason); -#else - ERR_put_error(ERR_LIB_BN, 0, reason, __FILE__, __LINE__); -#endif } #endif @@ -134,11 +128,7 @@ void New(const FunctionCallbackInfo& args) { int32_t bits = args[0].As()->Value(); if (bits < 2) { #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 PutDhError(DH_R_MODULUS_TOO_SMALL); -#else - PutBnError(BN_R_BITS_TOO_SMALL); -#endif // OPENSSL_VERSION_MAJOR >= 3 #else // OPENSSL_IS_BORINGSSL PutBnError(BN_R_BITS_TOO_SMALL); #endif // OPENSSL_IS_BORINGSSL diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index aaa3fee58c35b4..8168dd20fccadf 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -79,7 +79,7 @@ constexpr BoringSSLDigest kBoringSSLDigests[] = { }; #endif -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL void PushAliases(const char* name, void* data) { static_cast*>(data)->push_back(name); } @@ -155,7 +155,7 @@ void SaveSupportedHashAlgorithms(const EVP_MD* md, Environment* env = static_cast(arg); env->supported_hash_algorithms.push_back(from); } -#endif // OPENSSL_VERSION_MAJOR >= 3 +#endif // !OPENSSL_IS_BORINGSSL const std::vector& GetSupportedHashAlgorithms(Environment* env) { if (env->supported_hash_algorithms.empty()) { @@ -165,7 +165,7 @@ const std::vector& GetSupportedHashAlgorithms(Environment* env) { static_cast(digest.get); env->supported_hash_algorithms.emplace_back(digest.name); } -#elif OPENSSL_VERSION_MAJOR >= 3 +#elif !defined(OPENSSL_IS_BORINGSSL) // Since we'll fetch the EVP_MD*, cache them along the way to speed up // later lookups instead of throwing them away immediately. EVP_MD_do_all_sorted(SaveSupportedHashAlgorithmsAndCacheMD, env); @@ -194,7 +194,7 @@ void Hash::GetCachedAliases(const FunctionCallbackInfo& args) { size_t size = env->alias_to_md_id_map.size(); LocalVector names(isolate); LocalVector values(isolate); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL names.reserve(size); values.reserve(size); for (auto& [alias, id] : env->alias_to_md_id_map) { @@ -218,7 +218,7 @@ const EVP_MD* GetDigestImplementation(Environment* env, CHECK(cache_id_val->IsInt32()); CHECK(algorithm_cache->IsObject()); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int32_t cache_id = cache_id_val.As()->Value(); if (cache_id != -1) { // Alias already cached, return the cached EVP_MD*. return GetCachedMDByID(env, cache_id); @@ -266,7 +266,7 @@ void MarkInvalidXofLength() { // version-independent. #if !OPENSSL_VERSION_PREREQ(3, 4) bool IsShakeDigest(const EVP_MD* md) { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL return EVP_MD_is_a(md, "SHAKE128") || EVP_MD_is_a(md, "SHAKE256"); #else const char* name = OBJ_nid2sn(EVP_MD_type(md)); diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 1404390f4bc8bc..08e63acc3ffde4 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -1230,7 +1230,7 @@ void KeyObjectHandle::Equals(const FunctionCallbackInfo& args) { case kKeyTypePrivate: { EVP_PKEY* pkey = key.GetAsymmetricKey().get(); EVP_PKEY* pkey2 = key2.GetAsymmetricKey().get(); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int ok = EVP_PKEY_eq(pkey, pkey2); #else int ok = EVP_PKEY_cmp(pkey, pkey2); diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index ce44ad15fa79d3..d12853b5a5e62a 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -82,7 +82,7 @@ namespace { // that the user user Connection::VerifyError after the `secure` // callback has been made. int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) { - // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb: + // From https://www.openssl.org/docs/man3.0/man3/SSL_verify_cb: // // If VerifyCallback returns 1, the verification process is continued. If // VerifyCallback always returns 1, the TLS/SSL handshake will not be diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 711984e5e4f23f..da70d6d8d716e4 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -14,7 +14,7 @@ #include "math.h" -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include "openssl/provider.h" #endif @@ -81,20 +81,24 @@ int NoPasswordCallback(char* buf, int size, int rwflag, void* u) { return 0; } -bool ProcessFipsOptions() { - /* Override FIPS settings in configuration file, if needed. */ - if (per_process::cli_options->enable_fips_crypto || - per_process::cli_options->force_fips_crypto) { -#if OPENSSL_VERSION_MAJOR >= 3 - if (!ncrypto::testFipsEnabled()) return false; - return ncrypto::setFipsEnabled(true, nullptr); -#else - // TODO(@jasnell): Remove this ifdef branch when openssl 1.1.1 is - // no longer supported. - if (FIPS_mode() == 0) return FIPS_mode_set(1); -#endif +std::optional ProcessFipsOptions() { + if (!per_process::cli_options->enable_fips_crypto) return std::nullopt; + + // Whether FIPS-approved implementations are reachable is decided by the + // OpenSSL configuration, not by Node.js. Refuse to start rather than + // restrict the default property query to a provider that is not there, + // which would leave every operation failing as unsupported. + if (!ncrypto::testFipsEnabled()) { + return "--enable-fips requires an active OpenSSL provider named \"fips\". " + "FIPS mode is configured through OpenSSL; see " + "https://nodejs.org/api/crypto.html#fips-mode"; } - return true; + + if (!ncrypto::setFipsEnabled()) { + return "OpenSSL error when trying to enable FIPS"; + } + + return std::nullopt; } bool InitCryptoOnce(Isolate* isolate) { @@ -118,15 +122,6 @@ void InitCryptoOnce() { #ifndef OPENSSL_IS_BORINGSSL OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); -#if OPENSSL_VERSION_MAJOR < 3 - // --openssl-config=... - if (!per_process::cli_options->openssl_config.empty()) { - const char* conf = per_process::cli_options->openssl_config.c_str(); - OPENSSL_INIT_set_config_filename(settings, conf); - } -#endif - -#if OPENSSL_VERSION_MAJOR >= 3 // --openssl-legacy-provider if (per_process::cli_options->openssl_legacy_provider) { OSSL_PROVIDER* legacy_provider = OSSL_PROVIDER_load(nullptr, "legacy"); @@ -134,7 +129,6 @@ void InitCryptoOnce() { fprintf(stderr, "Unable to load legacy provider.\n"); } } -#endif OPENSSL_init_ssl(0, settings); @@ -193,24 +187,6 @@ void GetFipsCrypto(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(ncrypto::isFipsEnabled() ? 1 : 0); } -void SetFipsCrypto(const FunctionCallbackInfo& args) { - Mutex::ScopedLock lock(per_process::cli_options_mutex); - Mutex::ScopedLock fips_lock(fips_mutex); - - CHECK(!per_process::cli_options->force_fips_crypto); - Environment* env = Environment::GetCurrent(args); - CHECK(env->owns_process_state()); - bool enable = args[0]->BooleanValue(env->isolate()); - - CryptoErrorList errors; - if (!ncrypto::setFipsEnabled(enable, &errors)) { - Local exception; - if (cryptoErrorListToException(env, errors).ToLocal(&exception)) { - env->isolate()->ThrowException(exception); - } - } -} - void TestFipsCrypto(const v8::FunctionCallbackInfo& args) { Mutex::ScopedLock lock(per_process::cli_options_mutex); Mutex::ScopedLock fips_lock(fips_mutex); @@ -857,7 +833,6 @@ void Initialize(Environment* env, Local target) { #endif // !OPENSSL_NO_ENGINE SetMethodNoSideEffect(context, target, "getFipsCrypto", GetFipsCrypto); - SetMethod(context, target, "setFipsCrypto", SetFipsCrypto); SetMethodNoSideEffect(context, target, "testFipsCrypto", TestFipsCrypto); NODE_DEFINE_CONSTANT(target, kCryptoJobAsync); @@ -876,7 +851,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { #endif // !OPENSSL_NO_ENGINE registry->Register(GetFipsCrypto); - registry->Register(SetFipsCrypto); registry->Register(TestFipsCrypto); registry->Register(SecureBuffer); registry->Register(SecureHeapUsed); diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index c27b745ce83c8e..5f45cab022ffa5 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -48,7 +48,10 @@ constexpr T NumBitsToBytes(T bits) { return (bits / CHAR_BIT) + ((CHAR_BIT - 1 + (bits % CHAR_BIT)) / CHAR_BIT); } -bool ProcessFipsOptions(); +// Applies the FIPS related command line options. Returns a description of +// what went wrong, or std::nullopt when there was nothing to do or the +// options were applied successfully. +std::optional ProcessFipsOptions(); bool InitCryptoOnce(v8::Isolate* isolate); void InitCryptoOnce(); diff --git a/src/env.h b/src/env.h index c2caf979023811..1922763724c9f4 100644 --- a/src/env.h +++ b/src/env.h @@ -1069,11 +1069,11 @@ class Environment final : public MemoryRetainer { }; #if HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // We declare another alias here to avoid having to include crypto_util.h using EVPMDPointer = DeleteFnPtr; std::vector evp_md_cache; -#endif // OPENSSL_VERSION_MAJOR >= 3 +#endif // !OPENSSL_IS_BORINGSSL std::unordered_map alias_to_md_id_map; std::vector supported_hash_algorithms; #endif // HAVE_OPENSSL diff --git a/src/node.cc b/src/node.cc index b368c58734345f..f680ab67b31d00 100644 --- a/src/node.cc +++ b/src/node.cc @@ -50,7 +50,7 @@ #if HAVE_OPENSSL #include "ncrypto.h" #include "node_crypto.h" -#if OPENSSL_VERSION_MAJOR >= 3 && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE) +#if !defined(OPENSSL_IS_BORINGSSL) && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE) // OpenSSL hides this deprecated macro under OPENSSL_NO_DEPRECATED, but the // non-deprecated OPENSSL_INIT settings API still accepts the flag value. #define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 @@ -1183,7 +1183,7 @@ InitializeOncePerProcessInternal(const std::vector& args, // In the case of FIPS builds we should make sure // the random source is properly initialized first. -#if OPENSSL_VERSION_MAJOR >= 3 + // // Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to // avoid the default behavior where errors raised during the parsing of the // OpenSSL configuration file are not propagated and cannot be detected. @@ -1239,17 +1239,17 @@ InitializeOncePerProcessInternal(const std::vector& args, GetOpenSSLErrorString()); return result; } -#else // OPENSSL_VERSION_MAJOR < 3 - if (FIPS_mode()) { - OPENSSL_init(); - } -#endif - if (!crypto::ProcessFipsOptions()) { + + if (auto fips_error = crypto::ProcessFipsOptions()) { result->exit_code_ = ExitCode::kGenericUserError; result->early_return_ = true; - result->errors_.emplace_back( - "OpenSSL error when trying to enable FIPS:\n" + - GetOpenSSLErrorString()); + // The error queue is empty when the failure was detected by Node.js + // rather than reported by OpenSSL, in which case appending it would + // produce a message that trails off into nothing. + std::string openssl_errors = GetOpenSSLErrorString(); + result->errors_.emplace_back(openssl_errors.empty() + ? *fips_error + : *fips_error + ":\n" + openssl_errors); return result; } diff --git a/src/node_config.cc b/src/node_config.cc index 7245d9130d0365..2de1ee244ddb13 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -64,8 +64,6 @@ static void InitConfig(Local target, READONLY_FALSE_PROPERTY(target, "hasOpenSSL"); #endif // HAVE_OPENSSL - READONLY_TRUE_PROPERTY(target, "fipsMode"); - #ifdef NODE_HAVE_I18N_SUPPORT READONLY_TRUE_PROPERTY(target, "hasIntl"); diff --git a/src/node_constants.cc b/src/node_constants.cc index db670789dc063a..c06324204b4e13 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -57,7 +57,7 @@ #if !defined(RSA_PKCS1_PSS_PADDING) #define RSA_PKCS1_PSS_PADDING 6 #endif -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // OpenSSL hides these deprecated DH check constants under // OPENSSL_NO_DEPRECATED, but the numeric verifyError values remain public API. #if !defined(DH_CHECK_P_NOT_PRIME) @@ -74,7 +74,7 @@ #endif #endif #ifndef OPENSSL_NO_ENGINE -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // Engine constants remain public API while engine implementation lives in the // dedicated compatibility target. #define ENGINE_METHOD_RSA (unsigned int)0x0001 diff --git a/src/node_constants.h b/src/node_constants.h index 97429c0e5e9462..115de09587d31e 100644 --- a/src/node_constants.h +++ b/src/node_constants.h @@ -48,7 +48,7 @@ #define DEFAULT_CIPHER_LIST_CORE NODE_OPENSSL_DEFAULT_CIPHER_LIST #else // TLSv1.3 suites start with TLS_, and are the OpenSSL defaults, see: -// https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_ciphersuites.html +// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_ciphersuites.html #define DEFAULT_CIPHER_LIST_CORE \ "TLS_AES_256_GCM_SHA384:" \ "TLS_CHACHA20_POLY1305_SHA256:" \ diff --git a/src/node_metadata.cc b/src/node_metadata.cc index b91b1b4881489a..68daae837fc1fb 100644 --- a/src/node_metadata.cc +++ b/src/node_metadata.cc @@ -68,7 +68,7 @@ static constexpr size_t search(const char* s, char c, size_t n = 0) { static inline std::string GetOpenSSLVersion() { // sample openssl version string format - // for reference: "OpenSSL 1.1.0i 14 Aug 2018" + // for reference: "OpenSSL 3.5.7 9 Jun 2026" const char* version = OpenSSL_version(OPENSSL_VERSION); const size_t first_space = search(version, ' '); diff --git a/src/node_options.cc b/src/node_options.cc index b9d3dd56092e35..3d9e1bb2258ab2 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1471,13 +1471,9 @@ PerProcessOptionsParser::PerProcessOptionsParser( Implies("--use-openssl-ca", "[ssl_openssl_cert_store]"); ImpliesNot("--use-bundled-ca", "[ssl_openssl_cert_store]"); AddOption("--enable-fips", - "enable FIPS crypto at startup", + "require an active OpenSSL FIPS provider at startup", &PerProcessOptions::enable_fips_crypto, kAllowedInEnvvar); - AddOption("--force-fips", - "force FIPS crypto (cannot be disabled)", - &PerProcessOptions::force_fips_crypto, - kAllowedInEnvvar); #ifndef V8_ENABLE_SANDBOX AddOption("--secure-heap", "total size of the OpenSSL secure heap", @@ -1489,7 +1485,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( kAllowedInEnvvar); #endif // V8_ENABLE_SANDBOX #endif // HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) AddOption("--openssl-legacy-provider", "enable OpenSSL 3.0 legacy provider", &PerProcessOptions::openssl_legacy_provider, @@ -1499,7 +1495,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( &PerProcessOptions::openssl_shared_config, kAllowedInEnvvar); -#endif // OPENSSL_VERSION_MAJOR +#endif // HAVE_OPENSSL && !OPENSSL_IS_BORINGSSL AddOption("--use-largepages", "Map the Node.js static code to large pages. Options are " "'off' (the default value, meaning do not map), " diff --git a/src/node_options.h b/src/node_options.h index 7d9ff9e5147d18..2a89d6a063ae87 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -376,9 +376,8 @@ class PerProcessOptions : public Options { bool use_openssl_ca = false; bool use_bundled_ca = false; bool enable_fips_crypto = false; - bool force_fips_crypto = false; #endif -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) bool openssl_legacy_provider = false; bool openssl_shared_config = false; #endif diff --git a/test/addons/openssl-providers/binding.cc b/test/addons/openssl-providers/binding.cc index 785a103bb6c6c7..36f8de59ccd93f 100644 --- a/test/addons/openssl-providers/binding.cc +++ b/test/addons/openssl-providers/binding.cc @@ -1,8 +1,9 @@ #include #include -#include -#if OPENSSL_VERSION_MAJOR >= 3 +// BoringSSL declares OPENSSL_IS_BORINGSSL in crypto.h. +#include +#ifndef OPENSSL_IS_BORINGSSL #include #endif @@ -18,7 +19,7 @@ using v8::Object; using v8::String; using v8::Value; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int collectProviders(OSSL_PROVIDER* provider, void* cbdata) { static_cast*>(cbdata)->push_back(provider); return 1; @@ -28,7 +29,7 @@ int collectProviders(OSSL_PROVIDER* provider, void* cbdata) { inline void GetProviders(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); LocalVector arr(isolate, 0); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL std::vector providers; OSSL_PROVIDER_do_all(nullptr, &collectProviders, &providers); for (auto provider : providers) { diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index fddf584d7d41f7..a0cbbc1fbb42f2 100644 --- a/test/cctest/test_node_crypto_env.cc +++ b/test/cctest/test_node_crypto_env.cc @@ -26,7 +26,7 @@ TEST_F(NodeCryptoEnv, LoadBIO) { // just put a random string into BIO Local key = String::NewFromUtf8(isolate_, "abcdef").ToLocalChecked(); ncrypto::BIOPointer bio(node::crypto::LoadBIO(*env, key)); -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifndef OPENSSL_IS_BORINGSSL const int ofs = 2; ASSERT_EQ(BIO_seek(bio.get(), ofs), ofs); ASSERT_EQ(BIO_tell(bio.get()), ofs); diff --git a/test/fixtures/openssl_fips_disabled.cnf b/test/fixtures/openssl_fips_disabled.cnf deleted file mode 100644 index 253c6906e3f3a3..00000000000000 --- a/test/fixtures/openssl_fips_disabled.cnf +++ /dev/null @@ -1,12 +0,0 @@ -# Skeleton openssl.cnf for testing with FIPS - -nodejs_conf = openssl_conf_section -authorityKeyIdentifier=keyid:always,issuer:always - -[openssl_conf_section] - # Configuration module list -alg_section = evp_sect - -[ evp_sect ] -# Set to "yes" to enter FIPS mode if supported -fips_mode = no diff --git a/test/fixtures/openssl_fips_enabled.cnf b/test/fixtures/openssl_fips_enabled.cnf deleted file mode 100644 index 79733c657a96d0..00000000000000 --- a/test/fixtures/openssl_fips_enabled.cnf +++ /dev/null @@ -1,12 +0,0 @@ -# Skeleton openssl.cnf for testing with FIPS - -nodejs_conf = openssl_conf_section -authorityKeyIdentifier=keyid:always,issuer:always - -[openssl_conf_section] - # Configuration module list -alg_section = evp_sect - -[ evp_sect ] -# Set to "yes" to enter FIPS mode if supported -fips_mode = yes diff --git a/test/parallel/test-cli-node-print-help.js b/test/parallel/test-cli-node-print-help.js index f42129eb133026..3e56f0bbdaad1c 100644 --- a/test/parallel/test-cli-node-print-help.js +++ b/test/parallel/test-cli-node-print-help.js @@ -27,7 +27,7 @@ function validateNodePrintHelp() { { compileConstant: HAVE_OPENSSL, flags: [ '--openssl-config=...', '--tls-cipher-list=...', '--use-bundled-ca', '--use-openssl-ca', '--use-system-ca', - '--enable-fips', '--force-fips' ] }, + '--enable-fips' ] }, { compileConstant: NODE_HAVE_I18N_SUPPORT, flags: [ '--icu-data-dir=...', 'NODE_ICU_DATA' ] }, { compileConstant: HAVE_INSPECTOR, diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js deleted file mode 100644 index 06c88272438a05..00000000000000 --- a/test/parallel/test-crypto-ecb.js +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -if (!common.hasCrypto) { - common.skip('missing crypto'); -} - -const { hasOpenSSL3 } = require('../common/crypto'); -const crypto = require('crypto'); - -if (crypto.getFips()) { - common.skip('BF-ECB is not FIPS 140-2 compatible'); -} - -if (hasOpenSSL3) { - common.skip('Blowfish is only available with the legacy provider in ' + - 'OpenSSl 3.x'); -} - -if (!crypto.getCiphers().includes('BF-ECB')) { - common.skip('BF-ECB cipher is not available'); -} - -const assert = require('assert'); - -// Testing whether EVP_CipherInit_ex is functioning correctly. -// Reference: bug#1997 - -{ - const encrypt = - crypto.createCipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); - let hex = encrypt.update('Hello World!', 'ascii', 'hex'); - hex += encrypt.final('hex'); - assert.strictEqual(hex.toUpperCase(), '6D385F424AAB0CFBF0BB86E07FFB7D71'); -} - -{ - const decrypt = - crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); - let msg = decrypt.update('6D385F424AAB0CFBF0BB86E07FFB7D71', 'hex', 'ascii'); - msg += decrypt.final('ascii'); - assert.strictEqual(msg, 'Hello World!'); -} diff --git a/test/parallel/test-crypto-fips.js b/test/parallel/test-crypto-fips.js index 04a95fa5fd37c9..53a5552ed0913c 100644 --- a/test/parallel/test-crypto-fips.js +++ b/test/parallel/test-crypto-fips.js @@ -8,27 +8,24 @@ if (process.features.openssl_is_boringssl) common.skip('BoringSSL does not support FIPS'); const assert = require('assert'); +const crypto = require('crypto'); const spawnSync = require('child_process').spawnSync; const path = require('path'); -const fixtures = require('../common/fixtures'); const { internalBinding } = require('internal/test/binding'); const { testFipsCrypto } = internalBinding('crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); const FIPS_ENABLED = 1; const FIPS_DISABLED = 0; -const FIPS_ERROR_STRING2 = - 'Error [ERR_CRYPTO_FIPS_FORCED]: Cannot set FIPS mode, it was forced with ' + - '--force-fips at startup.'; -const FIPS_UNSUPPORTED_ERROR_STRING = 'fips mode not supported'; -const FIPS_ENABLE_ERROR_STRING = 'OpenSSL error when trying to enable FIPS:'; - -const CNF_FIPS_ON = fixtures.path('openssl_fips_enabled.cnf'); -const CNF_FIPS_OFF = fixtures.path('openssl_fips_disabled.cnf'); +const FIPS_ENABLE_ERROR_STRING = + '--enable-fips requires an active OpenSSL provider named "fips"'; const kNoFailure = 0; const kGenericUserError = 1; +// Whether a provider named "fips" is activated in the default library context. +// This is a runtime property of the OpenSSL configuration, not of the build. +const fipsProviderAvailable = testFipsCrypto() === 1; + let num_children_ok = 0; function sharedOpenSSL() { @@ -39,7 +36,7 @@ function testHelper(stream, args, expectedStatus, expectedOutput, cmd, env) { const fullArgs = args.concat(['-e', `console.log(${cmd})`]); const child = spawnSync(process.execPath, fullArgs, { cwd: path.dirname(process.execPath), - env: env + env: env, }); console.error( @@ -69,27 +66,35 @@ function testHelper(stream, args, expectedStatus, expectedOutput, cmd, env) { responseHandler(child[stream], expectedOutput); } -// --enable-fips should raise an error if OpenSSL is not FIPS enabled. +// There is no way to enter or leave FIPS mode at runtime. FIPS mode is a +// property of the OpenSSL configuration, and is only asserted at startup. +assert.strictEqual(crypto.setFips, undefined); +assert.strictEqual(Object.hasOwn(crypto, 'fips'), false); + +// testFipsCrypto() reports whether a provider named "fips" is activated, so it +// is always a well-defined 0 or 1 regardless of how Node.js was built. +assert.ok(testFipsCrypto() === 1 || testFipsCrypto() === 0); + +// --enable-fips fails closed: if no FIPS provider is active it must refuse to +// start rather than leave the process in a half-configured state. testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', + fipsProviderAvailable ? 'stdout' : 'stderr', ['--enable-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_ENABLE_ERROR_STRING, - 'process.versions', + fipsProviderAvailable ? kNoFailure : kGenericUserError, + fipsProviderAvailable ? FIPS_ENABLED : FIPS_ENABLE_ERROR_STRING, + 'require("crypto").getFips()', process.env); -// --force-fips should raise an error if OpenSSL is not FIPS enabled. -testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_ENABLE_ERROR_STRING, - 'process.versions', - process.env); +// --force-fips was removed; it only existed to lock out crypto.setFips(). +{ + const child = spawnSync(process.execPath, ['--force-fips', '-p', '1'], + { encoding: 'utf8' }); + assert.notStrictEqual(child.status, 0); + assert.match(child.stderr, /bad option: --force-fips/); +} -// By default FIPS should be off in both FIPS and non-FIPS builds -// unless Node.js was configured using --shared-openssl in -// which case it may be enabled by the system. +// By default FIPS should be off, unless Node.js was configured using +// --shared-openssl in which case it may be enabled by the system. if (!sharedOpenSSL()) { testHelper( 'stdout', @@ -99,212 +104,3 @@ if (!sharedOpenSSL()) { 'require("crypto").getFips()', { ...process.env, 'OPENSSL_CONF': ' ' }); } - -// Toggling fips with setFips should not be allowed from a worker thread -testHelper( - 'stderr', - [], - kGenericUserError, - 'Calling crypto.setFips() is not supported in workers', - 'new worker_threads.Worker(\'require("crypto").setFips(true);\', { eval: true })', - process.env); - -// This should succeed for both FIPS and non-FIPS builds in combination with -// OpenSSL 1.1.1 or OpenSSL 3.0 -const test_result = testFipsCrypto(); -assert.ok(test_result === 1 || test_result === 0); - -// If Node was configured using --shared-openssl fips support might be -// available depending on how OpenSSL was built. If fips support is -// available the tests that toggle the fips_mode on/off using the config -// file option will succeed and return 1 instead of 0. -// -// Note that this case is different from when calling the fips setter as the -// configuration file is handled by OpenSSL, so it is not possible for us -// to try to call the fips setter, to try to detect this situation, as -// that would throw an error: -// ("Error: Cannot set FIPS mode in a non-FIPS build."). -// Due to this uncertainty the following tests are skipped when configured -// with --shared-openssl. -if (!sharedOpenSSL() && !hasOpenSSL3) { - // OpenSSL config file should be able to turn on FIPS mode - testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_ON}`], - kNoFailure, - testFipsCrypto() ? FIPS_ENABLED : FIPS_DISABLED, - 'require("crypto").getFips()', - process.env); - - // OPENSSL_CONF should be able to turn on FIPS mode - testHelper( - 'stdout', - [], - kNoFailure, - testFipsCrypto() ? FIPS_ENABLED : FIPS_DISABLED, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_ON })); - - // --openssl-config option should override OPENSSL_CONF - testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_ON}`], - kNoFailure, - testFipsCrypto() ? FIPS_ENABLED : FIPS_DISABLED, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); -} - -// OpenSSL 3.x has changed the configuration files so the following tests -// will not work as expected with that version. -// TODO(danbev) Revisit these test once FIPS support is available in -// OpenSSL 3.x. -if (!hasOpenSSL3) { - testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_OFF}`], - kNoFailure, - FIPS_DISABLED, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_ON })); - - // --enable-fips should take precedence over OpenSSL config file - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips', `--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); - // --force-fips should take precedence over OpenSSL config file - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips', `--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); - // --enable-fips should turn FIPS mode on - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); - - // --force-fips should turn FIPS mode on - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - process.env); - - // OPENSSL_CONF should _not_ make a difference to --enable-fips - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); - - // Using OPENSSL_CONF should not make a difference to --force-fips - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").getFips()', - Object.assign({}, process.env, { 'OPENSSL_CONF': CNF_FIPS_OFF })); - - // setFipsCrypto should be able to turn FIPS mode on - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); - - // setFipsCrypto should be able to turn FIPS mode on and off - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); - - // setFipsCrypto takes precedence over OpenSSL config file, FIPS on - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - [`--openssl-config=${CNF_FIPS_OFF}`], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); - - // setFipsCrypto takes precedence over OpenSSL config file, FIPS off - testHelper( - 'stdout', - [`--openssl-config=${CNF_FIPS_ON}`], - kNoFailure, - FIPS_DISABLED, - '(require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); - - // --enable-fips does not prevent use of setFipsCrypto API - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--enable-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_DISABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(false),' + - 'require("crypto").getFips())', - process.env); - - // --force-fips prevents use of setFipsCrypto API - testHelper( - 'stderr', - ['--force-fips'], - kGenericUserError, - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); - - // --force-fips makes setFipsCrypto enable a no-op (FIPS stays on) - testHelper( - testFipsCrypto() ? 'stdout' : 'stderr', - ['--force-fips'], - testFipsCrypto() ? kNoFailure : kGenericUserError, - testFipsCrypto() ? FIPS_ENABLED : FIPS_UNSUPPORTED_ERROR_STRING, - '(require("crypto").setFips(true),' + - 'require("crypto").getFips())', - process.env); - - // --force-fips and --enable-fips order does not matter - testHelper( - 'stderr', - ['--force-fips', '--enable-fips'], - kGenericUserError, - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); - - // --enable-fips and --force-fips order does not matter - testHelper( - 'stderr', - ['--enable-fips', '--force-fips'], - kGenericUserError, - testFipsCrypto() ? FIPS_ERROR_STRING2 : FIPS_UNSUPPORTED_ERROR_STRING, - 'require("crypto").setFips(false)', - process.env); -} diff --git a/test/parallel/test-crypto-no-algorithm.js b/test/parallel/test-crypto-no-algorithm.js index 96236a976a89ef..cd72fd249406d9 100644 --- a/test/parallel/test-crypto-no-algorithm.js +++ b/test/parallel/test-crypto-no-algorithm.js @@ -4,29 +4,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); - -if (!hasOpenSSL3) - common.skip('this test requires OpenSSL 3.x'); - const assert = require('node:assert/strict'); -const crypto = require('node:crypto'); -const { isMainThread } = require('worker_threads'); - -if (isMainThread) { - // TODO(richardlau): Decide if `crypto.setFips` should error if the - // provider named "fips" is not available. - crypto.setFips(1); - crypto.randomBytes(20, common.mustCall((err) => { - // crypto.randomBytes should either succeed or fail but not hang. - if (err) { - assert.match(err.message, /digital envelope routines::unsupported/); - const expected = /random number generator::unable to fetch drbg/; - assert(err.opensslErrorStack.some((msg) => expected.test(msg)), - `did not find ${expected} in ${err.opensslErrorStack}`); - } - })); -} { // Startup test. Should not hang. diff --git a/test/parallel/test-crypto-sec-level.js b/test/parallel/test-crypto-sec-level.js index d7d2252be6c35d..3305ffb14ffd7d 100644 --- a/test/parallel/test-crypto-sec-level.js +++ b/test/parallel/test-crypto-sec-level.js @@ -11,7 +11,7 @@ const assert = require('assert'); // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour // This test simply validates that we can get some value for the secLevel // when needed by tests. const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); diff --git a/test/parallel/test-dsa-fips-invalid-key.js b/test/parallel/test-dsa-fips-invalid-key.js index 3df51bfbed3517..43ac7e22ced6a0 100644 --- a/test/parallel/test-dsa-fips-invalid-key.js +++ b/test/parallel/test-dsa-fips-invalid-key.js @@ -9,7 +9,7 @@ const fixtures = require('../common/fixtures'); const crypto = require('crypto'); if (!crypto.getFips()) { - common.skip('node compiled without FIPS OpenSSL.'); + common.skip('OpenSSL is not configured for FIPS mode'); } const assert = require('assert'); diff --git a/test/parallel/test-process-env-allowed-flags-are-documented.js b/test/parallel/test-process-env-allowed-flags-are-documented.js index 6028bbab787e29..cc3bbdb371f7c1 100644 --- a/test/parallel/test-process-env-allowed-flags-are-documented.js +++ b/test/parallel/test-process-env-allowed-flags-are-documented.js @@ -72,7 +72,6 @@ const conditionalOpts = [ '--secure-heap', '--secure-heap-min', '--enable-fips', - '--force-fips', ].includes(opt); } }, { diff --git a/test/parallel/test-process-versions.js b/test/parallel/test-process-versions.js index 14ac88d76cd24d..7b434d3e5daa45 100644 --- a/test/parallel/test-process-versions.js +++ b/test/parallel/test-process-versions.js @@ -104,18 +104,14 @@ assert.match( assert.match(process.versions.modules, /^\d+$/); if (common.hasCrypto) { - const { hasOpenSSL3 } = require('../common/crypto'); assert.match(process.versions.ncrypto, commonTemplate); if (process.config.variables.node_shared_openssl) { assert.ok(process.versions.openssl); } else { - const versionRegex = hasOpenSSL3 ? - // The following also matches a development version of OpenSSL 3.x which - // can be in the format '3.0.0-alpha4-dev'. This can be handy when - // building and linking against the main development branch of OpenSSL. - /^\d+\.\d+\.\d+(?:[-+][a-z0-9]+)*$/ : - /^\d+\.\d+\.\d+[a-z]?(\+quic)?(-fips)?$/; - assert.match(process.versions.openssl, versionRegex); + // The following also matches a development version of OpenSSL 3.x which + // can be in the format '3.0.0-alpha4-dev'. This can be handy when + // building and linking against the main development branch of OpenSSL. + assert.match(process.versions.openssl, /^\d+\.\d+\.\d+(?:[-+][a-z0-9]+)*$/); } } diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index d777a9bfa97f3f..cfdd7702eb1359 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js index 83af6daccbd0c9..66797249189fcc 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -40,7 +40,7 @@ const { // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); if (!opensslCli) { diff --git a/tools/dep_updaters/update-nixpkgs-pin.sh b/tools/dep_updaters/update-nixpkgs-pin.sh index a025676e20a7b5..ddf50433d0cbb6 100755 --- a/tools/dep_updaters/update-nixpkgs-pin.sh +++ b/tools/dep_updaters/update-nixpkgs-pin.sh @@ -45,14 +45,16 @@ update_pkgs_file "$NIXPKGS_COMPAT_PIN_FILE" "$COMPAT_VERSION_SHA1" "$COMPAT_UPST nix-instantiate -I "nixpkgs=$NIXPKGS_PIN_FILE" --eval --strict --json -E " let pkgs = import {}; - opensslAttrs = builtins.filter - (n: builtins.match \"openssl_[0-9]+(_[0-9]+)?\" n != null) - (builtins.attrNames pkgs); + isOpensslAttr = n: builtins.match \"openssl_[0-9]+(_[0-9]+)?\" n != null; + opensslAttrs = builtins.filter isOpensslAttr (builtins.attrNames pkgs); extraMatrixAttrs = [ \"boringssl\" ]; attrs = builtins.filter (n: let t = builtins.tryEval pkgs.\${n}; in t.success && (builtins.tryEval t.value.version).success + # Node.js requires OpenSSL 3 or later. BoringSSL is versioned + # independently and is not subject to this floor. + && (!isOpensslAttr n || pkgs.lib.versionAtLeast t.value.version \"3\") ) (opensslAttrs ++ extraMatrixAttrs); in diff --git a/tools/enable_fips_include.py b/tools/enable_fips_include.py deleted file mode 100644 index cb24c7d83b689b..00000000000000 --- a/tools/enable_fips_include.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2008 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import sys - -# Copy openssl.cnf into output directory -__import__('copyfile') - -# Open the copied openssl.cnf file -fin = open(sys.argv[2], "rt") -data = fin.read() -data = data.replace('# .include fipsmodule.cnf', '.include %s' % sys.argv[3]) -data = data.replace('# fips = fips_sect', 'fips = fips_sect') -data = data.replace('# activate = 1', 'activate = 1') -fin.close() -fin = open(sys.argv[2], "wt") -fin.write(data) -fin.close() diff --git a/tools/eslint-rules/crypto-check.js b/tools/eslint-rules/crypto-check.js index 10862c1b160b3b..bd79303829bff8 100644 --- a/tools/eslint-rules/crypto-check.js +++ b/tools/eslint-rules/crypto-check.js @@ -48,7 +48,7 @@ module.exports = { } function isCryptoCheck(node) { - return utils.usesCommonProperty(node, ['hasCrypto', 'hasFipsCrypto']); + return utils.usesCommonProperty(node, ['hasCrypto']); } function checkCryptoCall(node) { diff --git a/tools/nix/openssl-matrix.nix b/tools/nix/openssl-matrix.nix index 36978c5d4efcb0..45ab600df4fcd2 100644 --- a/tools/nix/openssl-matrix.nix +++ b/tools/nix/openssl-matrix.nix @@ -1,13 +1,12 @@ { pkgs ? import ./pkgs.nix { - config.permittedInsecurePackages = [ "openssl-1.1.1w" ]; + config.permittedInsecurePackages = [ ]; }, }: { inherit (pkgs) boringssl - openssl_1_1 openssl_3 openssl_3_5 openssl_3_6 diff --git a/tools/test.py b/tools/test.py index 2c2a4d78d80aea..aa8c3fbddf53f9 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1460,7 +1460,7 @@ def BuildOptions(): help='Send SIGABRT instead of SIGTERM to kill processes that time out', default=False, action="store_true", dest="abort_on_timeout") result.add_argument("--type", - help="Type of build (simple, fips, coverage)", + help="Type of build (simple, coverage)", default=None) result.add_argument("--error-reporter", help="use error reporter if the test uses node:test", @@ -1622,14 +1622,9 @@ def ArgsToTestPaths(test_root, args, suites): def get_env_type(vm, options_type, context): if options_type is not None: - env_type = options_type - else: - # 'simple' is the default value for 'env_type'. - env_type = 'simple' - ssl_ver = Execute([vm, '-p', 'process.versions.openssl'], context).stdout - if 'fips' in ssl_ver: - env_type = 'fips' - return env_type + return options_type + # 'simple' is the default value for 'env_type'. + return 'simple' def get_asan_state(vm, context): diff --git a/typings/internalBinding/config.d.ts b/typings/internalBinding/config.d.ts index 5651b391b88e35..e85f1a815a8eb9 100644 --- a/typings/internalBinding/config.d.ts +++ b/typings/internalBinding/config.d.ts @@ -2,7 +2,6 @@ export interface ConfigBinding { isDebugBuild: boolean; openSSLIsBoringSSL: boolean; hasOpenSSL: boolean; - fipsMode: boolean; hasIntl: boolean; hasSmallICU: boolean; hasTracing: boolean; diff --git a/typings/internalBinding/crypto.d.ts b/typings/internalBinding/crypto.d.ts index d91c5018ba688a..51ca77b17fd730 100644 --- a/typings/internalBinding/crypto.d.ts +++ b/typings/internalBinding/crypto.d.ts @@ -955,7 +955,6 @@ export interface CryptoBinding { secureBuffer(length: number): Uint8Array | undefined; secureHeapUsed(): bigint | undefined; setEngine?(engine: string, flags: number): void; - setFipsCrypto(fips: boolean | number): void; startLoadingCertificatesOffThread(): void; testFipsCrypto(): 0 | 1; timingSafeEqual(