diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 8a04fe4d74fc..76559c509a38 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -253,8 +253,8 @@ 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. + # release so EOL-with-extended-support cycles evaluate without relaxing + # nixpkgs' meta check globally. 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 e477d46863f4..b1accbe8962a 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. @@ -1044,14 +1042,20 @@ using the following 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. -When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL. +`./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 more information on how to -enable FIPS support in Node.js. +See [FIPS mode](doc/api/crypto.md#fips-mode) for how to configure it. ## Building Node.js with Temporal support @@ -1135,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/benchmark/crypto/create-keyobject.js b/benchmark/crypto/create-keyobject.js index 7cd6db2d567a..0a3dd56c048f 100644 --- a/benchmark/crypto/create-keyobject.js +++ b/benchmark/crypto/create-keyobject.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL } = require('../../test/common/crypto.js'); +const { hasOpenSSL, isBoringSSL } = require('../../test/common/crypto.js'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); @@ -26,7 +26,7 @@ const keyFixtures = { if (hasOpenSSL(3, 5)) { keyFixtures['ml-dsa-44'] = readKeyPair('ml_dsa_44_public', 'ml_dsa_44_private'); -} else if (process.features.openssl_is_boringssl) { +} else if (isBoringSSL()) { keyFixtures['ml-dsa-44'] = readKeyPair('ml_dsa_44_public', 'ml_dsa_44_private_seed_only'); } diff --git a/benchmark/crypto/kem.js b/benchmark/crypto/kem.js index a544fc2124af..ee23ca8cb929 100644 --- a/benchmark/crypto/kem.js +++ b/benchmark/crypto/kem.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL } = require('../../test/common/crypto.js'); +const { hasOpenSSL, isBoringSSL } = require('../../test/common/crypto.js'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); @@ -24,7 +24,7 @@ if (hasOpenSSL(3, 5)) { keyFixtures['ml-kem-512'] = readKeyPair('ml_kem_512_public', 'ml_kem_512_private'); keyFixtures['ml-kem-768'] = readKeyPair('ml_kem_768_public', 'ml_kem_768_private'); keyFixtures['ml-kem-1024'] = readKeyPair('ml_kem_1024_public', 'ml_kem_1024_private'); -} else if (process.features.openssl_is_boringssl) { +} else if (isBoringSSL()) { keyFixtures['ml-kem-768'] = readKeyPair('ml_kem_768_public', 'ml_kem_768_private_seed_only'); keyFixtures['ml-kem-1024'] = readKeyPair('ml_kem_1024_public', 'ml_kem_1024_private_seed_only'); } @@ -35,12 +35,12 @@ if (hasOpenSSL(3, 2)) { keyFixtures.x25519 = readKeyPair('x25519_public', 'x25519_private'); keyFixtures.x448 = readKeyPair('x448_public', 'x448_private'); } -if (hasOpenSSL(3, 0)) { +if (!isBoringSSL()) { keyFixtures.rsa = readKeyPair('rsa_public_2048', 'rsa_private_2048'); } if (Object.keys(keyFixtures).length === 0) { - console.log('no supported key types available for this OpenSSL version'); + console.log('no supported key types available for this crypto implementation'); process.exit(0); } diff --git a/benchmark/crypto/mac.js b/benchmark/crypto/mac.js index d1028fa414e6..507b543ba0ea 100644 --- a/benchmark/crypto/mac.js +++ b/benchmark/crypto/mac.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL } = require('../../test/common/crypto.js'); +const { isBoringSSL } = require('../../test/common/crypto.js'); const assert = require('node:assert'); const { createHmac, @@ -9,11 +9,10 @@ const { getMacs, } = require('node:crypto'); -if (!hasOpenSSL(3) || - process.features.openssl_is_boringssl || +if (isBoringSSL() || typeof createMac !== 'function' || typeof getMacs !== 'function') { - console.log('Skipping: generic MAC API requires OpenSSL >= 3'); + console.log('Skipping: generic MAC API requires OpenSSL EVP_MAC support'); process.exit(0); } diff --git a/benchmark/crypto/oneshot-sign.js b/benchmark/crypto/oneshot-sign.js index 72e3726d9a53..80dc14b51a76 100644 --- a/benchmark/crypto/oneshot-sign.js +++ b/benchmark/crypto/oneshot-sign.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL } = require('../../test/common/crypto.js'); +const { hasOpenSSL, isBoringSSL } = require('../../test/common/crypto.js'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); @@ -19,7 +19,7 @@ const keyFixtures = { if (hasOpenSSL(3, 5)) { keyFixtures['ml-dsa-44'] = readKey('ml_dsa_44_private'); -} else if (process.features.openssl_is_boringssl) { +} else if (isBoringSSL()) { keyFixtures['ml-dsa-44'] = readKey('ml_dsa_44_private_seed_only'); } diff --git a/benchmark/crypto/oneshot-verify.js b/benchmark/crypto/oneshot-verify.js index 8b397b02dbf2..dd4ab746caa6 100644 --- a/benchmark/crypto/oneshot-verify.js +++ b/benchmark/crypto/oneshot-verify.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL } = require('../../test/common/crypto.js'); +const { hasOpenSSL, isBoringSSL } = require('../../test/common/crypto.js'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); @@ -26,7 +26,7 @@ const keyFixtures = { if (hasOpenSSL(3, 5)) { keyFixtures['ml-dsa-44'] = readKeyPair('ml_dsa_44_public', 'ml_dsa_44_private'); -} else if (process.features.openssl_is_boringssl) { +} else if (isBoringSSL()) { keyFixtures['ml-dsa-44'] = readKeyPair('ml_dsa_44_public', 'ml_dsa_44_private_seed_only'); } diff --git a/configure.py b/configure.py index b11c4e3284d0..da0e5bb3289d 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', @@ -1348,8 +1349,9 @@ def try_check_compiler(cc, lang): # # The version of asm compiler is needed for building openssl asm files. # See deps/openssl/openssl.gypi for detail. -# Commands and regular expressions to obtain its version number are taken from -# https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/crypto/sha/asm/sha512-x86_64.pl#L112-L129 +# Commands and regular expressions to obtain its version number mirror the +# bundled OpenSSL assembler scripts, including +# deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl. # def get_version_helper(cc, regexp): try: @@ -2244,7 +2246,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 @@ -2278,15 +2279,15 @@ def without_ssl_error(option): if not options.shared_openssl and not options.openssl_no_asm: is_x86 = 'x64' in variables['target_arch'] or 'ia32' in variables['target_arch'] - # supported asm compiler for AVX2. See https://github.com/openssl/openssl/ - # blob/OpenSSL_1_1_0-stable/crypto/modes/asm/aesni-gcm-x86_64.pl#L52-L69 - openssl110_asm_supported = \ + # Check for an assembler that supports the instructions used by OpenSSL. + # See deps/openssl/openssl/INSTALL.md for its toolchain requirements. + openssl_asm_supported = \ ('gas_version' in variables and Version(variables['gas_version']) >= Version('2.23')) or \ ('xcode_version' in variables and Version(variables['xcode_version']) >= Version('5.0')) or \ ('llvm_version' in variables and Version(variables['llvm_version']) >= Version('3.3')) or \ ('nasm_version' in variables and Version(variables['nasm_version']) >= Version('2.10')) - if is_x86 and not openssl110_asm_supported: + if is_x86 and not openssl_asm_supported: error('''Did not find a new enough assembler, install one or build with --openssl-no-asm. Please refer to BUILDING.md''') @@ -2299,17 +2300,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 deleted file mode 100644 index a8e64e250491..000000000000 --- a/deps/ncrypto/engine.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "ncrypto.h" - -#if !defined(OPENSSL_NO_ENGINE) && \ - ((defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT) || \ - NCRYPTO_USE_LEGACY_OPENSSL) -#include -#endif - -namespace ncrypto { - -// ============================================================================ -// Engine - -#ifndef OPENSSL_NO_ENGINE -EnginePointer::EnginePointer(void* engine_, bool finish_on_exit_) - : engine(engine_), finish_on_exit(finish_on_exit_) {} - -EnginePointer::EnginePointer(EnginePointer&& other) noexcept - : engine(other.engine), finish_on_exit(other.finish_on_exit) { - other.release(); -} - -EnginePointer::~EnginePointer() { - reset(); -} - -EnginePointer& EnginePointer::operator=(EnginePointer&& other) noexcept { - if (this == &other) return *this; - this->~EnginePointer(); - return *new (this) EnginePointer(std::move(other)); -} - -void EnginePointer::reset(void* engine_, bool finish_on_exit_) { - if (engine != nullptr) { - ENGINE* current = static_cast(engine); - if (finish_on_exit) { - // This also does the equivalent of ENGINE_free. - ENGINE_finish(current); - } else { - ENGINE_free(current); - } - } - engine = engine_; - finish_on_exit = finish_on_exit_; -} - -void* EnginePointer::release() { - void* ret = engine; - engine = nullptr; - finish_on_exit = false; - return ret; -} - -EnginePointer EnginePointer::getEngineByName(const char* name, - CryptoErrorList* errors) { - MarkPopErrorOnReturn mark_pop_error_on_return(errors); - EnginePointer engine(ENGINE_by_id(name)); - if (!engine) { - // Engine not found, try loading dynamically. - engine = EnginePointer(ENGINE_by_id("dynamic")); - if (engine) { - ENGINE* current = static_cast(engine.engine); - if (!ENGINE_ctrl_cmd_string(current, "SO_PATH", name, 0) || - !ENGINE_ctrl_cmd_string(current, "LOAD", nullptr, 0)) { - engine.reset(); - } - } - } - return engine; -} - -bool EnginePointer::setAsDefault(uint32_t flags, CryptoErrorList* errors) { - if (engine == nullptr) return false; - ClearErrorOnReturn clear_error_on_return(errors); - return ENGINE_set_default(static_cast(engine), flags) != 0; -} - -bool EnginePointer::init(bool finish_on_exit) { - if (engine == nullptr) return false; - if (finish_on_exit) setFinishOnExit(); - return ENGINE_init(static_cast(engine)) == 1; -} - -EVPKeyPointer EnginePointer::loadPrivateKey(const char* key_name) { - if (engine == nullptr) return EVPKeyPointer(); - return EVPKeyPointer(ENGINE_load_private_key( - static_cast(engine), key_name, nullptr, nullptr)); -} - -bool EnginePointer::setClientCertEngine(SSL_CTX* ctx) { - if (engine == nullptr || ctx == nullptr) return false; - return SSL_CTX_set_client_cert_engine(ctx, static_cast(engine)) == 1; -} - -void EnginePointer::initEnginesOnce() { - static bool initialized = false; - if (!initialized) { - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - initialized = true; - } -} - -#endif // OPENSSL_NO_ENGINE - -} // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 59006ebf6a84..545bc2fbfb9e 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -19,7 +19,7 @@ #include #include #include -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include #include #include @@ -63,24 +63,13 @@ 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; using BignumGenCallbackPointer = DeleteFnPtr; using NetscapeSPKIPointer = DeleteFnPtr; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using X509PubKeyPointer = DeleteFnPtr; // OSSL_STORE_close() returns int, so it needs a void-returning adapter to be // usable as a DeleteFnPtr deleter. @@ -92,7 +81,7 @@ using UIMethodPointer = DeleteFnPtr; #endif const EVP_CIPHER* GetCipherCtxCipher(const EVP_CIPHER_CTX* ctx) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_CIPHER_CTX_get0_cipher(ctx); #else return EVP_CIPHER_CTX_cipher(ctx); @@ -100,14 +89,14 @@ const EVP_CIPHER* GetCipherCtxCipher(const EVP_CIPHER_CTX* ctx) { } const EVP_MD* GetDigestCtxMd(const EVP_MD_CTX* ctx) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER || NCRYPTO_USE_BORINGSSL +#if NCRYPTO_USE_OPENSSL_PROVIDER || NCRYPTO_USE_BORINGSSL return EVP_MD_CTX_get0_md(ctx); #else return EVP_MD_CTX_md(ctx); #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using ASN1StringPointer = DeleteFnPtr; using OSSLParamBldPointer = DeleteFnPtr; using RsaPssParamsPointer = DeleteFnPtr; @@ -136,7 +125,7 @@ using OpenSSLBufferPointer = static constexpr int kX509NameFlagsRFC2253WithinUtf8JSON = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB & ~ASN1_STRFLGS_ESC_CTRL; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER template bool GetPKeyBnParam(const EVP_PKEY* pkey, const char* name, Pointer* out) { BIGNUM* bn = nullptr; @@ -515,7 +504,7 @@ namespace { std::atomic fips_state_generation{0}; bool isFipsEnabledRaw() { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL return EVP_default_properties_is_fips_enabled(nullptr) == 1; #else return FIPS_mode() == 1; @@ -532,7 +521,7 @@ bool setFipsEnabled(bool enable, CryptoErrorList* errors) { const bool was_enabled = isFipsEnabled(); if (was_enabled == enable) return true; ClearErrorOnReturn clearErrorOnReturn(errors); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL const bool success = EVP_default_properties_enable_fips(nullptr, enable ? 1 : 0) == 1; #else @@ -550,7 +539,7 @@ uint64_t getFipsStateGeneration() { 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"); @@ -732,7 +721,7 @@ int BignumPointer::isPrime(int nchecks, }, &innerCb); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return BN_check_prime(get(), ctx.get(), cb.get()); #elif NCRYPTO_USE_BORINGSSL int is_probably_prime = 0; @@ -812,7 +801,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; } @@ -825,9 +814,9 @@ 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() + // A misconfigured OpenSSL installation may report 1 from RAND_poll() // and RAND_status() but fail in RAND_bytes() if it cannot look up // a matching algorithm for the CSPRNG. if (ERR_GET_LIB(code) == ERR_LIB_RAND) { @@ -862,7 +851,7 @@ int PasswordCallback(char* buf, int size, int rwflag, void* u) { return -1; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { struct StorePassphraseData { Buffer passphrase{.data = nullptr, .len = 0}; @@ -1148,7 +1137,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(), ""); @@ -1162,14 +1151,14 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { BIO_printf(out.get(), "Registered ID:%s", oline); } else if (gen->type == GEN_OTHERNAME) { // The format that is used here is based on OpenSSL's implementation of - // GENERAL_NAME_print (as of OpenSSL 3.0.1). Earlier versions of Node.js + // GENERAL_NAME_print. Earlier versions of Node.js // instead produced the same format as i2v_GENERAL_NAME, which was somewhat // 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: @@ -1189,7 +1178,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)) { @@ -1280,7 +1269,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 @@ -1658,7 +1647,7 @@ bool X509View::ifRsa(KeyCallback callback) const { OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); auto id = EVP_PKEY_id(pkey); if (id == EVP_PKEY_RSA || id == EVP_PKEY_RSA2 || id == EVP_PKEY_RSA_PSS) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Rsa rsa(pkey); #else Rsa rsa(EVP_PKEY_get0_RSA(pkey)); @@ -1675,7 +1664,7 @@ bool X509View::ifEc(KeyCallback callback) const { OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); auto id = EVP_PKEY_id(pkey); if (id == EVP_PKEY_EC) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec ec(pkey); #else Ec ec(EVP_PKEY_get0_EC_KEY(pkey)); @@ -1707,7 +1696,7 @@ X509Pointer X509Pointer::IssuerFrom(const SSL_CTX* ctx, const X509View& cert) { } X509Pointer X509Pointer::PeerFrom(const SSLPointer& ssl) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return X509Pointer(SSL_get1_peer_certificate(ssl.get())); #else return X509Pointer(SSL_get_peer_certificate(ssl.get())); @@ -1842,7 +1831,7 @@ bool EqualNoCase(const std::string_view a, const std::string_view b) { }); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* GetOpenSSLDhGroupName(const std::string_view name, DHPointer::FindGroupOption option) { if (option != DHPointer::FindGroupOption::NO_SMALL_PRIMES && @@ -1919,7 +1908,7 @@ std::optional CheckDhParams(const BIGNUM* p, const BIGNUM* g, const BIGNUM* q, const BIGNUM* j) { - // TODO(panva): In a semver-major, consider tightening OpenSSL 3 validation + // TODO(panva): In a semver-major, consider tightening OpenSSL validation // to report generator and q failures as strictly as legacy DH_check(). if (p == nullptr || g == nullptr) return std::nullopt; @@ -2007,7 +1996,7 @@ std::optional CheckDhParams(const BIGNUM* p, #endif } // namespace -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DHPointer::DHPointer(EVPKeyPointer&& key, const char* group_name) : dh_(key.release()), group_name_(group_name) {} @@ -2020,7 +2009,7 @@ DHPointer::DHPointer(DH* dh) : dh_(dh) {} #endif DHPointer::DHPointer(DHPointer&& other) noexcept -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER : dh_(other.dh_.release()), p_(std::move(other.p_)), g_(std::move(other.g_)), @@ -2045,14 +2034,14 @@ DHPointer::~DHPointer() { } void DHPointer::reset( -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_PKEY* dh #else DH* dh #endif ) { dh_.reset(dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER p_.reset(); g_.reset(); pub_key_.reset(); @@ -2061,7 +2050,7 @@ void DHPointer::reset( #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_PKEY* DHPointer::release() { if (!dh_ && p_ && g_) { auto pkey = @@ -2120,7 +2109,7 @@ DHPointer DHPointer::FromGroup(const std::string_view name, auto generator = GetStandardGenerator(); if (!generator) return {}; // Unable to create the generator. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* group_name = GetOpenSSLDhGroupName(name, option); return DHPointer(std::move(group), std::move(generator), group_name); #else @@ -2131,7 +2120,7 @@ DHPointer DHPointer::FromGroup(const std::string_view name, DHPointer DHPointer::New(BignumPointer&& p, BignumPointer&& g) { if (!p || !g) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = NewDhPKey(p.get(), g.get()); if (!pkey) return {}; return DHPointer(std::move(pkey)); @@ -2154,7 +2143,7 @@ DHPointer DHPointer::New(BignumPointer&& p, BignumPointer&& g) { } DHPointer DHPointer::New(size_t bits, unsigned int generator) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto param_ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_DH); if (!param_ctx.initForParamgen() || !param_ctx.setDhParameters(bits, generator)) { @@ -2179,7 +2168,7 @@ DHPointer DHPointer::New(size_t bits, unsigned int generator) { DHPointer::CheckResult DHPointer::check() { ClearErrorOnReturn clearErrorOnReturn; if (!*this) return DHPointer::CheckResult::NONE; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // TODO(panva): In a semver-major, consider validating named DH groups // through the provider instead of preserving the historical verifyError. if (group_name_ != nullptr) return CheckResult::NONE; @@ -2221,7 +2210,7 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey( if (!pub_key || !*this) { return DHPointer::CheckPublicKeyResult::CHECK_FAILED; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr p; DeleteFnPtr g; const BIGNUM* p_bn = p_.get(); @@ -2288,7 +2277,7 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey( DataPointer DHPointer::getPrime() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return p_.encode(); DeleteFnPtr p; @@ -2304,7 +2293,7 @@ DataPointer DHPointer::getPrime() const { size_t DHPointer::getPrimeBits() const { if (!*this) return 0; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return BignumPointer::GetBitCount(p_.get()); DeleteFnPtr p; @@ -2320,7 +2309,7 @@ size_t DHPointer::getPrimeBits() const { DataPointer DHPointer::getGenerator() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (g_) return g_.encode(); DeleteFnPtr p; @@ -2336,7 +2325,7 @@ DataPointer DHPointer::getGenerator() const { DataPointer DHPointer::getPublicKey() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pub_key_) return pub_key_.encode(); if (!dh_) return {}; @@ -2352,7 +2341,7 @@ DataPointer DHPointer::getPublicKey() const { DataPointer DHPointer::getPrivateKey() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pvt_key_) return pvt_key_.encode(); if (!dh_) return {}; @@ -2368,7 +2357,7 @@ DataPointer DHPointer::getPrivateKey() const { bool DHPointer::hasPrivateKey() const { if (!*this) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pvt_key_) return true; if (!dh_) return false; @@ -2386,7 +2375,7 @@ DataPointer DHPointer::generateKeys() { ClearErrorOnReturn clearErrorOnReturn; if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_ && g_) { if (!pvt_key_ && !GenerateDhPrivateKey(&pvt_key_, p_.get(), group_name_)) { return {}; @@ -2453,7 +2442,7 @@ DataPointer DHPointer::generateKeys() { size_t DHPointer::size() const { if (!*this) return 0; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return BignumPointer::GetByteCount(p_.get()); const int bits = EVP_PKEY_get_bits(dh_.get()); @@ -2470,7 +2459,7 @@ DataPointer DHPointer::computeSecret(const BignumPointer& peer) const { ClearErrorOnReturn clearErrorOnReturn; if (!*this || !peer) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_ && pvt_key_) { auto secret = BignumPointer::NewSecure(); BignumCtxPointer ctx(BN_CTX_new()); @@ -2538,7 +2527,7 @@ DataPointer DHPointer::computeSecret(const BignumPointer& peer) const { bool DHPointer::setPublicKey(BignumPointer&& key) { if (!*this) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_ && g_) { pub_key_ = std::move(key); return true; @@ -2575,7 +2564,7 @@ bool DHPointer::setPublicKey(BignumPointer&& key) { bool DHPointer::setPrivateKey(BignumPointer&& key) { if (!*this) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_ && g_) { pvt_key_ = std::move(key); return true; @@ -2619,7 +2608,7 @@ DataPointer DHPointer::stateless(const EVPKeyPointer& ourKey, if (!ctx || EVP_PKEY_derive_init(ctx.get()) <= 0) { return {}; } - // TODO(panva): In a semver-major, consider padding OpenSSL 3 DH derivation + // TODO(panva): In a semver-major, consider padding OpenSSL DH derivation // results here to match DiffieHellman::computeSecret(). if (EVP_PKEY_derive_set_peer(ctx.get(), theirKey.get()) <= 0 || EVP_PKEY_derive(ctx.get(), nullptr, &out_size) <= 0) { @@ -2648,11 +2637,6 @@ DataPointer DHPointer::stateless(const EVPKeyPointer& ourKey, // KDF const EVP_MD* getDigestByName(const char* name) { - // Historically, "dss1" and "DSS1" were DSA aliases for SHA-1 - // exposed through the public API. - if (strcmp(name, "dss1") == 0 || strcmp(name, "DSS1") == 0) [[unlikely]] { - return EVP_sha1(); - } return EVP_get_digestbyname(name); } @@ -2681,11 +2665,8 @@ DataPointer hkdf(const Digest& md, } auto ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_HKDF); - // OpenSSL < 3.0.0 accepted only a void* as the argument of - // EVP_PKEY_CTX_set_hkdf_md. - const EVP_MD* md_ptr = md; if (!ctx || !EVP_PKEY_derive_init(ctx.get()) || - !EVP_PKEY_CTX_set_hkdf_md(ctx.get(), md_ptr) || + !EVP_PKEY_CTX_set_hkdf_md(ctx.get(), md) || !EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), info.data, info.len)) { return {}; } @@ -2698,12 +2679,9 @@ DataPointer hkdf(const Digest& md, actual_salt = {default_salt, static_cast(md.size())}; } - // We do not use EVP_PKEY_HKDF_MODE_EXTRACT_AND_EXPAND because and instead - // implement the extraction step ourselves because EVP_PKEY_derive does not - // handle zero-length keys, which are required for Web Crypto. - // TODO(jasnell): Once OpenSSL 1.1.1 support is dropped completely, and once - // BoringSSL is confirmed to support it, wen can hopefully drop this and use - // EVP_KDF directly which does support zero length keys. + // Implement the extraction step here because EVP_PKEY_derive does not handle + // zero-length keys, which are required for Web Crypto. EVP_KDF handles them + // but is not available in BoringSSL. unsigned char pseudorandom_key[EVP_MAX_MD_SIZE]; unsigned pseudorandom_key_len = sizeof(pseudorandom_key); @@ -3036,7 +3014,7 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed( EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) { if (!dh) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyPointer(dh.release()); #else auto key = New(); @@ -3048,7 +3026,7 @@ EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) { #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer EVPKeyPointer::NewRSA(const Rsa& rsa) { const auto public_key = rsa.getPublicKey(); if (public_key.n == nullptr || public_key.e == nullptr) return {}; @@ -3099,7 +3077,7 @@ EVPKeyPointer EVPKeyPointer::NewRSA(RSAPointer&& rsa) { } return key; } -#endif // NCRYPTO_USE_OPENSSL3_PROVIDER +#endif // NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer::EVPKeyPointer(EVP_PKEY* pkey) : pkey_(pkey) {} @@ -3237,7 +3215,7 @@ BIOPointer EVPKeyPointer::derPublicKey() const { bool EVPKeyPointer::assign(const ECKeyPointer& eckey) { if (!pkey_ || !eckey) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return set(eckey); #else return EVP_PKEY_assign_EC_KEY(pkey_.get(), eckey.get()); @@ -3246,7 +3224,7 @@ bool EVPKeyPointer::assign(const ECKeyPointer& eckey) { bool EVPKeyPointer::set(const ECKeyPointer& eckey) { if (!pkey_ || !eckey) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int nid = EC_GROUP_get_curve_name(eckey.group_.get()); const char* group_name = OBJ_nid2sn(nid); if (group_name == nullptr) return false; @@ -3514,7 +3492,7 @@ Buffer GetPassphrase( return pass; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using OSSLEncoderCtxPointer = DeleteFnPtr; @@ -3680,7 +3658,7 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryLoadPrivateKeyFromStore( const StorePrivateKeyConfig& config) { -#if !NCRYPTO_USE_OPENSSL3_PROVIDER +#if !NCRYPTO_USE_OPENSSL_PROVIDER return ParseKeyResult(PKParseError::FAILED); #else // The error queue is left populated on failure so the caller can surface a @@ -3791,7 +3769,7 @@ Result EVPKeyPointer::writePrivateKey( // PKCS1 is only permitted for RSA keys. if (id() != EVP_PKEY_RSA) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher : nullptr; if (cipher != nullptr && passphrase.len == 0) { @@ -3806,12 +3784,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 if (rsa == nullptr) return Result(false); switch (config.format) { @@ -3873,7 +3847,7 @@ Result EVPKeyPointer::writePrivateKey( // SEC1 is only permitted for EC keys if (id() != EVP_PKEY_EC) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher : nullptr; err = !WriteEncodedPKey(bio.get(), @@ -3883,12 +3857,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 if (ec == nullptr) return Result(false); switch (config.format) { @@ -3940,7 +3910,7 @@ Result EVPKeyPointer::writePublicKey( if (config.type == ncrypto::EVPKeyPointer::PKEncodingType::PKCS1) { // PKCS#1 is only valid for RSA keys. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (id() != EVP_PKEY_RSA) return Result(false); if (!WriteEncodedPKey(bio.get(), get(), @@ -3951,12 +3921,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 (rsa == nullptr) return Result(false); if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { @@ -3977,7 +3943,7 @@ Result EVPKeyPointer::writePublicKey( #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (ECKeyHasMissingOid(*this)) { ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID); return Result(false, @@ -3987,7 +3953,7 @@ Result EVPKeyPointer::writePublicKey( if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { // Encode SPKI as PEM. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Build the SubjectPublicKeyInfo wrapper explicitly before PEM encoding. // Provider-backed keys can fail the direct PEM_write_bio_PUBKEY() path even // when OpenSSL can materialize the public wrapper with X509_PUBKEY_set(). @@ -4003,7 +3969,7 @@ Result EVPKeyPointer::writePublicKey( mark_pop_error_on_return.peekError()); } #else - // Non-OpenSSL >= 3 builds do not all declare PEM_write_bio_X509_PUBKEY(). + // BoringSSL does not declare PEM_write_bio_X509_PUBKEY(). if (PEM_write_bio_PUBKEY(bio.get(), get()) != 1) { return Result(false, mark_pop_error_on_return.peekError()); @@ -4073,7 +4039,7 @@ std::optional EVPKeyPointer::getBytesOfRS() const { int bits, id = base_id(); if (id == EVP_PKEY_DSA) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr q; if (!GetPKeyBnParam(get(), OSSL_PKEY_PARAM_FFC_Q, &q)) return std::nullopt; bits = BignumPointer::GetBitCount(q.get()); @@ -4091,7 +4057,7 @@ std::optional EVPKeyPointer::getBytesOfRS() const { if (!has_bits) return std::nullopt; #endif } else if (id == EVP_PKEY_EC) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec ec(get()); if (!ec) return std::nullopt; const EC_GROUP* group = ec.getGroup(); @@ -4117,17 +4083,10 @@ EVPKeyPointer::operator Rsa() const { int type = id(); if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA_PSS) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_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 @@ -4137,7 +4096,7 @@ EVPKeyPointer::operator Dsa() const { int type = id(); if (type != EVP_PKEY_DSA) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return Dsa(get()); #else OSSL3_CONST DSA* dsa = EVP_PKEY_get0_DSA(get()); @@ -4148,13 +4107,13 @@ EVPKeyPointer::operator Dsa() const { bool EVPKeyPointer::validateDsaParameters() const { if (!pkey_) return false; -#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()) { #endif // Validate DSA2 parameters from FIPS 186-4. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr p; DeleteFnPtr q; if (!GetPKeyBnParam(pkey_.get(), OSSL_PKEY_PARAM_FFC_P, &p) || @@ -4433,7 +4392,7 @@ constexpr char AsciiToLower(char c) { return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER constexpr auto kUnsupportedCipherFlags = EVP_CIPH_FLAG_CIPHER_WITH_MAC | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK; @@ -4475,7 +4434,7 @@ void PushAlgorithmAlias(const char* name, void* arg) { #endif } // namespace -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Cipher::Cipher(DeleteFnPtr cipher) : cipher_(cipher.get()), fetched_cipher_(std::move(cipher)) {} #endif @@ -4498,7 +4457,7 @@ bool CaseInsensitiveNameEqual::operator()(std::string_view lhs, DigestCache::Result DigestCache::lookup(const char* name, uint64_t generation) const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation) return {}; const auto it = aliases_.find(name); if (it == aliases_.end()) return {}; @@ -4513,7 +4472,7 @@ DigestCache::Result DigestCache::lookup(const char* name, DigestCache::Result DigestCache::insert(const char* name, const EVP_MD* digest, uint64_t generation) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation || name == nullptr || digest == nullptr) { return {}; } @@ -4558,7 +4517,7 @@ DigestCache::Result DigestCache::insert(const char* name, } void DigestCache::reset(uint64_t generation) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ == generation) return; aliases_.clear(); digests_.clear(); @@ -4568,7 +4527,7 @@ void DigestCache::reset(uint64_t generation) { } const DigestCache::AliasMap& DigestCache::aliases() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return aliases_; #else static const AliasMap empty; @@ -4577,7 +4536,7 @@ const DigestCache::AliasMap& DigestCache::aliases() const { } const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation) { aliases_.clear(); ciphers_.clear(); @@ -4595,7 +4554,7 @@ const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* CipherCache::insert( const char* name, DeleteFnPtr&& cipher, @@ -4632,7 +4591,7 @@ const EVP_CIPHER* CipherCache::insert( #endif Cipher::Cipher(const Cipher& other) : cipher_(other.cipher_) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (other.fetched_cipher_ != nullptr) { if (EVP_CIPHER_up_ref(other.fetched_cipher_.get()) == 1) { fetched_cipher_.reset(other.fetched_cipher_.get()); @@ -4645,7 +4604,7 @@ Cipher::Cipher(const Cipher& other) : cipher_(other.cipher_) { Cipher& Cipher::operator=(const Cipher& other) { if (this == &other) return *this; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (other.fetched_cipher_ != nullptr) { if (EVP_CIPHER_up_ref(other.fetched_cipher_.get()) == 1) { fetched_cipher_.reset(other.fetched_cipher_.get()); @@ -4665,13 +4624,13 @@ Cipher& Cipher::operator=(const Cipher& other) { const Cipher Cipher::FromName(const char* name, CipherCache* cache) { const EVP_CIPHER* cipher = EVP_get_cipherbyname(name); if (cipher != nullptr) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!IsSupportedLegacyCipher(cipher)) return Cipher(); #endif return Cipher(cipher); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // A resolution that overlaps a FIPS transition may use either property // state. The cache retains the generation observed here, so the first // resolution begun after the transition clears any stale entries. @@ -4704,13 +4663,13 @@ const Cipher Cipher::FromName(const char* name, CipherCache* cache) { const Cipher Cipher::FromNid(int nid, CipherCache* cache) { const EVP_CIPHER* cipher = EVP_get_cipherbynid(nid); if (cipher != nullptr) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!IsSupportedLegacyCipher(cipher)) return Cipher(); #endif return Cipher(cipher); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* name = OBJ_nid2sn(nid); if (name != nullptr) return FromName(name, cache); #else @@ -4820,7 +4779,7 @@ bool Cipher::isCcmMode() const { bool Cipher::isCtsMode() const { if (!cipher_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return (EVP_CIPHER_get_flags(cipher_) & EVP_CIPH_FLAG_CTS) != 0; #else return false; @@ -4931,7 +4890,7 @@ const char* Cipher::getName() const { const char* name = OBJ_nid2sn(nid); if (name != nullptr) return name; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_CIPHER_get0_name(cipher_); #else return {}; @@ -5028,10 +4987,10 @@ bool CipherCtxPointer::setAeadTagLength(size_t length) { ctx_.get(), EVP_CTRL_AEAD_SET_TAG, length, nullptr); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { // OSSL_CIPHER_PARAM_XTS_STANDARD is not defined by OpenSSL 3.0. Use its -// parameter name directly so custom 3.0 providers can advertise it too. +// parameter name directly so custom providers can advertise it too. constexpr char kCipherParamXtsStandard[] = "xts_standard"; bool SetCipherCtxStringParam(EVP_CIPHER_CTX* ctx, @@ -5057,7 +5016,7 @@ bool SetCipherCtxStringParam(EVP_CIPHER_CTX* ctx, #endif bool CipherCtxPointer::setCtsMode(const char* mode) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return SetCipherCtxStringParam(ctx_.get(), OSSL_CIPHER_PARAM_CTS_MODE, mode); #else static_cast(mode); @@ -5071,7 +5030,7 @@ bool CipherCtxPointer::setPadding(bool padding) { } bool CipherCtxPointer::setXtsStandard(const char* standard) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return SetCipherCtxStringParam(ctx_.get(), kCipherParamXtsStandard, standard); #else static_cast(standard); @@ -5813,7 +5772,7 @@ bool EVPKeyCtxPointer::setDsaParameters(uint32_t bits, bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) { if (!ctx_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* group_name = OBJ_nid2sn(curve); if (group_name == nullptr) return false; @@ -5878,7 +5837,7 @@ bool EVPKeyCtxPointer::setRsaKeygenBits(int bits) { bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) { if (!ctx_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx_.get(), e.get()) == 1; #else if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx_.get(), e.get()) == 1) { @@ -5892,15 +5851,12 @@ bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) { bool EVPKeyCtxPointer::setRsaPssKeygenMd(const Digest& md) { if (!md || !ctx_) return false; - // OpenSSL < 3 accepts a void* for the md parameter. - const EVP_MD* md_ptr = md; - return EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx_.get(), md_ptr) > 0; + return EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx_.get(), md) > 0; } bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md(const Digest& md) { if (!md || !ctx_) return false; - const EVP_MD* md_ptr = md; - return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx_.get(), md_ptr) > 0; + return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx_.get(), md) > 0; } bool EVPKeyCtxPointer::setRsaPssSaltlen(int salt_len) { @@ -5978,11 +5934,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 @@ -6135,7 +6087,7 @@ DataPointer CipherImpl(const EVPKeyPointer& key, } } // namespace -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { int DigestAlgorithmIdentifierToNid(const unsigned char* data, size_t size) { size_t sequence_header; @@ -6377,7 +6329,7 @@ Rsa::Rsa(OSSL3_CONST RSA* ptr) : rsa_(ptr) {} #endif const Rsa::PublicKey Rsa::getPublicKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!rsa_) return {}; return PublicKey{n_.get(), e_.get(), d_.get()}; #else @@ -6389,7 +6341,7 @@ const Rsa::PublicKey Rsa::getPublicKey() const { } const Rsa::PrivateKey Rsa::getPrivateKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!rsa_) return {}; return PrivateKey{p_.get(), q_.get(), dp_.get(), dq_.get(), qi_.get()}; #else @@ -6402,7 +6354,7 @@ const Rsa::PrivateKey Rsa::getPrivateKey() const { } const std::optional Rsa::getPssParams() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pss_params_; #else if (rsa_ == nullptr) return std::nullopt; @@ -6443,7 +6395,7 @@ const std::optional Rsa::getPssParams() const { BIOPointer Rsa::derPublicKey() const { auto bio = BIOPointer::NewMem(); if (!bio) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = EVPKeyPointer::NewRSA(*this); if (!pkey) return {}; if (!rsa_pss_) { @@ -6482,7 +6434,7 @@ BIOPointer Rsa::derPublicKey() const { bool Rsa::setPublicKey(BignumPointer&& n, BignumPointer&& e) { if (!n || !e) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER n_.reset(n.release()); e_.reset(e.release()); rsa_ = true; @@ -6503,7 +6455,7 @@ bool Rsa::setPrivateKey(BignumPointer&& d, BignumPointer&& dp, BignumPointer&& dq, BignumPointer&& qi) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!d || !q || !p || !dp || !dq || !qi) return false; d_.reset(d.release()); q_.reset(q.release()); @@ -6585,7 +6537,7 @@ struct CipherCallbackContext { void operator()(const char* name) { cb(name); } }; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER template , #endif &context); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_CIPHER_do_all_provided(nullptr, array_push_back_provider, &context); #endif #endif @@ -6695,7 +6647,7 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) { // ============================================================================ -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec::Ec() : ec_(nullptr), pub_(nullptr) {} Ec::Ec(const EVP_PKEY* pkey) : Ec() { @@ -6767,7 +6719,7 @@ Ec::Ec(OSSL3_CONST EC_KEY* key) : ec_(key) {} #endif const EC_GROUP* Ec::getGroup() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return ec_.get(); #else return ECKeyPointer::GetGroup(ec_); @@ -6775,7 +6727,7 @@ const EC_GROUP* Ec::getGroup() const { } const EC_POINT* Ec::getPublicKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pub_.get(); #else return ECKeyPointer::GetPublicKey(ec_); @@ -6783,7 +6735,7 @@ const EC_POINT* Ec::getPublicKey() const { } point_conversion_form_t Ec::getPointConversionForm() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return form_; #else return EC_KEY_get_conv_form(ec_); @@ -7546,7 +7498,7 @@ std::pair X509Name::Iterator::operator*() const { // ============================================================================ -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Dsa::Dsa() : dsa_(false) {} Dsa::Dsa(const EVP_PKEY* pkey) : Dsa() { @@ -7563,7 +7515,7 @@ Dsa::Dsa(OSSL3_CONST DSA* dsa) : dsa_(dsa) {} #endif const BIGNUM* Dsa::getP() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return nullptr; return p_.get(); #else @@ -7575,7 +7527,7 @@ const BIGNUM* Dsa::getP() const { } const BIGNUM* Dsa::getQ() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return nullptr; return q_.get(); #else @@ -7587,7 +7539,7 @@ const BIGNUM* Dsa::getQ() const { } size_t Dsa::getModulusLength() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return 0; #else if (dsa_ == nullptr) return 0; @@ -7596,7 +7548,7 @@ size_t Dsa::getModulusLength() const { } size_t Dsa::getDivisorLength() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return 0; #else if (dsa_ == nullptr) return 0; @@ -7611,13 +7563,13 @@ size_t Digest::size() const { return EVP_MD_size(md_); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Digest::Digest(DeleteFnPtr md) : md_(md.get()), fetched_md_(std::move(md)) {} #endif Digest::Digest(const Digest& other) : md_(other.md_) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (other.fetched_md_ != nullptr) { if (EVP_MD_up_ref(other.fetched_md_.get()) == 1) { fetched_md_.reset(other.fetched_md_.get()); @@ -7630,7 +7582,7 @@ Digest::Digest(const Digest& other) : md_(other.md_) { Digest& Digest::operator=(const Digest& other) { if (this == &other) return *this; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (other.fetched_md_ != nullptr) { if (EVP_MD_up_ref(other.fetched_md_.get()) == 1) { fetched_md_.reset(other.fetched_md_.get()); @@ -7653,7 +7605,7 @@ const Digest Digest::SHA256 = Digest(EVP_sha256()); const Digest Digest::SHA384 = Digest(EVP_sha384()); const Digest Digest::SHA512 = Digest(EVP_sha512()); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { bool IsSupportedDigest(const EVP_MD* md) { if (md == nullptr || EVP_MD_is_a(md, "NULL")) return false; @@ -7671,7 +7623,7 @@ bool IsSupportedDigest(const EVP_MD* md) { const Digest Digest::FromName(const char* name) { const EVP_MD* md = ncrypto::getDigestByName(name); if (md != nullptr) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (md == EVP_md_null()) return Digest(); #endif return Digest(md); @@ -7681,7 +7633,7 @@ const Digest Digest::FromName(const char* name) { } const Digest Digest::Fetch(const char* name) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER MarkPopErrorOnReturn mark_pop_error_on_return; DeleteFnPtr fetched( EVP_MD_fetch(nullptr, name, nullptr)); diff --git a/deps/ncrypto/ncrypto.gyp b/deps/ncrypto/ncrypto.gyp index 804a664fa0a2..ce6670e63bb5 100644 --- a/deps/ncrypto/ncrypto.gyp +++ b/deps/ncrypto/ncrypto.gyp @@ -5,22 +5,10 @@ 'ncrypto.cc', 'ncrypto.h', ], - 'ncrypto_engine_sources': [ - 'engine.cc', - 'ncrypto.h', - ], 'ncrypto_strict_defines': [ 'OPENSSL_API_COMPAT=30000', 'OPENSSL_NO_DEPRECATED', ], - 'ncrypto_legacy_openssl_defines': [ - 'OPENSSL_API_COMPAT=0x10100000L', - ], - 'ncrypto_engine_defines': [ - 'OPENSSL_API_COMPAT=30000', - 'OPENSSL_SUPPRESS_DEPRECATED', - 'NCRYPTO_ENGINE_COMPAT=1', - ], }, 'targets': [ { @@ -36,23 +24,15 @@ 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 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': [ @@ -62,27 +42,4 @@ ] }, ], - 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'targets': [ - { - 'target_name': 'ncrypto_engine', - 'type': 'static_library', - 'include_dirs': ['.'], - 'defines': [ - 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', - '<@(ncrypto_engine_defines)', - ], - 'sources': [ '<@(ncrypto_engine_sources)' ], - 'conditions': [ - ['node_shared_openssl=="false"', { - 'dependencies': [ - '../openssl/openssl.gyp:openssl' - ] - }], - ] - }, - ], - }], - ], } diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 79f403788cf4..8c75397b9fee 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -22,16 +22,16 @@ #include #include #include -#if defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT && \ - !defined(OPENSSL_NO_ENGINE) -#include -#endif // NCRYPTO_ENGINE_COMPAT && !OPENSSL_NO_ENGINE - #ifndef OPENSSL_VERSION_PREREQ #define OPENSSL_VERSION_PREREQ(maj, min) \ (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 @@ -45,46 +45,26 @@ #endif // 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 - +// - OpenSSL uses provider APIs and hides deprecated low-level objects. +// - 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_OPENSSL_PROVIDER 0 #else #define NCRYPTO_USE_BORINGSSL 0 +#define NCRYPTO_USE_OPENSSL_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 +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #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 @@ -96,19 +76,15 @@ #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 #endif -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_SIV 1 #else #define OPENSSL_WITH_AES_SIV 0 @@ -167,7 +143,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 @@ -404,7 +380,7 @@ class Digest final { Digest(const Digest& other); Digest& operator=(const Digest& other); inline Digest& operator=(const EVP_MD* md) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER fetched_md_.reset(); #endif md_ = md; @@ -429,7 +405,7 @@ class Digest final { private: const EVP_MD* md_ = nullptr; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Digest(DeleteFnPtr md); DeleteFnPtr fetched_md_; #endif @@ -462,7 +438,7 @@ class DigestCache final { Result lookup(const char* name, uint64_t generation) const; inline Result lookup(int32_t id, uint64_t generation) const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation || id == -1) return {}; const uint32_t unsigned_id = static_cast(id); if (unsigned_id < first_id_) return {}; @@ -481,7 +457,7 @@ class DigestCache final { private: uint64_t generation_ = 0; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using EVPMDPointer = DeleteFnPtr; // IDs are not reused across generations because JavaScript caches them @@ -507,14 +483,14 @@ class CipherCache final { NCRYPTO_DISALLOW_COPY_AND_MOVE(CipherCache) const EVP_CIPHER* lookup(const char* name, uint64_t generation); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* insert(const char* name, DeleteFnPtr&& cipher, uint64_t generation); #endif private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using EVPCipherPointer = DeleteFnPtr; uint64_t generation_ = 0; @@ -548,7 +524,7 @@ class Cipher final { Cipher(const Cipher& other); Cipher& operator=(const Cipher& other); inline Cipher& operator=(const EVP_CIPHER* cipher) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER fetched_cipher_.reset(); #endif cipher_ = cipher; @@ -643,7 +619,7 @@ class Cipher final { private: const EVP_CIPHER* cipher_ = nullptr; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Cipher(DeleteFnPtr cipher); DeleteFnPtr fetched_cipher_; #endif @@ -655,14 +631,14 @@ class Cipher final { class Dsa final { public: Dsa(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Dsa(const EVP_PKEY* pkey); #else Dsa(OSSL3_CONST DSA* dsa); #endif NCRYPTO_DISALLOW_COPY_AND_MOVE(Dsa) -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline operator bool() const { return dsa_; } @@ -679,7 +655,7 @@ class Dsa final { size_t getDivisorLength() const; private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool dsa_ = false; DeleteFnPtr p_; DeleteFnPtr q_; @@ -694,14 +670,14 @@ class Dsa final { class Rsa final { public: Rsa(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Rsa(const EVP_PKEY* pkey); #else Rsa(OSSL3_CONST RSA* rsa); #endif NCRYPTO_DISALLOW_COPY_AND_MOVE(Rsa) -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline operator bool() const { return rsa_; } @@ -754,7 +730,7 @@ class Rsa final { const Buffer in); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool rsa_ = false; bool rsa_pss_ = false; DeleteFnPtr n_; @@ -774,7 +750,7 @@ class Rsa final { class Ec final { public: Ec(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Ec(const EVP_PKEY* pkey); #else Ec(OSSL3_CONST EC_KEY* key); @@ -797,7 +773,7 @@ class Ec final { static bool GetCurves(GetCurveCallback callback); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr ec_; DeleteFnPtr pub_; point_conversion_form_t form_ = POINT_CONVERSION_UNCOMPRESSED; @@ -1145,7 +1121,7 @@ class EVPKeyPointer final { const Buffer& data); #endif static EVPKeyPointer NewDH(DHPointer&& dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER static EVPKeyPointer NewRSA(const Rsa& rsa); #else static EVPKeyPointer NewRSA(RSAPointer&& rsa); @@ -1310,7 +1286,7 @@ class DHPointer final { static DHPointer New(size_t bits, unsigned int generator); DHPointer() = default; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit DHPointer(EVPKeyPointer&& key, const char* group_name = nullptr); DHPointer(BignumPointer&& p, BignumPointer&& g, const char* group_name); #else @@ -1321,7 +1297,7 @@ class DHPointer final { NCRYPTO_DISALLOW_COPY(DHPointer) ~DHPointer(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline bool operator==(std::nullptr_t) noexcept { return !operator bool(); } @@ -1390,7 +1366,7 @@ class DHPointer final { const EVPKeyPointer& theirKey); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr dh_; BignumPointer p_; BignumPointer g_; @@ -1718,7 +1694,7 @@ class ECKeyPointer final { NCRYPTO_DISALLOW_COPY(ECKeyPointer) ~ECKeyPointer(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline bool operator==(std::nullptr_t) noexcept { return group_ == nullptr; } @@ -1762,7 +1738,7 @@ class ECKeyPointer final { #endif private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr group_; DeleteFnPtr pub_; DeleteFnPtr priv_; @@ -2007,44 +1983,6 @@ class MacCache final { }; #endif -#ifndef OPENSSL_NO_ENGINE -class EnginePointer final { - public: - EnginePointer() = default; - - explicit EnginePointer(void* engine_, bool finish_on_exit = false); - EnginePointer(EnginePointer&& other) noexcept; - EnginePointer& operator=(EnginePointer&& other) noexcept; - NCRYPTO_DISALLOW_COPY(EnginePointer) - ~EnginePointer(); - - inline operator bool() const { return engine != nullptr; } - inline void setFinishOnExit() { finish_on_exit = true; } - - void reset(void* engine_ = nullptr, bool finish_on_exit_ = false); - - bool setAsDefault(uint32_t flags, CryptoErrorList* errors = nullptr); - bool init(bool finish_on_exit = false); - EVPKeyPointer loadPrivateKey(const char* key_name); - bool setClientCertEngine(SSL_CTX* ctx); - - void* release(); - - // Retrieve an OpenSSL Engine instance by name. If the name does not - // identify a valid named engine, the returned EnginePointer will be - // empty. - static EnginePointer getEngineByName(const char* name, - CryptoErrorList* errors = nullptr); - - // Call once when initializing OpenSSL at startup for the process. - static void initEnginesOnce(); - - private: - void* engine = nullptr; - bool finish_on_exit = false; -}; -#endif // !OPENSSL_NO_ENGINE - // ============================================================================ // FIPS bool isFipsEnabled(); diff --git a/deps/ncrypto/unofficial.gni b/deps/ncrypto/unofficial.gni index dad4fbbf16f0..7cb27d22b9b8 100644 --- a/deps/ncrypto/unofficial.gni +++ b/deps/ncrypto/unofficial.gni @@ -26,11 +26,7 @@ template("ncrypto_gn_build") { source_set(target_name) { forward_variables_from(invoker, "*") public_configs = [ ":ncrypto_config" ] - defines = [ - "NCRYPTO_ENGINE_COMPAT=1", - "OPENSSL_SUPPRESS_DEPRECATED", - ] - sources = gypi_values.ncrypto_sources + gypi_values.ncrypto_engine_sources + sources = gypi_values.ncrypto_sources deps = [ "$node_openssl_path" ] } } diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 144085fd33df..d11f72a758d8 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -98,36 +98,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") or ' - 'llvm_version and v(llvm_version) >= v("8.0")', { - # 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 59945be330a2..eac32ca0bec8 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -884,9 +884,8 @@ priority than `--dns-result-order`. added: v6.0.0 --> -Enable [FIPS mode][] at startup. With OpenSSL 3, a configured provider named -`fips` must be available and initialize successfully. With OpenSSL 1.1.1, -Node.js must be built against a FIPS-capable OpenSSL. +Enable [FIPS mode][] at startup. A configured provider named `fips` must be +available and initialize successfully. ### `--enable-fips-indicator-events` @@ -2316,8 +2315,7 @@ added: v6.9.0 --> Load an OpenSSL configuration file on startup. The file can activate an -OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See -[FIPS mode][]. +OpenSSL FIPS provider. See [FIPS mode][]. This option takes precedence over the `OPENSSL_CONF` environment variable. @@ -2329,7 +2327,7 @@ added: - v16.17.0 --> -Enable OpenSSL 3.0 legacy provider. For more information please see +Enable OpenSSL's legacy provider. For more information please see [OSSL\_PROVIDER-legacy][OSSL_PROVIDER-legacy]. ### `--openssl-shared-config` diff --git a/doc/api/crypto.md b/doc/api/crypto.md index a08519a57688..b81b4de6c8f5 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3746,8 +3746,8 @@ defaults to 16 bytes. `SIV` and `GCM-SIV` only support 16-byte authentication tags. The `ctsMode` and `xtsStandard` options configure parameters exposed by OpenSSL -providers. They are available only with OpenSSL 3.0 or later and a provider -that supports the corresponding parameter. `ctsMode` applies only to CBC-CTS +providers. They are not available with BoringSSL and require a provider that +supports the corresponding parameter. `ctsMode` applies only to CBC-CTS ciphers, and `xtsStandard` applies only to `sm4-xts`. Supplying either option for an available cipher implementation that does not support it throws an `ERR_CRYPTO_UNSUPPORTED_OPERATION` error. See [CBC-CTS mode][] and [XTS mode][] @@ -3851,8 +3851,8 @@ set if a different length is used. For `SIV` and `GCM-SIV`, the `authTagLength` option defaults to 16 bytes and only 16-byte authentication tags are supported. The `ctsMode` and `xtsStandard` options configure parameters exposed by OpenSSL -providers. They are available only with OpenSSL 3.0 or later and a provider -that supports the corresponding parameter. `ctsMode` applies only to CBC-CTS +providers. They are not available with BoringSSL and require a provider that +supports the corresponding parameter. `ctsMode` applies only to CBC-CTS ciphers, and `xtsStandard` applies only to `sm4-xts`. Supplying either option for an available cipher implementation that does not support it throws an `ERR_CRYPTO_UNSUPPORTED_OPERATION` error. See [CBC-CTS mode][] and [XTS mode][] @@ -4493,7 +4493,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) @@ -4565,7 +4565,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) @@ -4578,18 +4578,6 @@ passed to [`crypto.createPublicKey()`][]. If the `callback` function is provided this function uses libuv's threadpool. -### `crypto.fips` - - - -> Stability: 0 - Deprecated - -Deprecated property for checking and controlling [FIPS mode][]. Use -[`crypto.getFips()`][] and [`crypto.setFips()`][] instead. - ### `crypto.generateKey(type, options, callback)` - -> Stability: 0 - Deprecated - -* `engine` {string} -* `flags` {crypto.constants} **Default:** `crypto.constants.ENGINE_METHOD_ALL` - -Load and set the `engine` for some or all OpenSSL functions (selected by flags). -Use of this API is deprecated because custom engine support has been deprecated -since OpenSSL 3. - -`engine` could be either an id or a path to the engine's shared library. - -The optional `flags` argument uses `ENGINE_METHOD_ALL` by default. The `flags` -is a bit field taking one of or a mix of the following flags (defined in -`crypto.constants`): - -* `crypto.constants.ENGINE_METHOD_RSA` -* `crypto.constants.ENGINE_METHOD_DSA` -* `crypto.constants.ENGINE_METHOD_DH` -* `crypto.constants.ENGINE_METHOD_RAND` -* `crypto.constants.ENGINE_METHOD_EC` -* `crypto.constants.ENGINE_METHOD_CIPHERS` -* `crypto.constants.ENGINE_METHOD_DIGESTS` -* `crypto.constants.ENGINE_METHOD_PKEY_METHS` -* `crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS` -* `crypto.constants.ENGINE_METHOD_ALL` -* `crypto.constants.ENGINE_METHOD_NONE` - ### `crypto.setFips(bool)` -Type: Runtime +Type: End-of-Life -The [`crypto.fips`][] property is deprecated. Please use `crypto.setFips()` +The `crypto.fips` property is no longer supported. Use `crypto.setFips()` and `crypto.getFips()` instead. An automated migration is available ([source](https://github.com/nodejs/userland-migrations/tree/main/recipes/crypto-fips-to-getFips)). @@ -4109,8 +4112,8 @@ that are shorter than the default authentication tag length (i.e., shorter than -Type: Runtime +Type: End-of-Life -OpenSSL 3 has deprecated support for custom engines with a recommendation to -switch to its new provider model. The `clientCertEngine` option for -`https.request()`, [`tls.createSecureContext()`][], and [`tls.createServer()`][]; -the `privateKeyEngine` and `privateKeyIdentifier` for [`tls.createSecureContext()`][]; -and [`crypto.setEngine()`][] all depend on this functionality from OpenSSL. +The `crypto.setEngine()` API and the `crypto.constants.ENGINE_METHOD_*` +constants have been removed. The `clientCertEngine` option for +[`https.request()`][], [`tls.createSecureContext()`][], and +[`tls.createServer()`][] and the `privateKeyEngine` and `privateKeyIdentifier` +options for [`tls.createSecureContext()`][] now throw +`ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED` when used. There is no direct +replacement API in Node.js. OpenSSL's provider model replaces engines upstream. ### DEP0184: Instantiating `node:zlib` classes without `new` @@ -4846,11 +4851,9 @@ async function example() { [`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.pbkdf2()`]: crypto.md#cryptopbkdf2password-salt-iterations-keylen-digest-callback [`crypto.randomBytes()`]: crypto.md#cryptorandombytessize-callback [`crypto.scrypt()`]: crypto.md#cryptoscryptpassword-salt-keylen-options-callback -[`crypto.setEngine()`]: crypto.md#cryptosetengineengine-flags [`decipher.final()`]: crypto.md#decipherfinaloutputencoding [`decipher.setAuthTag()`]: crypto.md#deciphersetauthtagbuffer-encoding [`dirent.parentPath`]: fs.md#direntparentpath diff --git a/doc/api/errors.md b/doc/api/errors.md index fa73cb12036b..a540b198e6e5 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -885,9 +885,8 @@ Argon2 is not supported by the current version of OpenSSL being used. ### `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED` -An OpenSSL engine was requested (for example, through the `clientCertEngine` or -`privateKeyEngine` TLS options) that is not supported by the version of OpenSSL -being used, likely due to the compile-time flag `OPENSSL_NO_ENGINE`. +An OpenSSL engine-based TLS or HTTPS option was used after support for custom +engines reached End-of-Life in Node.js. @@ -904,13 +903,6 @@ An invalid value for the `key` argument has been passed to the `crypto.ECDH()` class `computeSecret()` method. It means that the public key lies outside of the elliptic curve. - - -### `ERR_CRYPTO_ENGINE_UNKNOWN` - -An invalid crypto engine identifier was passed to -[`require('node:crypto').setEngine()`][]. - ### `ERR_CRYPTO_FIPS_FORCED` @@ -4761,7 +4753,6 @@ An error occurred trying to allocate memory. This should never happen. [`process.send()`]: process.md#processsendmessage-sendhandle-options-callback [`process.setUncaughtExceptionCaptureCallback()`]: process.md#processsetuncaughtexceptioncapturecallbackfn [`readable._read()`]: stream.md#readable_readsize -[`require('node:crypto').setEngine()`]: crypto.md#cryptosetengineengine-flags [`require()`]: modules.md#requireid [`server.close()`]: net.md#serverclosecallback [`server.listen()`]: net.md#serverlisten diff --git a/doc/api/https.md b/doc/api/https.md index eba303b6600a..c4a95ee67491 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -428,8 +428,9 @@ a `timeout` of 5 seconds. added: v0.3.6 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine` option is runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v22.4.0 - v20.16.0 @@ -471,10 +472,9 @@ changes: Makes a request to a secure web server. The following additional `options` from [`tls.connect()`][] are also accepted: -`ca`, `cert`, `ciphers`, `clientCertEngine` (deprecated), `crl`, `dhparam`, `ecdhCurve`, -`honorCipherOrder`, `key`, `passphrase`, `pfx`, `rejectUnauthorized`, -`secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`, -`highWaterMark`. +`ca`, `cert`, `ciphers`, `crl`, `dhparam`, `ecdhCurve`, `honorCipherOrder`, +`key`, `passphrase`, `pfx`, `rejectUnauthorized`, `secureOptions`, +`secureProtocol`, `servername`, `sessionIdContext`, `highWaterMark`. `options` can be an object, a string, or a [`URL`][] object. If `options` is a string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][] diff --git a/doc/api/permissions.md b/doc/api/permissions.md index b677013d7978..1ffc555d3274 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -354,8 +354,6 @@ There are constraints you need to know before using this system: to read files before environment initialization. As a result, such flags are not subject to the rules of the Permission Model. The same applies for V8 flags that can be set via runtime through `v8.setFlagsFromString`. -* OpenSSL engines cannot be requested at runtime when the Permission - Model is enabled, affecting the built-in crypto, https, and tls modules. * Run-Time Loadable Extensions cannot be loaded when the Permission Model is enabled, affecting the sqlite module. * Using existing file descriptors via the `node:fs` module bypasses the diff --git a/doc/api/tls.md b/doc/api/tls.md index c8e12eaacf62..9a4bf99fa9a1 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. @@ -1236,7 +1236,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()` @@ -1488,7 +1488,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()` @@ -1966,9 +1966,10 @@ argument. added: v0.11.13 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine`, `privateKeyEngine` and - `privateKeyIdentifier` options are runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine`, `privateKeyEngine`, or + `privateKeyIdentifier` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v26.4.0 - v24.19.0 @@ -2077,14 +2078,12 @@ 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 ciphers can be obtained via [`tls.getCiphers()`][]. Cipher names must be uppercased in order for OpenSSL to accept them. - * `clientCertEngine` {string} Name of an OpenSSL engine which can provide the - client certificate. **Deprecated.** * `crl` {string|string\[]|Buffer|Buffer\[]} PEM formatted CRLs (Certificate Revocation Lists). * `dhparam` {string|Buffer} `'auto'` or custom Diffie-Hellman parameters, @@ -2115,12 +2114,6 @@ changes: occur in an array. `object.passphrase` is optional. Encrypted keys will be decrypted with `object.passphrase` if provided, or `options.passphrase` if it is not. - * `privateKeyEngine` {string} Name of an OpenSSL engine to get private key - from. Should be used together with `privateKeyIdentifier`. **Deprecated.** - * `privateKeyIdentifier` {string} Identifier of a private key managed by - an OpenSSL engine. Should be used together with `privateKeyEngine`. - Should not be set together with `key`, because both options define a - private key in different ways. **Deprecated.** * `maxVersion` {string} Optionally set the maximum TLS version to allow. One of `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified along with the `secureProtocol` option; use one or the other. @@ -2194,8 +2187,9 @@ permissible, use 2048 bits or larger for stronger security. added: v0.3.2 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine` option is runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v22.4.0 - v20.16.0 @@ -2246,8 +2240,6 @@ changes: If a string is returned that does not match one of the client's ALPN protocols, an error will be thrown. This option cannot be used with the `ALPNProtocols` option, and setting both options will throw an error. - * `clientCertEngine` {string} Name of an OpenSSL engine which can provide the - client certificate. **Deprecated.** * `enableTrace` {boolean} If `true`, [`tls.TLSSocket.enableTrace()`][] will be called on new connections. Tracing can be enabled after the secure connection is established, but this option must be used to trace the secure @@ -2584,7 +2576,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 @@ -2601,8 +2593,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 @@ -2636,6 +2628,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 6e2acacd5854..bf91a29d1250 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] @@ -2721,7 +2721,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 4618a5f17df1..57c79ea2ba6c 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -405,7 +405,7 @@ }, "openssl-legacy-provider": { "type": "boolean", - "description": "enable OpenSSL 3.0 legacy provider" + "description": "enable OpenSSL's legacy provider" }, "openssl-shared-config": { "type": "boolean", diff --git a/doc/node.1 b/doc/node.1 index e0a467967f7c..c09a3987538b 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -513,9 +513,8 @@ The default is \fBverbatim\fR and \fBdns.setDefaultResultOrder()\fR have higher priority than \fB--dns-result-order\fR. . .It Fl -enable-fips -Enable FIPS mode at startup. With OpenSSL 3, a configured provider named -\fBfips\fR must be available and initialize successfully. With OpenSSL 1.1.1, -Node.js must be built against a FIPS-capable OpenSSL. +Enable FIPS mode at startup. A configured provider named \fBfips\fR must be +available and initialize successfully. . .It Fl -enable-fips-indicator-events Publish OpenSSL FIPS indicator results to the @@ -1165,12 +1164,11 @@ usually only useful for developers debugging Node.js itself. . .It Fl -openssl-config Ns = Ns Ar file Load an OpenSSL configuration file on startup. The file can activate an -OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See -FIPS mode. +OpenSSL FIPS provider. See FIPS mode. This option takes precedence over the \fBOPENSSL_CONF\fR environment variable. . .It Fl -openssl-legacy-provider -Enable OpenSSL 3.0 legacy provider. For more information please see +Enable OpenSSL's legacy provider. For more information please see OSSL_PROVIDER-legacy. . .It Fl -openssl-shared-config diff --git a/lib/crypto.js b/lib/crypto.js index b44ae9de4e5d..2eaf103299f8 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -123,7 +123,6 @@ const { getCurves, getHashes, getMacs, - setEngine, secureHeapUsed, } = require('internal/crypto/util'); const Certificate = require('internal/crypto/certificate'); @@ -235,7 +234,6 @@ module.exports = { scrypt, scryptSync, sign: signOneShot, - setEngine, timingSafeEqual, getFips, setFips, @@ -350,13 +348,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/https.js b/lib/https.js index 6ae2e5d8a213..d1bc8287c75a 100644 --- a/lib/https.js +++ b/lib/https.js @@ -49,6 +49,9 @@ const { ERR_PROXY_TUNNEL } = require('internal/errors').codes; assertCrypto(); const tls = require('tls'); +const { + validateOpenSSLEngineOptions, +} = require('internal/tls/secure-context'); const kPerRequestCheckServerIdentity = Symbol('per-request checkServerIdentity'); let perRequestCheckServerIdentityIndex = 0; const { @@ -465,6 +468,7 @@ function Agent(options) { return new Agent(options); options = { __proto__: null, ...options }; + validateOpenSSLEngineOptions(options); options.defaultPort ??= 443; options.protocol ??= 'https:'; FunctionPrototypeCall(HttpAgent, this, options); @@ -513,6 +517,7 @@ function getPfxAgentKey(pfx, passphrase) { * @returns {string} */ Agent.prototype.getName = function getName(options = kEmptyObject) { + validateOpenSSLEngineOptions(options); let name = FunctionPrototypeCall(HttpAgent.prototype.getName, this, options); name += ':'; @@ -523,10 +528,6 @@ Agent.prototype.getName = function getName(options = kEmptyObject) { if (options.cert) name += options.cert; - name += ':'; - if (options.clientCertEngine) - name += options.clientCertEngine; - name += ':'; if (options.ciphers) name += options.ciphers; @@ -587,14 +588,6 @@ Agent.prototype.getName = function getName(options = kEmptyObject) { if (options.sigalgs) name += JSONStringify(options.sigalgs); - name += ':'; - if (options.privateKeyIdentifier) - name += options.privateKeyIdentifier; - - name += ':'; - if (options.privateKeyEngine) - name += options.privateKeyEngine; - if (options[kPerRequestCheckServerIdentity]) name += `:${options[kPerRequestCheckServerIdentity]}`; @@ -670,6 +663,7 @@ function request(...args) { if (args[0] && typeof args[0] !== 'function') { ObjectAssign(options, ArrayPrototypeShift(args)); } + validateOpenSSLEngineOptions(options); if (options.checkServerIdentity !== undefined && options.checkServerIdentity !== tls.checkServerIdentity && diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index c408f26e5a9f..dccc2ed91d34 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -37,7 +37,6 @@ const { getCurves: _getCurves, getHashes: _getHashes, getMacs: _getMacs, - setEngine: _setEngine, secureHeapUsed: _secureHeapUsed, getCachedAliases, getCachedMacAliases, @@ -59,18 +58,10 @@ const isFips = getFipsCrypto() === 1; const { getOptionValue } = require('internal/options'); -const { - crypto: { - ENGINE_METHOD_ALL, - }, -} = internalBinding('constants'); - const normalizeHashName = require('internal/crypto/hashnames'); const { codes: { - ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED, - ERR_CRYPTO_ENGINE_UNKNOWN, ERR_INVALID_ARG_TYPE, }, hideStackFrames, @@ -78,7 +69,6 @@ const { const { validateArray, - validateNumber, validateString, } = require('internal/validators'); @@ -88,7 +78,6 @@ const { cachedResult, emitExperimentalWarning, filterDuplicateStrings, - getDeprecationWarningEmitter, lazyDOMException, setOwnProperty, } = require('internal/util'); @@ -200,29 +189,6 @@ const getMacs = cachedArrayByFipsGeneration( const getCurves = cachedResult(() => filterDuplicateStrings(_getCurves())); -const emitOpenSSLEngineDeprecation = getDeprecationWarningEmitter( - 'DEP0183', - 'OpenSSL engine-based APIs are deprecated.', -); - -function setEngine(id, flags) { - validateString(id, 'id'); - if (flags) - validateNumber(flags, 'flags'); - flags = flags >>> 0; - - // Use provided engine for everything by default - if (flags === 0) - flags = ENGINE_METHOD_ALL; - - emitOpenSSLEngineDeprecation(); - - if (typeof _setEngine !== 'function') - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - if (!_setEngine(id, flags)) - throw new ERR_CRYPTO_ENGINE_UNKNOWN(id); -} - const getArrayBufferOrView = hideStackFrames((buffer, name, encoding) => { if (isAnyArrayBuffer(buffer)) return buffer; @@ -1155,9 +1121,7 @@ module.exports = { getHashes, getMacs, getOptionalByteLength, - emitOpenSSLEngineDeprecation, kHandle, - setEngine, toBuf, kNamedCurveAliases, diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 221a40ecdf86..0a95e02c20f4 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1170,11 +1170,10 @@ E('ERR_CONSTRUCT_CALL_REQUIRED', 'Class constructor %s cannot be invoked without E('ERR_CONTEXT_NOT_INITIALIZED', 'context used is not initialized', Error); E('ERR_CRYPTO_ARGON2_NOT_SUPPORTED', 'Argon2 algorithm not supported', Error); E('ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - 'Custom engines not supported by this OpenSSL', Error); + 'Custom engines not supported by this version of Node.js', Error); 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.', diff --git a/lib/internal/tls/secure-context.js b/lib/internal/tls/secure-context.js index 597d4fce9271..9dccdb8aacfd 100644 --- a/lib/internal/tls/secure-context.js +++ b/lib/internal/tls/secure-context.js @@ -34,7 +34,6 @@ const { } = require('internal/validators'); const { - emitOpenSSLEngineDeprecation, toBuf, } = require('internal/crypto/util'); @@ -128,8 +127,26 @@ function processCiphers(ciphers, name) { return { cipherList, cipherSuites }; } +function validateOpenSSLEngineOptions(options) { + const { + clientCertEngine, + privateKeyEngine, + privateKeyIdentifier, + } = options; + + // OpenSSL engine support has reached End-of-Life. Keep recognizing these + // options so that their use throws instead of appearing to work while being + // silently ignored. + if (clientCertEngine != null || + privateKeyEngine != null || + privateKeyIdentifier != null) { + throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); + } +} + function configSecureContext(context, options = kEmptyObject, name = 'options') { validateObject(options, name); + validateOpenSSLEngineOptions(options); const { allowPartialTrustChain, @@ -137,15 +154,12 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') cert, certificateCompression, ciphers = getDefaultCiphers(), - clientCertEngine, crl, dhparam, ecdhCurve = getDefaultEcdhCurve(), key, passphrase, pfx, - privateKeyIdentifier, - privateKeyEngine, sessionIdContext, sessionTimeout, sigalgs, @@ -256,36 +270,6 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') context.setSigalgs(sigalgs); } - if (privateKeyIdentifier !== undefined && privateKeyIdentifier !== null) { - if (privateKeyEngine === undefined || privateKeyEngine === null) { - // Engine is required when privateKeyIdentifier is present - throw new ERR_INVALID_ARG_VALUE(`${name}.privateKeyEngine`, - privateKeyEngine); - } - if (key) { - // Both data key and engine key can't be set at the same time - throw new ERR_INVALID_ARG_VALUE(`${name}.privateKeyIdentifier`, - privateKeyIdentifier); - } - - if (typeof privateKeyIdentifier === 'string' && - typeof privateKeyEngine === 'string') { - emitOpenSSLEngineDeprecation(); - if (context.setEngineKey) - context.setEngineKey(privateKeyIdentifier, privateKeyEngine); - else - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - } else if (typeof privateKeyIdentifier !== 'string') { - throw new ERR_INVALID_ARG_TYPE(`${name}.privateKeyIdentifier`, - ['string', 'null', 'undefined'], - privateKeyIdentifier); - } else { - throw new ERR_INVALID_ARG_TYPE(`${name}.privateKeyEngine`, - ['string', 'null', 'undefined'], - privateKeyEngine); - } - } - validateString(ecdhCurve, `${name}.ecdhCurve`); context.setECDHCurve(ecdhCurve); @@ -331,18 +315,6 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') } } - if (typeof clientCertEngine === 'string') { - emitOpenSSLEngineDeprecation(); - if (typeof context.setClientCertEngine !== 'function') - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - else - context.setClientCertEngine(clientCertEngine); - } else if (clientCertEngine !== undefined && clientCertEngine !== null) { - throw new ERR_INVALID_ARG_TYPE(`${name}.clientCertEngine`, - ['string', 'null', 'undefined'], - clientCertEngine); - } - if (ticketKeys !== undefined && ticketKeys !== null) { validateBuffer(ticketKeys, `${name}.ticketKeys`); if (ticketKeys.byteLength !== 48) { @@ -362,4 +334,5 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') module.exports = { configSecureContext, + validateOpenSSLEngineOptions, }; diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js index 37fa7845843f..72a8a5ee727f 100644 --- a/lib/internal/tls/wrap.js +++ b/lib/internal/tls/wrap.js @@ -46,6 +46,9 @@ const EE = require('events'); const net = require('net'); const tls = require('tls'); const common = require('internal/tls/common'); +const { + validateOpenSSLEngineOptions, +} = require('internal/tls/secure-context'); const { kReinitializeHandle } = require('internal/net'); const JSStreamSocket = require('internal/js_stream_socket'); const { Buffer } = require('buffer'); @@ -620,6 +623,7 @@ function initRead(tlsSocket, socket) { function TLSSocket(socket, opts) { const tlsOptions = { ...opts }; + validateOpenSSLEngineOptions(tlsOptions); let enableTrace = tlsOptions.enableTrace; if (enableTrace == null) { @@ -1440,7 +1444,6 @@ function tlsConnectionListener(rawSocket) { // - rejectUnauthorized. Boolean, default to true. // - key. string. // - cert: string. -// - clientCertEngine: string. // - ca: string or array of strings. // - sessionTimeout: integer. // @@ -1532,6 +1535,7 @@ exports.createServer = function createServer(options, listener) { Server.prototype.setSecureContext = function(options) { validateObject(options, 'options'); + validateOpenSSLEngineOptions(options); if (options.pfx) this.pfx = options.pfx; @@ -1553,11 +1557,6 @@ Server.prototype.setSecureContext = function(options) { else this.cert = undefined; - if (options.clientCertEngine) - this.clientCertEngine = options.clientCertEngine; - else - this.clientCertEngine = undefined; - if (options.ca) this.ca = options.ca; else @@ -1624,8 +1623,6 @@ Server.prototype.setSecureContext = function(options) { if (options.ticketKeys) this.ticketKeys = options.ticketKeys; - this.privateKeyIdentifier = options.privateKeyIdentifier; - this.privateKeyEngine = options.privateKeyEngine; this.certificateCompression = options.certificateCompression; this._sharedCreds = tls.createSecureContext({ @@ -1633,7 +1630,6 @@ Server.prototype.setSecureContext = function(options) { key: this.key, passphrase: this.passphrase, cert: this.cert, - clientCertEngine: this.clientCertEngine, ca: this.ca, ciphers: this.ciphers, sigalgs: this.sigalgs, @@ -1648,8 +1644,6 @@ Server.prototype.setSecureContext = function(options) { sessionIdContext: this.sessionIdContext, ticketKeys: this.ticketKeys, sessionTimeout: this.sessionTimeout, - privateKeyIdentifier: this.privateKeyIdentifier, - privateKeyEngine: this.privateKeyEngine, certificateCompression: this.certificateCompression, }); }; @@ -1847,6 +1841,7 @@ exports.connect = function connect(...args) { minDHSize: 1024, ...options, }; + validateOpenSSLEngineOptions(options); if (!options.keepAlive) options.singleUse = true; diff --git a/node.gyp b/node.gyp index 942bea024498..efc0e6995a2d 100644 --- a/node.gyp +++ b/node.gyp @@ -753,87 +753,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 { diff --git a/node.gypi b/node.gypi index 104e884e6614..3b9810e0273c 100644 --- a/node.gypi +++ b/node.gypi @@ -400,7 +400,6 @@ 'defines': [ 'HAVE_OPENSSL=1' ], 'conditions': [ [ 'node_shared_openssl=="false"', { - 'defines': [ 'OPENSSL_API_COMPAT=0x10100000L', ], 'dependencies': [ './deps/openssl/openssl.gyp:openssl', diff --git a/src/crypto/README.md b/src/crypto/README.md index d3c1016e94a5..086c0933c6ca 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -97,8 +97,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_aes.cc b/src/crypto/crypto_aes.cc index bea8f5b24be5..c5a4074ad215 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -145,11 +145,8 @@ WebCryptoCipherStatus AES_Cipher(Environment* env, auto buf = DataPointer::Alloc(buf_len); auto ptr = static_cast(buf.get()); - // In some outdated version of OpenSSL (e.g. - // ubi81_sharedlibs_openssl111fips_x64) may be used in sharedlib mode, the - // logic will be failed when input size is zero. The newer OpenSSL has fixed - // it up. But we still have to regard zero as special in Node.js code to - // prevent old OpenSSL failure. + // Some shared OpenSSL builds fail when the input size is zero. Keep handling + // zero-length input in Node.js to avoid relying on backend-specific behavior. // // Refs: // https://github.com/openssl/openssl/commit/420cb707b880e4fb649094241371701013eeb15f diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 348d96e60435..f28ecdae965f 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -830,8 +830,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 9dc68f4d9d2d..5dded14f1b5d 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -35,12 +35,8 @@ namespace node { using ncrypto::BIOPointer; using ncrypto::Cipher; using ncrypto::ClearErrorOnReturn; -using ncrypto::CryptoErrorList; using ncrypto::DHPointer; using ncrypto::Digest; -#ifndef OPENSSL_NO_ENGINE -using ncrypto::EnginePointer; -#endif // !OPENSSL_NO_ENGINE using ncrypto::EVPKeyPointer; using ncrypto::MarkPopErrorOnReturn; using ncrypto::SSLPointer; @@ -1352,11 +1348,6 @@ Local SecureContext::GetConstructorTemplate( SetProtoMethodNoSideEffect( isolate, tmpl, "getIssuer", GetCertificate); -#ifndef OPENSSL_NO_ENGINE - SetProtoMethod(isolate, tmpl, "setEngineKey", SetEngineKey); - SetProtoMethod(isolate, tmpl, "setClientCertEngine", SetClientCertEngine); -#endif // !OPENSSL_NO_ENGINE - #define SET_INTEGER_CONSTANTS(name, value) \ tmpl->Set(FIXED_ONE_BYTE_STRING(isolate, name), \ Integer::NewFromUnsigned(isolate, value)); @@ -1441,11 +1432,6 @@ void SecureContext::RegisterExternalReferences( registry->Register(GetCertificate); registry->Register(GetCertificate); -#ifndef OPENSSL_NO_ENGINE - registry->Register(SetEngineKey); - registry->Register(SetClientCertEngine); -#endif // !OPENSSL_NO_ENGINE - registry->Register(CtxGetter); registry->Register(GetBundledRootCertificates); @@ -1606,7 +1592,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 @@ -1625,16 +1611,16 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version)); CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version)); - // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was - // exposed in the public API. To retain compatibility, install a callback - // which restores the old algorithm. + // The ticket key size changed after the original size was exposed in the + // public API. To retain compatibility, install a callback which restores + // the old algorithm. if (!ncrypto::CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) || !ncrypto::CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) || !ncrypto::CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_))) { return THROW_ERR_CRYPTO_OPERATION_FAILED( env, "Error generating ticket keys"); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(sc->ctx_.get(), TicketCompatibilityCallback); #else @@ -1717,54 +1703,6 @@ void SecureContext::SetSigalgs(const FunctionCallbackInfo& args) { return ThrowCryptoError(env, ERR_get_error()); } -#ifndef OPENSSL_NO_ENGINE -void SecureContext::SetEngineKey(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - - SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); - - CHECK_EQ(args.Length(), 2); - - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CryptoErrorList errors; - Utf8Value engine_id(env->isolate(), args[1]); - auto engine = EnginePointer::getEngineByName(*engine_id, &errors); - if (!engine) { - Local exception; - if (errors.empty()) { - errors.add(getNodeCryptoErrorString(NodeCryptoError::ENGINE_NOT_FOUND, - *engine_id)); - } - if (cryptoErrorListToException(env, errors).ToLocal(&exception)) - env->isolate()->ThrowException(exception); - return; - } - - if (!engine.init(true /* finish on exit*/)) { - return THROW_ERR_CRYPTO_OPERATION_FAILED( - env, "Failure to initialize engine"); - } - - Utf8Value key_name(env->isolate(), args[0]); - auto key = engine.loadPrivateKey(*key_name); - - if (!key) - return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key"); - - if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get())) - return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey"); - - sc->private_key_engine_ = std::move(engine); -} -#endif // !OPENSSL_NO_ENGINE - Maybe SecureContext::AddCert(Environment* env, BIOPointer&& bio) { ClearErrorOnReturn clear_error_on_return; // TODO(tniessen): this should be checked by the caller and not treated as ok @@ -1946,7 +1884,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { if (!bio) return; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer params(PEM_read_bio_Parameters(bio.get(), nullptr)); if (params && params.id() == EVP_PKEY_DH) dh.reset(params.release()); #else @@ -1970,7 +1908,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { env->isolate(), "DH parameter is less than 2048 bits")); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer dh_pkey(dh.release()); if (!SSL_CTX_set0_tmp_dh_pkey(sc->ctx_.get(), dh_pkey.get())) { #else @@ -1979,7 +1917,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { return THROW_ERR_CRYPTO_OPERATION_FAILED( env, "Error setting temp DH parameter"); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER dh_pkey.release(); #endif } @@ -2282,7 +2220,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: @@ -2298,53 +2236,6 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { } } -#ifndef OPENSSL_NO_ENGINE -void SecureContext::SetClientCertEngine( - const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsString()); - - SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); - - MarkPopErrorOnReturn mark_pop_error_on_return; - - // SSL_CTX_set_client_cert_engine does not itself support multiple - // calls by cleaning up before overwriting the client_cert_engine - // internal context variable. - // Instead of trying to fix up this problem we in turn also do not - // support multiple calls to SetClientCertEngine. - CHECK(!sc->client_cert_engine_provided_); - - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CryptoErrorList errors; - const Utf8Value engine_id(env->isolate(), args[0]); - auto engine = EnginePointer::getEngineByName(*engine_id, &errors); - if (!engine) { - Local exception; - if (errors.empty()) { - errors.add(getNodeCryptoErrorString(NodeCryptoError::ENGINE_NOT_FOUND, - *engine_id)); - } - if (cryptoErrorListToException(env, errors).ToLocal(&exception)) - env->isolate()->ThrowException(exception); - return; - } - - // Note that this takes another reference to `engine`. - if (!engine.setClientCertEngine(sc->ctx_.get())) - return ThrowCryptoError(env, ERR_get_error()); - sc->client_cert_engine_provided_ = true; -} -#endif // !OPENSSL_NO_ENGINE - void SecureContext::GetTicketKeys(const FunctionCallbackInfo& args) { SecureContext* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); @@ -2384,7 +2275,7 @@ void SecureContext::EnableTicketKeyCallback( SecureContext* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(wrap->ctx_.get(), TicketKeyCallback); #else SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback); @@ -2392,7 +2283,7 @@ void SecureContext::EnableTicketKeyCallback( } namespace { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool InitTicketHmac(EVP_MAC_CTX* hctx, const unsigned char* key, size_t key_len) { @@ -2416,7 +2307,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl, unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -2513,7 +2404,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl, unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 73aff5b628a1..af701f3f7055 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -106,15 +106,12 @@ class SecureContext final : public BaseObject { static const int kTicketKeyIVIndex = 4; protected: - // OpenSSL structures are opaque. This is sizeof(SSL_CTX) for OpenSSL 1.1.1b: + // OpenSSL structures are opaque. Estimate SSL_CTX memory usage: static const int64_t kExternalSize = 1024; static void New(const v8::FunctionCallbackInfo& args); static void Init(const v8::FunctionCallbackInfo& args); static void SetKey(const v8::FunctionCallbackInfo& args); -#ifndef OPENSSL_NO_ENGINE - static void SetEngineKey(const v8::FunctionCallbackInfo& args); -#endif // !OPENSSL_NO_ENGINE static void SetCert(const v8::FunctionCallbackInfo& args); static void AddCACert(const v8::FunctionCallbackInfo& args); static void SetAllowPartialTrustChain( @@ -141,10 +138,6 @@ class SecureContext final : public BaseObject { static void GetMaxProto(const v8::FunctionCallbackInfo& args); static void Close(const v8::FunctionCallbackInfo& args); static void LoadPKCS12(const v8::FunctionCallbackInfo& args); -#ifndef OPENSSL_NO_ENGINE - static void SetClientCertEngine( - const v8::FunctionCallbackInfo& args); -#endif // !OPENSSL_NO_ENGINE static void GetTicketKeys(const v8::FunctionCallbackInfo& args); static void SetTicketKeys(const v8::FunctionCallbackInfo& args); static void EnableTicketKeyCallback( @@ -158,7 +151,7 @@ class SecureContext final : public BaseObject { unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -169,7 +162,7 @@ class SecureContext final : public BaseObject { unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -185,10 +178,6 @@ class SecureContext final : public BaseObject { ncrypto::X509Pointer issuer_; // Non-owning cache for SSL_CTX_get_cert_store(ctx_.get()) X509_STORE* own_cert_store_cache_ = nullptr; -#ifndef OPENSSL_NO_ENGINE - bool client_cert_engine_provided_ = false; - ncrypto::EnginePointer private_key_engine_; -#endif // !OPENSSL_NO_ENGINE unsigned char ticket_key_name_[16]; unsigned char ticket_key_aes_[16]; diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 7fbaf4fff5d9..d79a7148c898 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 @@ -206,7 +196,7 @@ void New(const FunctionCallbackInfo& args) { } } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (BN_num_bits(bn_p.get()) >= 512 && BN_cmp(bn_g.get(), bn_p.get()) >= 0) { PutDhError(DH_R_BAD_GENERATOR); return ThrowCryptoError(env, ERR_get_error(), "Invalid generator"); diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 976c921fee94..068a44f0ef86 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -82,7 +82,7 @@ constexpr BoringSSLDigest kBoringSSLDigests[] = { void ResetHashCache(Environment* env, uint64_t generation, Local algorithm_cache = Local()) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::DigestCache* cache = env->provider_digest_cache.get(); CHECK_NOT_NULL(cache); if (!algorithm_cache.IsEmpty()) { @@ -113,7 +113,7 @@ bool SynchronizeHashCache(Environment* env, return true; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_MD* GetCachedMDByID(Environment* env, int32_t id, Local algorithm_cache = Local()) { @@ -241,7 +241,7 @@ void SaveSupportedHashAlgorithms(const EVP_MD* md, Environment* env = static_cast(arg); env->supported_hash_algorithms.push_back(from); } -#endif // NCRYPTO_USE_OPENSSL3_PROVIDER +#endif // NCRYPTO_USE_OPENSSL_PROVIDER const std::vector& GetSupportedHashAlgorithms(Environment* env) { while (true) { @@ -254,7 +254,7 @@ const std::vector& GetSupportedHashAlgorithms(Environment* env) { static_cast(digest.get); env->supported_hash_algorithms.emplace_back(digest.name); } -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#elif NCRYPTO_USE_OPENSSL_PROVIDER // 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); @@ -290,7 +290,7 @@ void Hash::GetCachedAliases(const FunctionCallbackInfo& args) { size_t size = 0; LocalVector names(isolate); LocalVector values(isolate); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const auto& aliases = env->provider_digest_cache->aliases(); size = aliases.size(); names.reserve(size); @@ -317,7 +317,7 @@ const EVP_MD* GetDigestImplementation( CHECK(algorithm_cache->IsObject()); DCHECK(!digest_owner.has_value()); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Local cache = algorithm_cache.As(); int32_t cache_id = cache_id_val.As()->Value(); if (cache_id != -1) { @@ -358,7 +358,7 @@ const EVP_MD* GetDigestImplementation( } void MarkInvalidXofLength() { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH); #else EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH); @@ -373,7 +373,7 @@ void MarkInvalidXofLength() { // version-independent. #if !OPENSSL_VERSION_PREREQ(3, 4) bool IsShakeDigest(const EVP_MD* md) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_MD_is_a(md, "SHAKE128") || EVP_MD_is_a(md, "SHAKE256"); #else const char* name = OBJ_nid2sn(EVP_MD_type(md)); @@ -537,7 +537,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo& args) { CHECK(args[6]->IsUint32() || args[6]->IsUndefined()); // outputLength if (args.Length() == 7) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int32_t cache_id = args[1].As()->Value(); if (cache_id != -1) { if (const EVP_MD* md = @@ -619,7 +619,7 @@ void Hash::New(const FunctionCallbackInfo& args) { xof_md_len = Just(args[1].As()->Value()); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // This is the common path after the first lookup. Avoid constructing a // digest owner when the Environment already owns the cached implementation. if (args.Length() == 4 && args[0]->IsString()) { @@ -980,7 +980,7 @@ bool ByteLengthToBitLength(size_t byte_length, size_t* bit_length) { } KeccakKmacXof NewKeccakKmacXof(bool use_128_bits) { - // OpenSSL 3.x exposes the cSHAKE/KMAC suffix primitive as KECCAK-KMAC-*. + // OpenSSL exposes the cSHAKE/KMAC suffix primitive as KECCAK-KMAC-*. const char* digest_name = use_128_bits ? OSSL_DIGEST_NAME_KECCAK_KMAC128 : OSSL_DIGEST_NAME_KECCAK_KMAC256; auto digest = std::unique_ptr{ diff --git a/src/crypto/crypto_kem.h b/src/crypto/crypto_kem.h index dc60001e2d13..bdc99499204b 100644 --- a/src/crypto/crypto_kem.h +++ b/src/crypto/crypto_kem.h @@ -112,15 +112,15 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry); #else -// Provide stub implementations when OpenSSL < 3.0 +// Provide stub implementations when KEM is unavailable. namespace node { namespace crypto { namespace KEM { inline void Initialize(Environment* env, v8::Local target) { - // No-op when OpenSSL < 3.0 + // No-op when KEM is unavailable. } inline void RegisterExternalReferences(ExternalReferenceRegistry* registry) { - // No-op when OpenSSL < 3.0 + // No-op when KEM is unavailable. } } // namespace KEM } // namespace crypto diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 2d80caf76661..16ba98b68675 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -1337,7 +1337,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_rsa.cc b/src/crypto/crypto_rsa.cc index e80c70c961df..1aef184c2fa0 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -40,7 +40,7 @@ using v8::Value; namespace crypto { namespace { bool IsRsaPssDigestEncodable(const Digest& digest) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int nid = EVP_MD_type(digest.get()); if (nid == NID_undef) return false; @@ -78,10 +78,8 @@ EVPKeyCtxPointer RsaKeyGenTraits::Setup(RsaKeyPairGenConfig* params) { return {}; } - // TODO(tniessen): This appears to only be necessary in OpenSSL 3, while - // OpenSSL 1.1.1 behaves as recommended by RFC 8017 and defaults the MGF1 - // hash algorithm to the RSA-PSS hashAlgorithm. Remove this code if the - // behavior of OpenSSL 3 changes. + // OpenSSL does not default the MGF1 hash algorithm to the RSA-PSS + // hashAlgorithm as recommended by RFC 8017, so set it explicitly. auto& mgf1_md = params->params.mgf1_md; if (!mgf1_md && params->params.md) { mgf1_md = params->params.md; @@ -365,7 +363,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { KeyType type = d_value->IsString() ? kKeyTypePrivate : kKeyTypePublic; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::Rsa rsa_view; #else RSAPointer rsa(RSA_new()); @@ -437,7 +435,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { } } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = EVPKeyPointer::NewRSA(rsa_view); #else auto pkey = EVPKeyPointer::NewRSA(std::move(rsa)); @@ -456,8 +454,6 @@ bool GetRsaKeyDetail(Environment* env, Mutex::ScopedLock lock(key.mutex()); const auto& m_pkey = key.GetAsymmetricKey(); - // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL - // versions older than 1.1.1e via FIPS / dynamic linking. const ncrypto::Rsa rsa = m_pkey; if (!rsa) return false; diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index 5e09477a6913..0ddd465438ab 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -8,7 +8,7 @@ #include "env-inl.h" #include "memory_tracker-inl.h" #include "openssl/ec.h" -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #endif @@ -405,7 +405,7 @@ bool MayBeSM2Key(const EVPKeyPointer& key) { if (key.id() == EVP_PKEY_SM2) return true; if (key.id() != EVP_PKEY_EC) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // An ECKeyPointer would also need the public point, which a provider-backed // key need not expose. char group_name[64]; diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 14cf5cc8c85d..ac7b25795ce8 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -81,7 +81,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 @@ -540,9 +540,9 @@ void TLSWrap::InitSSL() { SSL_set_mode(ssl_.get(), SSL_MODE_RELEASE_BUFFERS); #endif // SSL_MODE_RELEASE_BUFFERS - // This is default in 1.1.1, but set it anyway, Cycle() doesn't currently - // re-call ClearIn() if SSL_read() returns SSL_ERROR_WANT_READ, so data can be - // left sitting in the incoming enc_in_ and never get processed. + // Set SSL_MODE_AUTO_RETRY explicitly because Cycle() doesn't currently + // re-call ClearIn() if SSL_read() returns SSL_ERROR_WANT_READ, so data can + // be left sitting in the incoming enc_in_ and never get processed. // - https://wiki.openssl.org/index.php/TLS1.3#Non-application_data_records SSL_set_mode(ssl_.get(), SSL_MODE_AUTO_RETRY); @@ -674,8 +674,8 @@ void TLSWrap::SSLInfoCallback(const SSL* ssl_, int where, int ret) { } } - // SSL_CB_HANDSHAKE_START and SSL_CB_HANDSHAKE_DONE are called - // sending HelloRequest in OpenSSL-1.1.1. + // SSL_CB_HANDSHAKE_START and SSL_CB_HANDSHAKE_DONE are called when sending + // HelloRequest. // We need to check whether this is in a renegotiation state or not. if (where & SSL_CB_HANDSHAKE_DONE && !SSL_renegotiate_pending(ssl)) { Debug(c, "SSLInfoCallback(SSL_CB_HANDSHAKE_DONE);"); @@ -916,7 +916,7 @@ void TLSWrap::ClearOut() { return; const char* ls = ERR_lib_error_string(ssl_err); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; #else const char* fs = ERR_func_error_string(ssl_err); diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index 2d3ccef24fac..2d7d0ff025d9 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -138,7 +138,7 @@ class TLSWrap : public AsyncWrap, } private: - // OpenSSL structures are opaque. Estimate SSL memory size for OpenSSL 1.1.1b: + // OpenSSL structures are opaque. Estimate SSL memory usage: // SSL: 6224 // SSL->SSL3_STATE: 1040 // ...some buffers: 42 * 1024 diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 942e00accba9..0f8a2b1c27dd 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -19,7 +19,7 @@ #include #include "math.h" -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include "openssl/provider.h" #endif @@ -38,9 +38,6 @@ using ncrypto::BignumPointer; using ncrypto::BIOPointer; using ncrypto::CryptoErrorList; using ncrypto::DataPointer; -#ifndef OPENSSL_NO_ENGINE -using ncrypto::EnginePointer; -#endif // !OPENSSL_NO_ENGINE using ncrypto::SSLPointer; using v8::Array; using v8::ArrayBuffer; @@ -453,7 +450,7 @@ std::optional ProcessFipsOptions() { const bool force_fips = per_process::cli_options->force_fips_crypto; if (!enable_fips && !force_fips) return std::nullopt; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // 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, @@ -507,15 +504,6 @@ void InitCryptoOnce() { OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); CHECK_NOT_NULL(settings); -#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"); @@ -523,7 +511,6 @@ void InitCryptoOnce() { fprintf(stderr, "Unable to load legacy provider.\n"); } } -#endif OPENSSL_init_ssl(0, settings); InstallFipsIndicatorCallback(); @@ -571,10 +558,6 @@ void InitCryptoOnce() { // Turn off compression. Saves memory and protects against CRIME attacks. // No-op with OPENSSL_NO_COMP builds of OpenSSL. sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); - -#ifndef OPENSSL_NO_ENGINE - EnginePointer::initEnginesOnce(); -#endif // !OPENSSL_NO_ENGINE } void GetFipsCrypto(const FunctionCallbackInfo& args) { @@ -934,7 +917,7 @@ Maybe Decorate(Environment* env, if (err == 0) return JustVoid(); // No decoration necessary. const char* ls = ERR_lib_error_string(err); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; #else const char* fs = ERR_func_error_string(err); @@ -1075,28 +1058,6 @@ void ThrowCryptoError(Environment* env, env->isolate()->ThrowException(exception); } -#ifndef OPENSSL_NO_ENGINE -void SetEngine(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CHECK(args.Length() >= 2 && args[0]->IsString()); - uint32_t flags; - if (!args[1]->Uint32Value(env->context()).To(&flags)) return; - - const node::Utf8Value engine_id(env->isolate(), args[0]); - // If the engine name is not known, calling setAsDefault on the - // empty engine pointer will be non-op that always returns false. - args.GetReturnValue().Set( - EnginePointer::getEngineByName(*engine_id).setAsDefault(flags)); -} -#endif // !OPENSSL_NO_ENGINE - MaybeLocal EncodeBignum(Environment* env, const BIGNUM* bn, int size) { EscapableHandleScope scope(env->isolate()); auto buf = BignumPointer::EncodePadded(bn, size); @@ -1242,10 +1203,6 @@ void SecureHeapUsed(const FunctionCallbackInfo& args) { namespace Util { void Initialize(Environment* env, Local target) { Local context = env->context(); -#ifndef OPENSSL_NO_ENGINE - SetMethod(context, target, "setEngine", SetEngine); -#endif // !OPENSSL_NO_ENGINE - SetMethodNoSideEffect(context, target, "getFipsCrypto", GetFipsCrypto); SetMethodNoSideEffect( context, target, "getFipsCryptoGeneration", GetFipsCryptoGeneration); @@ -1265,10 +1222,6 @@ void Initialize(Environment* env, Local target) { context, target, "getOpenSSLSecLevelCrypto", GetOpenSSLSecLevelCrypto); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { -#ifndef OPENSSL_NO_ENGINE - registry->Register(SetEngine); -#endif // !OPENSSL_NO_ENGINE - registry->Register(GetFipsCrypto); registry->Register(GetFipsCryptoGeneration); registry->Register(SetupFipsIndicatorChannel); diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index aafdd3bf273b..41f0f2568b31 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -112,7 +112,6 @@ void Decode(const v8::FunctionCallbackInfo& args, V(DERIVING_BITS_FAILED, "Deriving bits failed") \ V(ECDH_FAILED, "ECDH key agreement failed") \ V(ENCAPSULATION_FAILED, "Encapsulation failed") \ - V(ENGINE_NOT_FOUND, "Engine \"%s\" was not found") \ V(HKDF_FAILED, "HKDF derivation failed") \ V(INVALID_KEY_TYPE, "Invalid key type") \ V(KEY_GENERATION_JOB_FAILED, "Key generation job failed") \ diff --git a/src/env.cc b/src/env.cc index 842ffebf2b2c..26de688a42ea 100644 --- a/src/env.cc +++ b/src/env.cc @@ -884,7 +884,7 @@ Environment::Environment(IsolateData* isolate_data, ? AllocateEnvironmentThreadId().id : thread_id.id), thread_name_(thread_name) { -#if HAVE_OPENSSL && NCRYPTO_USE_OPENSSL3_PROVIDER +#if HAVE_OPENSSL && NCRYPTO_USE_OPENSSL_PROVIDER provider_digest_cache = std::make_unique(); provider_cipher_cache = std::make_unique(); #if OPENSSL_WITH_EVP_MAC diff --git a/src/node.cc b/src/node.cc index 5a926fa775a3..c4b68a117bfd 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 @@ -1170,7 +1170,6 @@ InitializeOncePerProcessInternal(const std::vector& args, if (!(flags & ProcessInitializationFlags::kNoInitOpenSSL)) { #if HAVE_OPENSSL #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 auto GetOpenSSLErrorString = []() -> std::string { std::string ret; ERR_print_errors_cb( @@ -1186,6 +1185,7 @@ InitializeOncePerProcessInternal(const std::vector& args, // In the case of FIPS builds we should make sure // the random source is properly initialized first. + // // 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. @@ -1242,11 +1242,7 @@ InitializeOncePerProcessInternal(const std::vector& args, GetOpenSSLErrorString()); return result; } -#else // OPENSSL_VERSION_MAJOR < 3 - if (FIPS_mode()) { - OPENSSL_init(); - } -#endif + if (auto fips_error = crypto::ProcessFipsOptions()) { result->exit_code_ = ExitCode::kGenericUserError; result->early_return_ = true; diff --git a/src/node_config.cc b/src/node_config.cc index 7245d9130d03..2de1ee244ddb 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 bd3b66414d18..fd1f87fc5884 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) @@ -73,25 +73,6 @@ #define DH_NOT_SUITABLE_GENERATOR 0x08 #endif #endif -#ifndef OPENSSL_NO_ENGINE -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 -// Engine constants remain public API while engine implementation lives in the -// dedicated compatibility target. -#define ENGINE_METHOD_RSA (unsigned int)0x0001 -#define ENGINE_METHOD_DSA (unsigned int)0x0002 -#define ENGINE_METHOD_DH (unsigned int)0x0004 -#define ENGINE_METHOD_RAND (unsigned int)0x0008 -#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 -#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 -#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 -#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 -#define ENGINE_METHOD_EC (unsigned int)0x0800 -#define ENGINE_METHOD_ALL (unsigned int)0xFFFF -#define ENGINE_METHOD_NONE (unsigned int)0x0000 -#else -#include -#endif -#endif // !OPENSSL_NO_ENGINE #endif // HAVE_OPENSSL #if defined(__POSIX__) @@ -959,54 +940,6 @@ void DefineCryptoConstants(Local target) { NODE_DEFINE_CONSTANT(target, SSL_OP_TLS_ROLLBACK_BUG); #endif -# ifndef OPENSSL_NO_ENGINE - -# ifdef ENGINE_METHOD_RSA - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RSA); -# endif - -# ifdef ENGINE_METHOD_DSA - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DSA); -# endif - -# ifdef ENGINE_METHOD_DH - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DH); -# endif - -# ifdef ENGINE_METHOD_RAND - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND); -# endif - -# ifdef ENGINE_METHOD_EC - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_EC); -# endif - -# ifdef ENGINE_METHOD_CIPHERS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_CIPHERS); -# endif - -# ifdef ENGINE_METHOD_DIGESTS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS); -# endif - -# ifdef ENGINE_METHOD_PKEY_METHS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS); -# endif - -# ifdef ENGINE_METHOD_PKEY_ASN1_METHS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_ASN1_METHS); -# endif - -# ifdef ENGINE_METHOD_ALL - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ALL); -# endif - -# ifdef ENGINE_METHOD_NONE - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_NONE); -# endif - -# endif // !OPENSSL_NO_ENGINE - #ifdef DH_CHECK_P_NOT_SAFE_PRIME NODE_DEFINE_CONSTANT(target, DH_CHECK_P_NOT_SAFE_PRIME); #endif diff --git a/src/node_constants.h b/src/node_constants.h index 97429c0e5e94..115de09587d3 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_errors.h b/src/node_errors.h index cab1dc76dcc7..b65fb791ca7d 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -50,7 +50,6 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details); V(ERR_CONSTRUCT_CALL_INVALID, TypeError) \ V(ERR_CPU_PROFILE_NOT_STARTED, Error) \ V(ERR_CPU_PROFILE_TOO_MANY, Error) \ - V(ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED, Error) \ V(ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, Error) \ V(ERR_CRYPTO_INITIALIZATION_FAILED, Error) \ V(ERR_CRYPTO_INVALID_AUTH_TAG, TypeError) \ diff --git a/src/node_metadata.cc b/src/node_metadata.cc index b91b1b488148..68daae837fc1 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 4665f1faeda7..ca6150fe407e 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1524,9 +1524,9 @@ 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", + "enable OpenSSL's legacy provider", BOOL_FIELD(openssl_legacy_provider), kAllowedInEnvvar); AddOption("--openssl-shared-config", @@ -1534,7 +1534,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( BOOL_FIELD(openssl_shared_config), kAllowedInEnvvar); -#endif // OPENSSL_VERSION_MAJOR +#endif // HAVE_OPENSSL && !OPENSSL_IS_BORINGSSL AddOption("--use-largepages", "This option is no longer supported and a no-op. It still accepts" " these values for compatibility: 'off' (default), 'on' (report a " diff --git a/src/node_options.h b/src/node_options.h index 322955cc38a9..f1368644d689 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -413,7 +413,7 @@ class PerProcessOptions : public Options { DEFINE_BOOL_FIELD(force_fips_crypto) = false; std::string force_fips_crypto_policy = "provider"; #endif // HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) DEFINE_BOOL_FIELD(openssl_legacy_provider) = false; DEFINE_BOOL_FIELD(openssl_shared_config) = false; #endif diff --git a/test/addons/openssl-client-cert-engine/binding.gyp b/test/addons/openssl-client-cert-engine/binding.gyp deleted file mode 100644 index 726f135a4caf..000000000000 --- a/test/addons/openssl-client-cert-engine/binding.gyp +++ /dev/null @@ -1,23 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['OS=="mac" and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'xcode_settings': { - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ] - } - ] -} diff --git a/test/addons/openssl-client-cert-engine/test.js b/test/addons/openssl-client-cert-engine/test.js deleted file mode 100644 index 4f7c7d7ac0f1..000000000000 --- a/test/addons/openssl-client-cert-engine/test.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; -const common = require('../../common'); -const fixture = require('../../common/fixtures'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const fs = require('fs'); -const path = require('path'); - -const engine = path.join(__dirname, - `/build/${common.buildType}/testengine.engine`); - -if (!fs.existsSync(engine)) - common.skip('no client cert engine'); - -const assert = require('assert'); -const https = require('https'); - -const agentKey = fs.readFileSync(fixture.path('/keys/agent1-key.pem')); -const agentCert = fs.readFileSync(fixture.path('/keys/agent1-cert.pem')); -const agentCa = fs.readFileSync(fixture.path('/keys/ca1-cert.pem')); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -const serverOptions = { - key: agentKey, - cert: agentCert, - ca: agentCa, - requestCert: true, - rejectUnauthorized: true, -}; - -const server = https.createServer(serverOptions, common.mustCall((req, res) => { - res.writeHead(200); - res.end('hello world'); -})).listen(0, common.localhostIPv4, common.mustCall(() => { - const clientOptions = { - method: 'GET', - host: common.localhostIPv4, - port: server.address().port, - path: '/test', - clientCertEngine: engine, // `engine` will provide key+cert - rejectUnauthorized: false, // Prevent failing on self-signed certificates - headers: {}, - }; - - const req = https.request(clientOptions, common.mustCall((response) => { - let body = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => { - body += chunk; - }); - - response.on('end', common.mustCall(() => { - assert.strictEqual(body, 'hello world'); - server.close(); - })); - })); - - req.end(); -})); diff --git a/test/addons/openssl-client-cert-engine/testengine.cc b/test/addons/openssl-client-cert-engine/testengine.cc deleted file mode 100644 index 95712901e69c..000000000000 --- a/test/addons/openssl-client-cert-engine/testengine.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testengine" -#define TEST_ENGINE_NAME "dummy test engine" - -#define AGENT_KEY "test/fixtures/keys/agent1-key.pem" -#define AGENT_CERT "test/fixtures/keys/agent1-cert.pem" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -std::string LoadFile(const char* filename) { - std::ifstream file(filename); - return std::string(std::istreambuf_iterator(file), - std::istreambuf_iterator()); -} - - -int EngineLoadSSLClientCert(ENGINE* engine, - SSL* ssl, - STACK_OF(X509_NAME)* ca_dn, - X509** ppcert, - EVP_PKEY** ppkey, - STACK_OF(X509)** pother, - UI_METHOD* ui_method, - void* callback_data) { - if (ppcert != nullptr) { - std::string cert = LoadFile(AGENT_CERT); - if (cert.empty()) { - return 0; - } - - BIO* bio = BIO_new_mem_buf(cert.data(), cert.size()); - *ppcert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); - BIO_vfree(bio); - if (*ppcert == nullptr) { - printf("Could not read certificate\n"); - return 0; - } - } - - if (ppkey != nullptr) { - std::string key = LoadFile(AGENT_KEY); - if (key.empty()) { - return 0; - } - - BIO* bio = BIO_new_mem_buf(key.data(), key.size()); - *ppkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr); - BIO_vfree(bio); - if (*ppkey == nullptr) { - printf("Could not read private key\n"); - return 0; - } - } - - return 1; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - ENGINE_set_load_ssl_client_cert_function(engine, EngineLoadSSLClientCert); - - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/addons/openssl-key-engine/binding.gyp b/test/addons/openssl-key-engine/binding.gyp deleted file mode 100644 index fc1fafa89bab..000000000000 --- a/test/addons/openssl-key-engine/binding.gyp +++ /dev/null @@ -1,23 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testkeyengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['OS=="mac" and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testkeyengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'xcode_settings': { - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ] - } - ] -} diff --git a/test/addons/openssl-key-engine/test.js b/test/addons/openssl-key-engine/test.js deleted file mode 100644 index 92b7bb558ad7..000000000000 --- a/test/addons/openssl-key-engine/test.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; -const common = require('../../common'); -const fixture = require('../../common/fixtures'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const fs = require('fs'); -const path = require('path'); - -const engine = path.join(__dirname, - `/build/${common.buildType}/testkeyengine.engine`); - -if (!fs.existsSync(engine)) - common.skip('no client cert engine'); - -const assert = require('assert'); -const https = require('https'); - -const agentKey = fs.readFileSync(fixture.path('/keys/agent1-key.pem')); -const agentCert = fs.readFileSync(fixture.path('/keys/agent1-cert.pem')); -const agentCa = fs.readFileSync(fixture.path('/keys/ca1-cert.pem')); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -const serverOptions = { - key: agentKey, - cert: agentCert, - ca: agentCa, - requestCert: true, - rejectUnauthorized: true, -}; - -const server = https.createServer(serverOptions, common.mustCall((req, res) => { - res.writeHead(200); - res.end('hello world'); -})).listen(0, common.localhostIPv4, common.mustCall(() => { - const clientOptions = { - method: 'GET', - host: common.localhostIPv4, - port: server.address().port, - path: '/test', - privateKeyEngine: engine, - privateKeyIdentifier: 'dummykey', - cert: agentCert, - rejectUnauthorized: false, // Prevent failing on self-signed certificates - headers: {}, - }; - - const req = https.request(clientOptions, common.mustCall((response) => { - let body = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => { - body += chunk; - }); - - response.on('end', common.mustCall(() => { - assert.strictEqual(body, 'hello world'); - server.close(); - })); - })); - - req.end(); -})); diff --git a/test/addons/openssl-key-engine/testkeyengine.cc b/test/addons/openssl-key-engine/testkeyengine.cc deleted file mode 100644 index 704027ba5a43..000000000000 --- a/test/addons/openssl-key-engine/testkeyengine.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testkeyengine" -#define TEST_ENGINE_NAME "dummy test key engine" - -#define PRIVATE_KEY "test/fixtures/keys/agent1-key.pem" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -std::string LoadFile(const char* filename) { - std::ifstream file(filename); - return std::string(std::istreambuf_iterator(file), - std::istreambuf_iterator()); -} - -static EVP_PKEY* EngineLoadPrivkey(ENGINE* engine, const char* name, - UI_METHOD* ui_method, void* callback_data) { - if (strcmp(name, "dummykey") == 0) { - std::string key = LoadFile(PRIVATE_KEY); - BIO* bio = BIO_new_mem_buf(key.data(), key.size()); - EVP_PKEY* ret = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr); - - BIO_vfree(bio); - if (ret != nullptr) { - return ret; - } - } - - return nullptr; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - ENGINE_set_load_privkey_function(engine, EngineLoadPrivkey); - - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/addons/openssl-providers/binding.cc b/test/addons/openssl-providers/binding.cc index 785a103bb6c6..36f8de59ccd9 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/addons/openssl-providers/providers.cjs b/test/addons/openssl-providers/providers.cjs index fc0f93ef45c8..4967c88fdcd8 100644 --- a/test/addons/openssl-providers/providers.cjs +++ b/test/addons/openssl-providers/providers.cjs @@ -4,10 +4,10 @@ const common = require('../../common'); if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../../common/crypto'); +const { isBoringSSL } = require('../../common/crypto'); -if (!hasOpenSSL3) { - common.skip('this test requires OpenSSL 3.x'); +if (isBoringSSL()) { + common.skip('OpenSSL provider support is required'); } const assert = require('node:assert'); const { diff --git a/test/addons/openssl-test-engine/binding.gyp b/test/addons/openssl-test-engine/binding.gyp deleted file mode 100644 index fe18de701bbd..000000000000 --- a/test/addons/openssl-test-engine/binding.gyp +++ /dev/null @@ -1,33 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testsetengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['(OS=="mac" or OS=="linux") and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testsetengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'OTHER_CFLAGS': ['-Wno-deprecated-declarations'], - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ['OS=="linux"', { - 'cflags': [ - '-Wno-deprecated-declarations', - ], - }], - ], - }], - ], - } - ] -} diff --git a/test/addons/openssl-test-engine/test.js b/test/addons/openssl-test-engine/test.js deleted file mode 100644 index e4ce6b5b519a..000000000000 --- a/test/addons/openssl-test-engine/test.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; -const common = require('../../common'); - -// This tests crypto.setEngine(). - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const crypto = require('crypto'); -const fs = require('fs'); -const path = require('path'); - -// Engine support in OpenSSL is checked later on. -let hasEngineSupport = true; - -assert.throws(() => crypto.setEngine(true), /ERR_INVALID_ARG_TYPE|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); -assert.throws(() => crypto.setEngine('/path/to/engine', 'notANumber'), - /ERR_INVALID_ARG_TYPE/); - -{ - const invalidEngineName = 'xxx'; - assert.throws(() => crypto.setEngine(invalidEngineName), - /ERR_CRYPTO_ENGINE_UNKNOWN|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); - assert.throws(() => crypto.setEngine(invalidEngineName, - crypto.constants.ENGINE_METHOD_RSA), - /ERR_CRYPTO_ENGINE_UNKNOWN|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); -} - -try { - crypto.setEngine('dynamic'); - crypto.setEngine('dynamic'); - - crypto.setEngine('dynamic', crypto.constants.ENGINE_METHOD_RSA); - crypto.setEngine('dynamic', crypto.constants.ENGINE_METHOD_RSA); -} catch (err) { - assert.strictEqual(err.code, 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED'); - hasEngineSupport = false; -} - -if (hasEngineSupport) { - const engine = path.join(__dirname, - `/build/${common.buildType}/testsetengine.engine`); - - if (!fs.existsSync(engine)) - common.skip('no engine'); - - { - const engineId = path.parse(engine).name; - const execDir = path.parse(engine).dir; - - crypto.setEngine(engine); - // OpenSSL 3.0.1 and 1.1.1m now throw errors if an engine is loaded again - // with a duplicate absolute path. - // TODO(richardlau): figure out why this fails on macOS but not Linux. - // crypto.setEngine(engine); - - // crypto.setEngine(engine, crypto.constants.ENGINE_METHOD_RSA); - // crypto.setEngine(engine, crypto.constants.ENGINE_METHOD_RSA); - - process.env.OPENSSL_ENGINES = execDir; - - crypto.setEngine(engineId); - crypto.setEngine(engineId); - - crypto.setEngine(engineId, crypto.constants.ENGINE_METHOD_RSA); - crypto.setEngine(engineId, crypto.constants.ENGINE_METHOD_RSA); - } -} diff --git a/test/addons/openssl-test-engine/testsetengine.cc b/test/addons/openssl-test-engine/testsetengine.cc deleted file mode 100644 index 04f57ec4ba66..000000000000 --- a/test/addons/openssl-test-engine/testsetengine.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testsetengine" -#define TEST_ENGINE_NAME "dummy test engine" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index fddf584d7d41..4c349ac1a0af 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); @@ -35,7 +35,7 @@ TEST_F(NodeCryptoEnv, LoadBIO) { "any errors on the OpenSSL error stack\n"; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER TEST_F(NodeCryptoEnv, ExportIncompleteRsaPrivateKeyAsJwk) { v8::HandleScope handle_scope(isolate_); Argv argv; diff --git a/test/common/crypto.js b/test/common/crypto.js index 63f7487f15d3..ca6d7cce9df7 100644 --- a/test/common/crypto.js +++ b/test/common/crypto.js @@ -123,6 +123,8 @@ const hasOpenSSL = (major = 0, minor = 0, patch = 0) => { return OPENSSL_VERSION_NUMBER >= opensslVersionNumber(major, minor, patch); }; +const isBoringSSL = () => process.features.openssl_is_boringssl; + const hasFIPS = (major = 0, minor = 0, patch = 0) => { return crypto.getFips() === 1 && hasOpenSSL(major, minor, patch); }; @@ -144,9 +146,7 @@ module.exports = { sec1EncExp, hasOpenSSL, hasFIPS, - get hasOpenSSL3() { - return hasOpenSSL(3); - }, + isBoringSSL, // opensslCli defined lazily to reduce overhead of spawnSync get opensslCli() { if (opensslCli !== null) return opensslCli; diff --git a/test/doctool/test-doc-api-json.mjs b/test/doctool/test-doc-api-json.mjs index ff063e018d0e..83a0367bde00 100644 --- a/test/doctool/test-doc-api-json.mjs +++ b/test/doctool/test-doc-api-json.mjs @@ -158,5 +158,5 @@ for await (const dirent of await fs.opendir(new URL('../../out/doc/api/', import assert.partialDeepStrictEqual(allExpectedKeys, findAllKeys(json)); } -assert.strictEqual(numberOfDeprecatedSections, 49); // Increase this number every time a new API is deprecated. +assert.strictEqual(numberOfDeprecatedSections, 48); // Increase this number every time a new API is deprecated. assert.strictEqual(numberOfRemovedAPIs, 46); // Increase this number every time a section is marked as removed. diff --git a/test/fixtures/crypto/ecdsa.js b/test/fixtures/crypto/ecdsa.js index c3545fb20ec7..9e76f7a6aff4 100644 --- a/test/fixtures/crypto/ecdsa.js +++ b/test/fixtures/crypto/ecdsa.js @@ -1,5 +1,7 @@ 'use strict'; +const { isBoringSSL } = require('../../common/crypto'); + module.exports = function() { const pkcs8 = { 'P-256': Buffer.from( @@ -72,7 +74,7 @@ module.exports = function() { 'b6a0a14d7e4bc6dd2eda82c9234f174b670b60c8f7d101f68fdf5889e02373b025' + 'dcbc4c82f2929b8e06c68535da98e38fe399c53a814b097935581ef21535eb', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': Buffer.from( 'f6a48eb5557f484ed0c3e4b5c78a3cf497cbd346db06a4165d429248aa2cc51a69' + '747d09f57af145469a8b607a9b8b9709629d74e8f5ca337c6ddc581b6f6103', @@ -104,7 +106,7 @@ module.exports = function() { '72fbdb369fd34c1c54264d07f4facd69b02e4206f8a8bb259b882a305c56fde2d3' + '5107e493c53cd6b4af0b31306f4d03fd43cfc762a1030e17a3d775453a1212b142' + '9f7b3d93066a5f42a10b138cd177dc09616e827d598822d78d4627b754e6', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': Buffer.from( '0b07c078be30fa5925a307d6fc559c5f398e63fb5d007d6b24a834847f2d3d18d5' + 'b5e840711c52a7bc6626c3ced93301e873c013a706f6b297c12cc6d47a71e0529e' + @@ -144,7 +146,7 @@ module.exports = function() { '01f0071e6a32867fa70f695cd39c4e87e142b9e4134d38740bd6fee354a575167e' + '13524e94832637910fe11e53a85fb21b91adb81bb1779c4e2b8bc87c717dc35084', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': Buffer.from( '00463679f47a4c705e03447360dcf34d1743e0d4b2591cc66832a6bc80d92e538c' + '169a1fd330f98e7235ca7fec7e16ac44fb13095b8edf2c76b75c4845177d59e425' + @@ -170,7 +172,7 @@ module.exports = function() { const curves = ['P-256', 'P-384', 'P-521']; const hashes = ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512']; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { hashes.push('SHA3-256', 'SHA3-384', 'SHA3-512'); } diff --git a/test/fixtures/crypto/eddsa.js b/test/fixtures/crypto/eddsa.js index a5382219f4f3..bd35ea77d9e2 100644 --- a/test/fixtures/crypto/eddsa.js +++ b/test/fixtures/crypto/eddsa.js @@ -1,5 +1,7 @@ 'use strict'; +const { isBoringSSL } = require('../../common/crypto'); + const common = require('../../common'); module.exports = function() { @@ -46,7 +48,7 @@ module.exports = function() { const algorithms = ['Ed25519']; const contexts = [new Uint8Array(0), new Uint8Array(32), new Uint8Array(255)]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { algorithms.push('Ed448') } else { common.printSkipMessage(`Skipping unsupported Ed448 test cases`); diff --git a/test/fixtures/crypto/hmac.js b/test/fixtures/crypto/hmac.js index acdf3229a4bc..6872eecf707d 100644 --- a/test/fixtures/crypto/hmac.js +++ b/test/fixtures/crypto/hmac.js @@ -1,5 +1,7 @@ 'use strict'; +const { isBoringSSL } = require('../../common/crypto'); + module.exports = function () { const plaintext = Buffer.from( '5f4dba4f320c0ce876725afce5fbd25bf83e5a7125a08cafe73c3ebac421779df9d55d' + @@ -22,7 +24,7 @@ module.exports = function () { '5dcc359443aaf652fa1375d6b3e61fdcf29bb4a28bd5d3dcfa40f82f906bb280' + '0455db03b5d31fb972a15a6d0103a24e56d156a119c0e5a1e92a44c3c5657cf9', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': Buffer.from( 'e588ec0811463d767241df1074b47ae4071b51f2ce36537ba69ccdc3fdc2b7a8', 'hex'), @@ -48,7 +50,7 @@ module.exports = function () { '61fb278c3ffb0cce2bf1cf723ddfd8ef1f931c0c618c25907324605939e3f9a2' + 'c6f4af690bda3407dc2f5770f6a0a44b954d64a332e3ee0821abf82b7f3e99c1', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': Buffer.from( 'c1ac5e11fcd50c48bf567f6e296632f5801c4eb07a8a47579b41dee971a3099b', 'hex'), diff --git a/test/fixtures/crypto/rsa_pkcs.js b/test/fixtures/crypto/rsa_pkcs.js index d54c44b6d820..d76333d8f05d 100644 --- a/test/fixtures/crypto/rsa_pkcs.js +++ b/test/fixtures/crypto/rsa_pkcs.js @@ -1,5 +1,7 @@ 'use strict'; +const { isBoringSSL } = require('../../common/crypto'); + module.exports = function () { const pkcs8 = Buffer.from( '308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282' + @@ -97,7 +99,7 @@ module.exports = function () { '7a6335c70e193235dcda48add6858626bd96311e60f7e5ea4491b6c1e6248afe12b' + 'bbd54f8869b043a5b0444562813f0a98b300356f306e6b783a29f3bec97ca40ea20' + '062cab8926ec5d96aa387cc84821a6d72b8ea126e7d', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'sha3-256': Buffer.from( 'be1b476c1911a01d71710fd8a2f3158d6f7839e91443b01bed30dfdd04336d80c6b' + 'f692c06fad254877901c10a73853e8fb202a29cddefdf16c3adcda1fc123625897d' + @@ -161,7 +163,7 @@ module.exports = function () { plaintext, signature: signatures['sha-512'] }, - ...(!process.features.openssl_is_boringssl ? [ + ...(!isBoringSSL() ? [ { publicKeyBuffer: spki, privateKeyBuffer: pkcs8, diff --git a/test/fixtures/crypto/rsa_pss.js b/test/fixtures/crypto/rsa_pss.js index 423f2c4d77bf..6c125786d96b 100644 --- a/test/fixtures/crypto/rsa_pss.js +++ b/test/fixtures/crypto/rsa_pss.js @@ -1,5 +1,7 @@ 'use strict'; +const { isBoringSSL } = require('../../common/crypto'); + module.exports = function() { const pkcs8 = Buffer.from( '308204bf020100300d06092a864886f70d0101010500048204a9308204a5020100028' + @@ -150,7 +152,7 @@ module.exports = function() { 'b68c04bfe452c3adc6c10066a915231b7b404727eb6201b4921eb96d9407de2b963' + '3879ceb71d759d9828d7b4d062f6ef100757d8328187caf57dfb859d1555345207c' + '1cce7905c3564c08fec78867a53d5a2cf84810e1ffa', 'hex'), - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'sha3-512, no salt': Buffer.from( 'd2430dc87abeaa7d13f7cec8510f1a296e1c608f44b1696829c59a99e8eefe9b2ee' + '6ee8ad6fdc93c24fcba2f04d1da195924b6209717e1992c10ed9f4783478765fe34' + @@ -255,7 +257,7 @@ module.exports = function() { plaintext, signature: signatures['sha-512, salted'] }, - ...(!process.features.openssl_is_boringssl ? [ + ...(!isBoringSSL() ? [ { publicKeyBuffer: spki, privateKeyBuffer: pkcs8, diff --git a/test/fixtures/openssl_fips_disabled.cnf b/test/fixtures/openssl_fips_disabled.cnf deleted file mode 100644 index 253c6906e3f3..000000000000 --- 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 79733c657a96..000000000000 --- 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/fixtures/webcrypto/supports-level-2.mjs b/test/fixtures/webcrypto/supports-level-2.mjs index 3d0f8a630394..61633ae95a12 100644 --- a/test/fixtures/webcrypto/supports-level-2.mjs +++ b/test/fixtures/webcrypto/supports-level-2.mjs @@ -13,8 +13,6 @@ const [ECDH, X25519] = await Promise.all([ subtle.generateKey('X25519', false, ['deriveBits', 'deriveKey']), ]); -const boringSSL = process.features.openssl_is_boringssl; - export const vectors = { 'encrypt': [ [false, 'Invalid'], diff --git a/test/fixtures/webcrypto/supports-modern-algorithms.mjs b/test/fixtures/webcrypto/supports-modern-algorithms.mjs index 4b44e02d479d..d19ab9b82517 100644 --- a/test/fixtures/webcrypto/supports-modern-algorithms.mjs +++ b/test/fixtures/webcrypto/supports-modern-algorithms.mjs @@ -1,14 +1,13 @@ import * as crypto from 'node:crypto' -import { hasOpenSSL } from '../../common/crypto.js' +import { hasOpenSSL, isBoringSSL } from '../../common/crypto.js' -const boringSSL = process.features.openssl_is_boringssl; -const pqc = hasOpenSSL(3, 5) || boringSSL; +const pqc = hasOpenSSL(3, 5) || isBoringSSL(); const argon2 = hasOpenSSL(3, 2); const shake128 = crypto.getHashes().includes('shake128'); const shake256 = crypto.getHashes().includes('shake256'); -const ocb = hasOpenSSL(3); -const kmac = hasOpenSSL(3); +const ocb = !isBoringSSL(); +const kmac = !isBoringSSL(); const { subtle } = globalThis.crypto; const X25519 = await subtle.generateKey('X25519', false, ['deriveBits', 'deriveKey']); @@ -90,7 +89,7 @@ export const vectors = { [pqc, 'ML-DSA-44'], [pqc, 'ML-DSA-65'], [pqc, 'ML-DSA-87'], - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], [true, 'ChaCha20-Poly1305'], @@ -111,7 +110,7 @@ export const vectors = { [pqc, 'ML-DSA-44'], [pqc, 'ML-DSA-65'], [pqc, 'ML-DSA-87'], - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], [true, 'ChaCha20-Poly1305'], @@ -132,7 +131,7 @@ export const vectors = { [pqc, 'ML-DSA-44'], [pqc, 'ML-DSA-65'], [pqc, 'ML-DSA-87'], - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], [true, 'ChaCha20-Poly1305'], @@ -148,15 +147,15 @@ export const vectors = { [true, 'RSA-PSS'], [true, 'RSASSA-PKCS1-v1_5'], [true, 'X25519'], - [!boringSSL, 'X448'], + [!isBoringSSL(), 'X448'], [true, 'Ed25519'], - [!boringSSL, 'Ed448'], + [!isBoringSSL(), 'Ed448'], [true, 'ECDH'], [true, 'ECDSA'], [pqc, 'ML-DSA-44'], [pqc, 'ML-DSA-65'], [pqc, 'ML-DSA-87'], - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], [false, 'AES-CTR'], @@ -215,12 +214,12 @@ export const vectors = { [false, 'AES-OCB'], ], 'encapsulateBits': [ - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], ], 'encapsulateKey': [ - [pqc && !boringSSL, 'ML-KEM-512', 'AES-KW'], + [pqc && !isBoringSSL(), 'ML-KEM-512', 'AES-KW'], [pqc, 'ML-KEM-768', 'AES-KW'], [pqc, 'ML-KEM-768', 'AES-GCM'], [pqc, 'ML-KEM-768', 'AES-CTR'], @@ -241,12 +240,12 @@ export const vectors = { [false, 'ML-KEM-768', 'Ed25519'], ], 'decapsulateBits': [ - [pqc && !boringSSL, 'ML-KEM-512'], + [pqc && !isBoringSSL(), 'ML-KEM-512'], [pqc, 'ML-KEM-768'], [pqc, 'ML-KEM-1024'], ], 'decapsulateKey': [ - [pqc && !boringSSL, 'ML-KEM-512', 'AES-KW'], + [pqc && !isBoringSSL(), 'ML-KEM-512', 'AES-KW'], [pqc, 'ML-KEM-768', 'AES-KW'], [pqc, 'ML-KEM-768', 'AES-GCM'], [pqc, 'ML-KEM-768', 'AES-CTR'], diff --git a/test/fixtures/webcrypto/supports-secure-curves.mjs b/test/fixtures/webcrypto/supports-secure-curves.mjs index a3a84f6c9f9a..b877db54f8d8 100644 --- a/test/fixtures/webcrypto/supports-secure-curves.mjs +++ b/test/fixtures/webcrypto/supports-secure-curves.mjs @@ -1,62 +1,60 @@ -import { hasOpenSSL } from '../../common/crypto.js' +import { hasOpenSSL, isBoringSSL } from '../../common/crypto.js' const supportsContext = hasOpenSSL(3, 2); const { subtle } = globalThis.crypto; -const boringSSL = process.features.openssl_is_boringssl; - const X25519 = await subtle.generateKey('X25519', false, ['deriveBits', 'deriveKey']); let X448; let Ed448; -if (!boringSSL) { +if (!isBoringSSL()) { X448 = await subtle.generateKey('X448', false, ['deriveBits', 'deriveKey']) Ed448 = await subtle.generateKey('Ed448', false, ['sign', 'verify']) } export const vectors = { 'sign': [ - [!boringSSL, 'Ed448'], - [!boringSSL, { name: 'Ed448', context: Buffer.alloc(0) }], - [!boringSSL && supportsContext, { name: 'Ed448', context: Buffer.alloc(32) }], - [!boringSSL && supportsContext, { name: 'Ed448', context: Buffer.alloc(255) }], + [!isBoringSSL(), 'Ed448'], + [!isBoringSSL(), { name: 'Ed448', context: Buffer.alloc(0) }], + [!isBoringSSL() && supportsContext, { name: 'Ed448', context: Buffer.alloc(32) }], + [!isBoringSSL() && supportsContext, { name: 'Ed448', context: Buffer.alloc(255) }], [false, { name: 'Ed448', context: Buffer.alloc(256) }], ], 'generateKey': [ - [!boringSSL, 'X448'], - [!boringSSL, 'Ed448'], + [!isBoringSSL(), 'X448'], + [!isBoringSSL(), 'Ed448'], ], 'deriveKey': [ - [!boringSSL, + [!isBoringSSL(), { name: 'X448', public: X448?.publicKey }, { name: 'AES-CBC', length: 128 }], [false, { name: 'X448', public: X448?.publicKey }, { name: 'HMAC', hash: 'SHA-256' }], - [!boringSSL, + [!isBoringSSL(), { name: 'X448', public: X448?.publicKey }, { name: 'HMAC', hash: 'SHA-256', length: 448 }], [false, { name: 'X448', public: X448?.publicKey }, { name: 'HMAC', hash: 'SHA-256', length: 449 }], - [!boringSSL, + [!isBoringSSL(), { name: 'X448', public: X448?.publicKey }, 'HKDF'], ], 'deriveBits': [ - [!boringSSL, { name: 'X448', public: X448?.publicKey }], - [!boringSSL, { name: 'X448', public: X448?.publicKey }, 448], + [!isBoringSSL(), { name: 'X448', public: X448?.publicKey }], + [!isBoringSSL(), { name: 'X448', public: X448?.publicKey }, 448], [false, { name: 'X448', public: X448?.publicKey }, 449], [false, { name: 'X448', public: X25519.publicKey }], [false, { name: 'X448', public: X448?.privateKey }], [false, 'X448'], ], 'importKey': [ - [!boringSSL, 'X448'], - [!boringSSL, 'Ed448'], + [!isBoringSSL(), 'X448'], + [!isBoringSSL(), 'Ed448'], ], 'exportKey': [ - [!boringSSL, 'Ed448'], - [!boringSSL, 'X448'], + [!isBoringSSL(), 'Ed448'], + [!isBoringSSL(), 'X448'], ], }; diff --git a/test/fixtures/webcrypto/supports-sha3.mjs b/test/fixtures/webcrypto/supports-sha3.mjs index 73f5b778eeb9..00ba3ec3cd18 100644 --- a/test/fixtures/webcrypto/supports-sha3.mjs +++ b/test/fixtures/webcrypto/supports-sha3.mjs @@ -1,6 +1,6 @@ -const { subtle } = globalThis.crypto; +import { isBoringSSL } from '../../common/crypto.js' -const boringSSL = process.features.openssl_is_boringssl; +const { subtle } = globalThis.crypto; const RSA_KEY_GEN = { modulusLength: 2048, @@ -14,18 +14,18 @@ const [ECDH, X25519] = await Promise.all([ export const vectors = { 'digest': [ - [!boringSSL, 'SHA3-256'], - [!boringSSL, 'SHA3-384'], - [!boringSSL, 'SHA3-512'], + [!isBoringSSL(), 'SHA3-256'], + [!isBoringSSL(), 'SHA3-384'], + [!isBoringSSL(), 'SHA3-512'], ], 'generateKey': [ - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], - [!boringSSL, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [!isBoringSSL(), { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 25 }], [false, { name: 'HMAC', hash: 'SHA3-256', length: 0 }], // This interaction is not defined for now. @@ -33,28 +33,28 @@ export const vectors = { [false, { name: 'HMAC', hash: 'SHA3-256' }], ], 'deriveKey': [ - [!boringSSL, + [!isBoringSSL(), { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, { name: 'AES-CBC', length: 128 }], - [!boringSSL, + [!isBoringSSL(), { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], [false, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 'HKDF'], - [!boringSSL, + [!isBoringSSL(), { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, { name: 'AES-CBC', length: 128 }], - [!boringSSL, + [!isBoringSSL(), { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 'HKDF'], - [!boringSSL, + [!isBoringSSL(), { name: 'X25519', public: X25519.publicKey }, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], - [!boringSSL, + [!isBoringSSL(), { name: 'ECDH', public: ECDH.publicKey }, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], @@ -74,27 +74,27 @@ export const vectors = { { name: 'HMAC', hash: 'SHA3-256' }], ], 'deriveBits': [ - [!boringSSL, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8], - [!boringSSL, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 0], + [!isBoringSSL(), { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 8], + [!isBoringSSL(), { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 0], [false, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, null], [false, { name: 'HKDF', hash: 'SHA3-256', salt: Buffer.alloc(0), info: Buffer.alloc(0) }, 7], - [!boringSSL, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 8], - [!boringSSL, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 0], + [!isBoringSSL(), { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 8], + [!isBoringSSL(), { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 0], [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 0 }, 8], [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, null], [false, { name: 'PBKDF2', hash: 'SHA3-256', salt: Buffer.alloc(0), iterations: 1 }, 7], ], 'importKey': [ - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256' }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], - [!boringSSL, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256' }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 256 }], - [!boringSSL, { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256' }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 25 }], + [!isBoringSSL(), { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'RSA-PSS', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'RSA-OAEP', hash: 'SHA3-256', ...RSA_KEY_GEN }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256' }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 256 }], + [!isBoringSSL(), { name: 'HMAC', hash: 'SHA3-256', length: 25 }], [false, { name: 'HMAC', hash: 'SHA3-256', length: 0 }], ], 'get key length': [ diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index 90c399790f65..7956c63a63c6 100644 --- a/test/parallel/test-cli-node-options.js +++ b/test/parallel/test-cli-node-options.js @@ -12,7 +12,7 @@ const { Worker } = require('worker_threads'); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); tmpdir.refresh(); const printA = path.relative(tmpdir.path, fixtures.path('printA.js')); @@ -65,7 +65,7 @@ if (common.isLinux) { if (common.hasCrypto) { expectNoWorker('--use-openssl-ca', 'B\n'); expectNoWorker('--use-bundled-ca', 'B\n'); - if (!hasOpenSSL3) + if (isBoringSSL()) expectNoWorker('--openssl-config=_ossl_cfg', 'B\n'); if (common.isMacOS) { expect('--use-system-ca', 'B\n'); diff --git a/test/parallel/test-config-json-schema.js b/test/parallel/test-config-json-schema.js index 82679660a30f..6f7972b5692a 100644 --- a/test/parallel/test-config-json-schema.js +++ b/test/parallel/test-config-json-schema.js @@ -10,10 +10,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL3) { - common.skip('this test requires OpenSSL 3.x'); +if (isBoringSSL()) { + common.skip('this test is not supported with BoringSSL'); } if (!common.hasIntl) { diff --git a/test/parallel/test-crypto-async-sign-verify.js b/test/parallel/test-crypto-async-sign-verify.js index 96b4b5d90679..883f74476730 100644 --- a/test/parallel/test-crypto-async-sign-verify.js +++ b/test/parallel/test-crypto-async-sign-verify.js @@ -3,7 +3,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const util = require('util'); const crypto = require('crypto'); @@ -100,7 +100,7 @@ test('rsa_public.pem', 'rsa_private.pem', 'sha256', false, // ED25519 test('ed25519_public.pem', 'ed25519_private.pem', undefined, true); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // ED448 test('ed448_public.pem', 'ed448_private.pem', undefined, true); @@ -132,7 +132,7 @@ if (!process.features.openssl_is_boringssl) { common.printSkipMessage('Skipping unsupported ed448/secp256k1/dsa test cases'); } -// Test Parallel Execution w/ KeyObject is threadsafe in openssl3 +// Test Parallel Execution w/ KeyObject is threadsafe in OpenSSL { const publicKey = { key: crypto.createPublicKey( @@ -171,12 +171,10 @@ MCowBQYDK2VuAyEA6pwGRbadNQAI/tYN8+/p/0/hbsdHfOEGr1ADiLVk/Gc= const data = crypto.randomBytes(32); const signature = crypto.randomBytes(16); - let expected = /no default digest/; - let expectedCode = 'ERR_OSSL_EVP_NO_DEFAULT_DIGEST'; - if (hasOpenSSL(3) || process.features.openssl_is_boringssl) { - expected = /operation[\s_]not[\s_]supported[\s_]for[\s_]this[\s_]keytype/i; - expectedCode = 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE'; - } + const expected = + /operation[\s_]not[\s_]supported[\s_]for[\s_]this[\s_]keytype/i; + const expectedCode = + 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE'; crypto.verify(undefined, data, untrustedKey, signature, common.mustCall((err) => { assert.ok(err); diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js index 3ad34729f871..55811e1e8c01 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -29,7 +29,7 @@ const assert = require('assert'); const crypto = require('crypto'); const { inspect } = require('util'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const isFipsEnabled = crypto.getFips() === 1; const fips3 = hasFIPS(3); @@ -813,7 +813,7 @@ for (const test of TEST_CASES) { } catch (err) { // OpenSSL without https://github.com/openssl/openssl/pull/32427 // cannot finalize an empty CCM message unless update() was called. - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { assert.strictEqual(err.code, 'ERR_OSSL_TAG_NOT_SET'); } else { assert.match(err.message, /Unsupported state/); @@ -834,7 +834,7 @@ if (fips3) { }), { code: 'ERR_OSSL_EVP_UNSUPPORTED', }); -} else if (!process.features.openssl_is_boringssl) { +} else if (!isBoringSSL()) { const key = Buffer.alloc(32); const iv = Buffer.alloc(12); @@ -852,7 +852,7 @@ if (fips3) { // ChaCha20-Poly1305 should respect the authTagLength option and should not // require the authentication tag before calls to update() during decryption. -if (!fips3 && !process.features.openssl_is_boringssl) { +if (!fips3 && !isBoringSSL()) { const key = Buffer.alloc(32); const iv = Buffer.alloc(12); @@ -903,7 +903,7 @@ if (!fips3 && !process.features.openssl_is_boringssl) { // shorter tags as long as their length was valid according to NIST SP 800-38D. // For ChaCha20-Poly1305, we intentionally deviate from that because there are // no recommended or approved authentication tag lengths below 16 bytes. -if (!fips3 && !process.features.openssl_is_boringssl) { +if (!fips3 && !isBoringSSL()) { const rfcTestCases = TEST_CASES.filter(({ algo, tampered }) => { return algo === 'chacha20-poly1305' && tampered === false; }); @@ -942,7 +942,7 @@ if (!fips3 && !process.features.openssl_is_boringssl) { } // https://github.com/nodejs/node/issues/45874 -if (!fips3 && !process.features.openssl_is_boringssl) { +if (!fips3 && !isBoringSSL()) { const rfcTestCases = TEST_CASES.filter(({ algo, tampered }) => { return algo === 'chacha20-poly1305' && tampered === false; }); diff --git a/test/parallel/test-crypto-boringssl-evp-list.js b/test/parallel/test-crypto-boringssl-evp-list.js index 3f142c24f28a..5e27e540f7f7 100644 --- a/test/parallel/test-crypto-boringssl-evp-list.js +++ b/test/parallel/test-crypto-boringssl-evp-list.js @@ -1,10 +1,12 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); -if (!process.features.openssl_is_boringssl) +if (!isBoringSSL()) common.skip('BoringSSL-only test'); const assert = require('assert'); diff --git a/test/parallel/test-crypto-certificate.js b/test/parallel/test-crypto-certificate.js index 6462654680ea..649b4c1c6368 100644 --- a/test/parallel/test-crypto-certificate.js +++ b/test/parallel/test-crypto-certificate.js @@ -26,7 +26,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { Certificate } = crypto; const fixtures = require('../common/fixtures'); @@ -42,7 +42,7 @@ function copyArrayBuffer(buf) { function checkMethods(certificate) { - if (!process.features.openssl_is_boringssl) + if (!isBoringSSL()) assert.strictEqual(certificate.verifySpkac(spkacValid), !hasFIPS(3)); assert.strictEqual(certificate.verifySpkac(spkacFail), false); @@ -58,7 +58,7 @@ function checkMethods(certificate) { ); assert.strictEqual(certificate.exportChallenge(spkacFail), ''); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { const ab = copyArrayBuffer(spkacValid); const expected = !hasFIPS(3); assert.strictEqual(certificate.verifySpkac(ab), expected); diff --git a/test/parallel/test-crypto-cipheriv-decipheriv.js b/test/parallel/test-crypto-cipheriv-decipheriv.js index d2c216924ea8..bbadf3d485d6 100644 --- a/test/parallel/test-crypto-cipheriv-decipheriv.js +++ b/test/parallel/test-crypto-cipheriv-decipheriv.js @@ -5,7 +5,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const isFipsEnabled = crypto.getFips() === 1; const fips3 = hasFIPS(3); @@ -293,8 +293,8 @@ assert.throws( errMessage); // But all other IV lengths should be accepted. -const minIvLength = hasOpenSSL(3) ? 8 : 1; -const maxIvLength = hasOpenSSL(3) ? 64 : 256; +const minIvLength = isBoringSSL() ? 1 : 8; +const maxIvLength = isBoringSSL() ? 256 : 64; for (let n = minIvLength; n < maxIvLength; n += 1) { if (isFipsEnabled && n < 12) continue; crypto.createCipheriv('aes-128-gcm', Buffer.alloc(16), Buffer.alloc(n)); diff --git a/test/parallel/test-crypto-classes.js b/test/parallel/test-crypto-classes.js index 48d68c93fb62..d8ff1ba70d0e 100644 --- a/test/parallel/test-crypto-classes.js +++ b/test/parallel/test-crypto-classes.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); // 'ClassName' : ['args', 'for', 'constructor'] const TEST_CASES = { @@ -31,7 +31,7 @@ if (hasFIPS(3)) { TEST_CASES.DiffieHellman = [2048]; TEST_CASES.DiffieHellmanGroup = ['modp14']; } else if (crypto.getFips() !== 1) { - TEST_CASES.DiffieHellman = [hasOpenSSL(3) ? 1024 : 256]; + TEST_CASES.DiffieHellman = [isBoringSSL() ? 256 : 1024]; } for (const [clazz, args] of Object.entries(TEST_CASES)) { diff --git a/test/parallel/test-crypto-dep0183.js b/test/parallel/test-crypto-dep0183.js index c0b9a8e9f679..754b90d2de76 100644 --- a/test/parallel/test-crypto-dep0183.js +++ b/test/parallel/test-crypto-dep0183.js @@ -1,3 +1,4 @@ +// Flags: --expose-internals 'use strict'; const common = require('../common'); @@ -6,17 +7,90 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); +const https = require('https'); +const tls = require('tls'); +const { internalBinding } = require('internal/test/binding'); -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, +process.on('warning', (warning) => { + if (warning.code === 'DEP0183') + throw warning; }); -assert.throws( - () => crypto.setEngine('nodejs-test-invalid-engine'), - (err) => { - return err.code === 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED' || - err.code === 'ERR_CRYPTO_ENGINE_UNKNOWN'; - }, -); +// DEP0183: OpenSSL engine-based APIs have reached End-of-Life. +assert.strictEqual(Object.hasOwn(crypto, 'setEngine'), false); +import('node:crypto').then(common.mustCall((esmCrypto) => { + assert.strictEqual(Object.hasOwn(esmCrypto, 'setEngine'), false); +})); + +for (const name of [ + 'ENGINE_METHOD_RSA', + 'ENGINE_METHOD_DSA', + 'ENGINE_METHOD_DH', + 'ENGINE_METHOD_RAND', + 'ENGINE_METHOD_CIPHERS', + 'ENGINE_METHOD_DIGESTS', + 'ENGINE_METHOD_PKEY_METHS', + 'ENGINE_METHOD_PKEY_ASN1_METHS', + 'ENGINE_METHOD_EC', + 'ENGINE_METHOD_ALL', + 'ENGINE_METHOD_NONE', +]) { + assert.strictEqual(Object.hasOwn(crypto.constants, name), false); +} + +const binding = internalBinding('crypto'); +assert.strictEqual(Object.hasOwn(binding, 'setEngine'), false); +const secureContext = new binding.SecureContext(); +assert.strictEqual('setEngineKey' in secureContext, false); +assert.strictEqual('setClientCertEngine' in secureContext, false); + +const engineError = { + code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', + message: 'Custom engines not supported by this version of Node.js', +}; +const engineOptions = [ + { clientCertEngine: 'engine' }, + { clientCertEngine: 0 }, + { privateKeyEngine: 'engine' }, + { privateKeyEngine: false }, + { privateKeyIdentifier: 'key' }, + { privateKeyIdentifier: '' }, + { privateKeyIdentifier: 'key', privateKeyEngine: 'engine' }, +]; +const existingContext = tls.createSecureContext(); + +// The removed TLS options remain recognized so they cannot appear to work. +for (const options of engineOptions) { + assert.throws(() => tls.createSecureContext(options), engineError); + assert.throws(() => tls.createServer(options), engineError); + assert.throws( + () => tls.connect({ port: 443, secureContext: existingContext, ...options }), + engineError, + ); + assert.throws( + () => new tls.TLSSocket(undefined, { secureContext: existingContext, ...options }), + engineError, + ); + assert.throws( + () => https.request({ host: 'localhost', port: 443, agent: false, ...options }), + engineError, + ); +} + +// HTTPS rejects the options before a pooled socket could hide their use. +const agent = new https.Agent(); +const options = { host: 'example.com', port: 443 }; +for (const removedOption of [ + 'clientCertEngine', + 'privateKeyEngine', + 'privateKeyIdentifier', +]) { + assert.throws( + () => new https.Agent({ [removedOption]: 'engine' }), + engineError, + ); + assert.throws( + () => agent.getName({ ...options, [removedOption]: 'engine' }), + engineError, + ); +} diff --git a/test/parallel/test-crypto-dh-constructor.js b/test/parallel/test-crypto-dh-constructor.js index 28747ac3a726..94993c9effec 100644 --- a/test/parallel/test-crypto-dh-constructor.js +++ b/test/parallel/test-crypto-dh-constructor.js @@ -5,10 +5,10 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + 2048 : (crypto.getFips() === 1 || !isBoringSSL() ? 1024 : 256); const dh1 = crypto.createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); diff --git a/test/parallel/test-crypto-dh-curves.js b/test/parallel/test-crypto-dh-curves.js index ee8849163ae8..d4b4a4fc67f3 100644 --- a/test/parallel/test-crypto-dh-curves.js +++ b/test/parallel/test-crypto-dh-curves.js @@ -5,11 +5,10 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { DH_CHECK_P_NOT_PRIME, DH_CHECK_P_NOT_SAFE_PRIME, - DH_NOT_SUITABLE_GENERATOR, } = crypto.constants; // Second OAKLEY group, see @@ -21,7 +20,7 @@ const p = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; crypto.createDiffieHellman(p, 'hex'); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const notPrime = Buffer.from(p, 'hex'); notPrime[notPrime.length - 1] = 0xfd; assert.strictEqual( @@ -63,12 +62,12 @@ assert.throws( }); // Confirm DH_check() results are exposed for optional examination. -const bad_dh = process.features.openssl_is_boringssl ? +const bad_dh = isBoringSSL() ? crypto.createDiffieHellman('abcd', 'hex', 0) : crypto.createDiffieHellman('02', 'hex'); assert.notStrictEqual(bad_dh.verifyError, 0); -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { const smallSafePrime = crypto.createDiffieHellman( Buffer.from([23]), Buffer.from([2])); assert.notStrictEqual(smallSafePrime.verifyError, 0); @@ -77,11 +76,6 @@ if (hasOpenSSL(3)) { () => crypto.createDiffieHellman(Buffer.from(p, 'hex'), Buffer.from(p, 'hex')), { code: 'ERR_OSSL_DH_BAD_GENERATOR' }); -} else if (!process.features.openssl_is_boringssl) { - assert.strictEqual( - crypto.createDiffieHellman(Buffer.from(p, 'hex'), - Buffer.from(p, 'hex')).verifyError, - DH_NOT_SUITABLE_GENERATOR); } const availableCurves = new Set(crypto.getCurves()); diff --git a/test/parallel/test-crypto-dh-errors.js b/test/parallel/test-crypto-dh-errors.js index 3ff9b746e020..8b5db3f9610a 100644 --- a/test/parallel/test-crypto-dh-errors.js +++ b/test/parallel/test-crypto-dh-errors.js @@ -5,7 +5,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); // https://github.com/nodejs/node/issues/32738 // XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError @@ -25,7 +25,7 @@ assert.throws(() => crypto.createDiffieHellman('abcdef', 13.37), { }); for (const bits of [-1, 0, 1]) { - if (hasOpenSSL3) { + if (!isBoringSSL()) { assert.throws(() => crypto.createDiffieHellman(bits), { code: 'ERR_OSSL_DH_MODULUS_TOO_SMALL', name: 'Error', diff --git a/test/parallel/test-crypto-dh-generate-keys.js b/test/parallel/test-crypto-dh-generate-keys.js index d074ba957516..dcfaaac0028b 100644 --- a/test/parallel/test-crypto-dh-generate-keys.js +++ b/test/parallel/test-crypto-dh-generate-keys.js @@ -6,11 +6,11 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); { const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + 2048 : (crypto.getFips() === 1 || !isBoringSSL() ? 1024 : 256); function unlessInvalidState(f) { try { diff --git a/test/parallel/test-crypto-dh-group-setters.js b/test/parallel/test-crypto-dh-group-setters.js index 37d0a44d0e1e..39f45ae99918 100644 --- a/test/parallel/test-crypto-dh-group-setters.js +++ b/test/parallel/test-crypto-dh-group-setters.js @@ -1,12 +1,14 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const crypto = require('crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { common.skip('Skipping unsupported Diffie-Hellman tests'); } diff --git a/test/parallel/test-crypto-dh-leak.js b/test/parallel/test-crypto-dh-leak.js index 8d5141eef4b1..37106b2acfa3 100644 --- a/test/parallel/test-crypto-dh-leak.js +++ b/test/parallel/test-crypto-dh-leak.js @@ -9,12 +9,12 @@ if (common.isASan) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const before = process.memoryUsage.rss(); { const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + 2048 : (crypto.getFips() === 1 || !isBoringSSL() ? 1024 : 256); const dh = crypto.createDiffieHellman(size); const publicKey = dh.generateKeys(); const privateKey = dh.getPrivateKey(); diff --git a/test/parallel/test-crypto-dh-modp2-views.js b/test/parallel/test-crypto-dh-modp2-views.js index e32c515e1536..81df42d2284c 100644 --- a/test/parallel/test-crypto-dh-modp2-views.js +++ b/test/parallel/test-crypto-dh-modp2-views.js @@ -5,9 +5,9 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS, modp2buf } = require('../common/crypto'); +const { hasFIPS, modp2buf, isBoringSSL } = require('../common/crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { common.skip('Skipping unsupported Diffie-Hellman tests'); } diff --git a/test/parallel/test-crypto-dh-modp2.js b/test/parallel/test-crypto-dh-modp2.js index 0bf36f93a39a..f3daabb4960b 100644 --- a/test/parallel/test-crypto-dh-modp2.js +++ b/test/parallel/test-crypto-dh-modp2.js @@ -5,9 +5,9 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS, modp2buf } = require('../common/crypto'); +const { hasFIPS, modp2buf, isBoringSSL } = require('../common/crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { common.skip('Skipping unsupported Diffie-Hellman tests'); } diff --git a/test/parallel/test-crypto-dh-odd-key.js b/test/parallel/test-crypto-dh-odd-key.js index c96227770e3d..049c9931c084 100644 --- a/test/parallel/test-crypto-dh-odd-key.js +++ b/test/parallel/test-crypto-dh-odd-key.js @@ -27,12 +27,12 @@ if (!common.hasCrypto) { const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); function test() { const odd = Buffer.alloc(39, 'A'); - const size = hasFIPS(3) ? 2048 : (hasOpenSSL(3) ? 1024 : 32); + const size = hasFIPS(3) ? 2048 : (isBoringSSL() ? 32 : 1024); const c = crypto.createDiffieHellman(size); c.setPrivateKey(odd); c.generateKeys(); diff --git a/test/parallel/test-crypto-dh-stateless.js b/test/parallel/test-crypto-dh-stateless.js index 0ade828eb234..fdeb87602ab7 100644 --- a/test/parallel/test-crypto-dh-stateless.js +++ b/test/parallel/test-crypto-dh-stateless.js @@ -5,9 +5,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL } = require('../common/crypto'); -const isBoringSSL = process.features.openssl_is_boringssl; - +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); // Error code for a key-type mismatch during (EC)DH. The underlying OpenSSL // error code varies by version, and in OpenSSL 4.0 by platform: some builds // report a generic internal error instead of a typed key-type mismatch. @@ -17,7 +15,7 @@ let keyTypeMismatchCode; if (hasOpenSSL(4, 0)) { keyTypeMismatchCode = /^ERR_OSSL_EVP_(OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE|INTERNAL_ERROR)$/; -} else if (hasOpenSSL(3)) { +} else if (!isBoringSSL()) { keyTypeMismatchCode = 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE'; } else { keyTypeMismatchCode = 'ERR_OSSL_EVP_DIFFERENT_KEY_TYPES'; @@ -229,7 +227,7 @@ function testDHError(options, expected) { }); } -if (isBoringSSL) { +if (isBoringSSL()) { common.printSkipMessage('Skipping finite-field DH KeyObject import and ' + 'generation tests unsupported by BoringSSL'); } else { @@ -338,15 +336,6 @@ if (isBoringSSL) { // Same generator, but different primes. [{ group: 'modp5' }, { group: 'modp18' }]]; - // TODO(danbev): Take a closer look if there should be a check in OpenSSL3 - // when the dh parameters differ. - if (!hasOpenSSL(3)) { - // Same primes, but different generator. - list.push([{ group: 'modp5' }, { prime: group.getPrime(), generator: 5 }]); - // Same generator, but different primes. - list.push([{ primeLength: 1024 }, { primeLength: 1024 }]); - } - for (const [params1, params2] of list) { const options = { privateKey: crypto.generateKeyPairSync('dh', params1).privateKey, @@ -354,9 +343,7 @@ if (isBoringSSL) { }; testDHError(options, { name: 'Error', - code: hasOpenSSL(3) ? - 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' : - 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' + code: 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' }); } } @@ -417,13 +404,13 @@ test(crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' }), }; testDHError(options, { name: 'Error', - code: hasOpenSSL(3) ? - 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' : - 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' + code: isBoringSSL() ? + 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' : + 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' }); } -if (isBoringSSL) { +if (isBoringSSL()) { common.printSkipMessage('Skipping x448 diffieHellman test cases ' + 'unsupported by BoringSSL'); } else { @@ -541,7 +528,7 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [ { const ec256 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' }); const ec384 = crypto.generateKeyPairSync('ec', { namedCurve: 'P-384' }); - const x448 = isBoringSSL ? null : crypto.generateKeyPairSync('x448'); + const x448 = isBoringSSL() ? null : crypto.generateKeyPairSync('x448'); const x25519 = crypto.generateKeyPairSync('x25519'); const ed25519 = crypto.generateKeyPairSync('ed25519'); @@ -573,9 +560,9 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [ testDHError({ privateKey: privKey(ec256.privateKey), publicKey: pubKey(ec384.publicKey), - }, { code: hasOpenSSL(3) ? - 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' : - 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' }); + }, { code: isBoringSSL() ? + 'ERR_OSSL_EVP_DIFFERENT_PARAMETERS' : + 'ERR_OSSL_MISMATCHING_DOMAIN_PARAMETERS' }); // Incompatible key types (ec + x25519) testDHError({ @@ -591,7 +578,7 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [ /^ERR_OSSL_EVP_(OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE|INTERNAL_ERROR)$/ : 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE' }); - if (!isBoringSSL) { + if (!isBoringSSL()) { // Incompatible key types (x448 + x25519) testDHError({ privateKey: privKey(x448.privateKey), @@ -603,9 +590,7 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [ testDHError({ privateKey: privKey(x25519.privateKey), publicKey: pubKey(zeroX25519PublicKey), - }, isBoringSSL ? { code: 'ERR_OSSL_EVP_INVALID_PEER_KEY' } : - hasOpenSSL(3) ? - { code: 'ERR_OSSL_FAILED_DURING_DERIVATION' } : - { message: /Deriving bits failed/ }); + }, isBoringSSL() ? { code: 'ERR_OSSL_EVP_INVALID_PEER_KEY' } : + { code: 'ERR_OSSL_FAILED_DURING_DERIVATION' }); } } diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index f5d239f1d457..f83f46873d6d 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -7,13 +7,13 @@ if (!common.hasCrypto) { const assert = require('assert'); const crypto = require('crypto'); const { - hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); { const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + 2048 : (crypto.getFips() === 1 || !isBoringSSL() ? 1024 : 256); const dh1 = crypto.createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); const dh2 = crypto.createDiffieHellman(p1, 'buffer'); @@ -59,7 +59,7 @@ const { assert.strictEqual(secret1, secret4); let wrongBlockLength; - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { wrongBlockLength = { message: /wrong[\s_]final[\s_]block[\s_]length/i, code: /ERR_OSSL_(EVP_)?WRONG_FINAL_BLOCK_LENGTH/, @@ -100,7 +100,7 @@ const { // Through a fluke of history, g=0 defaults to DH_GENERATOR (2). { const g = 0; - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { assert.throws(() => crypto.createDiffieHellman('abcdef', g), { code: 'ERR_CRYPTO_OPERATION_FAILED', name: 'Error' @@ -112,7 +112,7 @@ const { } { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { assert.throws(() => crypto.createDiffieHellman('abcdef', Buffer.from([2])), { code: 'ERR_CRYPTO_OPERATION_FAILED', name: 'Error' diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js deleted file mode 100644 index 06c88272438a..000000000000 --- 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-eddsa-variants.js b/test/parallel/test-crypto-eddsa-variants.js index 3a75a7bf4f6f..5942e15ba280 100644 --- a/test/parallel/test-crypto-eddsa-variants.js +++ b/test/parallel/test-crypto-eddsa-variants.js @@ -8,6 +8,7 @@ const crypto = require('crypto'); const { hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); // RFC 8032 Section 7 test vectors for Ed25519, Ed25519ctx, and Ed448. @@ -180,7 +181,7 @@ function createKeyPair(algorithm, secretKeyHex, publicKeyHex) { } for (const v of vectors) { - if (v.algorithm.startsWith('Ed448') && process.features.openssl_is_boringssl) continue; + if (v.algorithm.startsWith('Ed448') && isBoringSSL()) continue; if (v.algorithm.endsWith('ctx') || v.context) { if (!hasOpenSSL(3, 2)) continue; } diff --git a/test/parallel/test-crypto-encap-decap.js b/test/parallel/test-crypto-encap-decap.js index 7cafa0f2aa93..a4f3b4131965 100644 --- a/test/parallel/test-crypto-encap-decap.js +++ b/test/parallel/test-crypto-encap-decap.js @@ -6,17 +6,11 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const { promisify } = require('util'); -const isBoringSSL = process.features.openssl_is_boringssl; const isFips = hasFIPS(3); -if (!hasOpenSSL(3) && !isBoringSSL) { - assert.throws(() => crypto.encapsulate(), { code: 'ERR_CRYPTO_KEM_NOT_SUPPORTED' }); - return; -} - assert.throws(() => crypto.encapsulate(), { code: 'ERR_INVALID_ARG_TYPE', message: /The "key" argument must be of type/ }); assert.throws(() => crypto.decapsulate(), { code: 'ERR_INVALID_ARG_TYPE', @@ -24,7 +18,7 @@ assert.throws(() => crypto.decapsulate(), { code: 'ERR_INVALID_ARG_TYPE', const keys = { 'rsa': { - supported: hasOpenSSL(3), // RSASVE was added in 3.0 + supported: !isBoringSSL(), // BoringSSL does not support RSASVE publicKey: fixtures.readKey('rsa_public_2048.pem', 'ascii'), privateKey: fixtures.readKey('rsa_private_2048.pem', 'ascii'), sharedSecretLength: 256, @@ -90,7 +84,7 @@ const keys = { raw: true, }, 'ml-kem-768': { - supported: hasOpenSSL(3, 5) || isBoringSSL, + supported: hasOpenSSL(3, 5) || isBoringSSL(), publicKey: fixtures.readKey('ml_kem_768_public.pem', 'ascii'), privateKey: fixtures.readKey('ml_kem_768_private_seed_only.pem', 'ascii'), sharedSecretLength: 32, @@ -98,7 +92,7 @@ const keys = { raw: true, }, 'ml-kem-1024': { - supported: hasOpenSSL(3, 5) || isBoringSSL, + supported: hasOpenSSL(3, 5) || isBoringSSL(), publicKey: fixtures.readKey('ml_kem_1024_public.pem', 'ascii'), privateKey: fixtures.readKey('ml_kem_1024_private_seed_only.pem', 'ascii'), sharedSecretLength: 32, diff --git a/test/parallel/test-crypto-fips-indicator-strict.js b/test/parallel/test-crypto-fips-indicator-strict.js index cc65d0016269..9fbcc83b63f2 100644 --- a/test/parallel/test-crypto-fips-indicator-strict.js +++ b/test/parallel/test-crypto-fips-indicator-strict.js @@ -6,7 +6,13 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +const { + isBoringSSL, + hasFIPS, + hasOpenSSL, +} = require('../common/crypto'); + +if (isBoringSSL()) { common.skip('BoringSSL does not support FIPS'); } @@ -18,7 +24,6 @@ const { Worker } = require('node:worker_threads'); const { spawnSyncAndExitWithoutError, } = require('../common/child_process'); -const { hasFIPS, hasOpenSSL } = require('../common/crypto'); const channelName = 'crypto.fips.indicator'; const mode = process.env.NODE_TEST_FIPS_FORCE_MODE; @@ -26,7 +31,7 @@ const mode = process.env.NODE_TEST_FIPS_FORCE_MODE; if (!hasOpenSSL(3, 4)) { common.skip('OpenSSL 3.4 or later is required'); } else if (!hasFIPS(3, 4)) { - common.skip('an active OpenSSL 3.4+ FIPS provider is required'); + common.skip('an active OpenSSL FIPS provider is required'); } else if (mode === 'provider') { assertSerializedMode(mode); assert.strictEqual( diff --git a/test/parallel/test-crypto-fips.js b/test/parallel/test-crypto-fips.js index ea20d895b1c8..af5de599de47 100644 --- a/test/parallel/test-crypto-fips.js +++ b/test/parallel/test-crypto-fips.js @@ -4,35 +4,24 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support FIPS'); const assert = require('assert'); const spawnSync = require('child_process').spawnSync; const path = require('path'); const { spawnSyncAndAssert } = require('../common/child_process'); -const fixtures = require('../common/fixtures'); const { internalBinding } = require('internal/test/binding'); const { testFipsCrypto } = internalBinding('crypto'); -const { hasOpenSSL, 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 = - hasOpenSSL3 ? - '--enable-fips requires an active OpenSSL provider named "fips"' : - 'OpenSSL error when trying to enable FIPS:'; + '--enable-fips requires an active OpenSSL provider named "fips"'; const FIPS_FORCE_ERROR_STRING = - hasOpenSSL3 ? - '--force-fips requires an active OpenSSL provider named "fips"' : - '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'); + '--force-fips requires an active OpenSSL provider named "fips"'; const kNoFailure = 0; const kGenericUserError = 1; @@ -146,23 +135,21 @@ if (!sharedOpenSSL()) { 'require("crypto").getFips()', { ...process.env, 'OPENSSL_CONF': ' ' }); - if (hasOpenSSL3) { - // Disabling FIPS mode should not throw after OpenSSL updates the default - // property query. - testHelper( - 'stdout', - [], - kNoFailure, - FIPS_DISABLED, - '(() => {' + - 'const crypto = require("crypto");' + - 'crypto.setFips(true);' + - 'require("assert").strictEqual(crypto.getFips(), 1);' + - 'crypto.setFips(false);' + - 'return crypto.getFips();' + - '})()', - { ...process.env, 'OPENSSL_CONF': ' ' }); - } + // Disabling FIPS mode should not throw after OpenSSL updates the default + // property query. + testHelper( + 'stdout', + [], + kNoFailure, + FIPS_DISABLED, + '(() => {' + + 'const crypto = require("crypto");' + + 'crypto.setFips(true);' + + 'require("assert").strictEqual(crypto.getFips(), 1);' + + 'crypto.setFips(false);' + + 'return crypto.getFips();' + + '})()', + { ...process.env, 'OPENSSL_CONF': ' ' }); } // Toggling fips with setFips should not be allowed from a worker thread @@ -174,202 +161,6 @@ testHelper( '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 +// This should succeed whether FIPS is enabled or disabled. 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-getcipherinfo.js b/test/parallel/test-crypto-getcipherinfo.js index 5afd2e5a4208..3f234168489f 100644 --- a/test/parallel/test-crypto-getcipherinfo.js +++ b/test/parallel/test-crypto-getcipherinfo.js @@ -10,7 +10,7 @@ const { getCiphers, getCipherInfo, } = require('crypto'); -const { hasFIPS, hasOpenSSL3 } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); @@ -18,7 +18,7 @@ const ciphers = getCiphers(); assert.strictEqual(getCipherInfo(-1), undefined); assert.strictEqual(getCipherInfo('cipher that does not exist'), undefined); -if (hasOpenSSL3) { +if (!isBoringSSL()) { assert.deepStrictEqual( ciphers.filter((cipher) => cipher.includes('cbc-hmac')), []); for (const cipher of [ @@ -54,7 +54,7 @@ if (ciphers.includes('aes-128-wrap-inv')) { } assert(!ciphers.some((cipher) => /^\d+(?:\.\d+)+$/.test(cipher))); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // A failed provider fetch must not contaminate the OpenSSL error queue. assert.throws(() => createHash('sha256', { outputLength: 28 }), { code: 'ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH', @@ -63,7 +63,7 @@ if (!process.features.openssl_is_boringssl) { for (const cipher of ciphers) { const info = getCipherInfo(cipher); - if (process.features.openssl_is_boringssl && !info) { + if (isBoringSSL() && !info) { // BoringSSL reports some legacy ciphers in getCiphers() but returns no // info for them (e.g. des-ede3, des-ede3-ecb, rc2-40-cbc). common.printSkipMessage(`Skipping unsupported ${cipher} test case`); @@ -115,7 +115,7 @@ assert(getCipherInfo('aes-128-cbc', { ivLength: 16 })); assert(!getCipherInfo('aes-128-ccm', { ivLength: 1 })); assert(!getCipherInfo('aes-128-ccm', { ivLength: 14 })); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { for (let n = 7; n <= 13; n++) assert(getCipherInfo('aes-128-ccm', { ivLength: n })); } else { @@ -126,7 +126,7 @@ assert(!getCipherInfo('aes-128-ocb', { ivLength: 16 })); if (hasFIPS(3)) { assert.strictEqual( getCipherInfo('aes-128-ocb', { ivLength: 12 }), undefined); -} else if (!process.features.openssl_is_boringssl) { +} else if (!isBoringSSL()) { for (let n = 1; n < 16; n++) assert(getCipherInfo('aes-128-ocb', { ivLength: n })); } else { diff --git a/test/parallel/test-crypto-hash-stream-pipe.js b/test/parallel/test-crypto-hash-stream-pipe.js index ac851646a918..94fc28306dde 100644 --- a/test/parallel/test-crypto-hash-stream-pipe.js +++ b/test/parallel/test-crypto-hash-stream-pipe.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -30,10 +32,10 @@ const crypto = require('crypto'); const stream = require('stream'); const s = new stream.PassThrough(); -const h = process.features.openssl_is_boringssl ? +const h = isBoringSSL() ? crypto.createHash('sha512') : crypto.createHash('sha3-512'); -const expect = process.features.openssl_is_boringssl ? +const expect = isBoringSSL() ? 'fba055c6fd0c5b6645407749ed7a8b41' + 'b8f629f2163c3ca3701d864adabda1f8' + '93c37bf82b22fdd151ba8e357f611da4' + diff --git a/test/parallel/test-crypto-hash.js b/test/parallel/test-crypto-hash.js index 44734e7aeb6f..823e3daa9ba2 100644 --- a/test/parallel/test-crypto-hash.js +++ b/test/parallel/test-crypto-hash.js @@ -1,5 +1,7 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) { common.skip('missing crypto'); } @@ -189,7 +191,7 @@ assert.throws( } // Test XOF hash functions and the outputLength option. -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const invalidXofLength = { code: 'ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH', name: 'Error', diff --git a/test/parallel/test-crypto-hkdf.js b/test/parallel/test-crypto-hkdf.js index bfde3b324331..72409c904cbf 100644 --- a/test/parallel/test-crypto-hkdf.js +++ b/test/parallel/test-crypto-hkdf.js @@ -13,7 +13,7 @@ const { hkdfSync, getHashes } = require('crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); { assert.throws(() => hkdf(), { @@ -125,9 +125,6 @@ const algorithms = [ ['sha256', '', 'salt', '', 10], ['sha512', 'secret', 'salt', '', 15], ]; -if (!hasOpenSSL(3) && !process.features.openssl_is_boringssl) - algorithms.push(['whirlpool', 'secret', '', 'info', 20]); - algorithms.forEach(([ hash, secret, salt, info, length ]) => { { const syncResult = hkdfSync(hash, secret, salt, info, length); @@ -216,7 +213,7 @@ algorithms.forEach(([ hash, secret, salt, info, length ]) => { }); -if (!hasOpenSSL(3)) { +if (isBoringSSL()) { const kKnownUnsupported = ['shake128', 'shake256']; for (const hash of getHashes()) { if (kKnownUnsupported.includes(hash)) continue; diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index 1e19b3e972da..116daa5f3113 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -69,19 +69,6 @@ function testHmac(algo, key, data, expected) { '19fd6e1ba73d9ed2224dd5094a71babe85d9a892'); } -{ - // Historically, dss1 and DSS1 are SHA-1 aliases. - const key = '0123456789abcdef'; - const expected = - crypto.createHmac('sha1', key).update('data').digest('hex'); - - for (const algo of ['dss1', 'DSS1']) { - assert.strictEqual( - crypto.createHmac(algo, key).update('data').digest('hex'), - expected); - } -} - // Test HMAC (Wikipedia Test Cases) const wikipedia = [ { diff --git a/test/parallel/test-crypto-job-error-parity.js b/test/parallel/test-crypto-job-error-parity.js index ee9bd27bba6b..0495ab4144d3 100644 --- a/test/parallel/test-crypto-job-error-parity.js +++ b/test/parallel/test-crypto-job-error-parity.js @@ -8,7 +8,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const crypto = require('crypto'); const fixtures = require('../common/fixtures'); @@ -195,7 +195,7 @@ const data = Buffer.from('test data'); } // === crypto.encapsulate / crypto.decapsulate === -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { // KEM: Decapsulate with wrong private key type { const rsaPublicKey = crypto.createPublicKey( diff --git a/test/parallel/test-crypto-key-objects-raw.js b/test/parallel/test-crypto-key-objects-raw.js index 024d5f6f199f..8d4ce01733d8 100644 --- a/test/parallel/test-crypto-key-objects-raw.js +++ b/test/parallel/test-crypto-key-objects-raw.js @@ -7,7 +7,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); // EC: NIST and OpenSSL curve names are both recognized for raw-public and raw-private { @@ -67,7 +67,7 @@ const { hasOpenSSL } = require('../common/crypto'); ['x25519', 'x25519_public.pem'], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { rawPublicKeys.push( ['ed448', 'ed448_public.pem'], ['x448', 'x448_public.pem'], @@ -76,7 +76,7 @@ const { hasOpenSSL } = require('../common/crypto'); common.printSkipMessage('Skipping unsupported ed448/x448 test cases'); } - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { rawPublicKeys.push( ['ml-dsa-44', 'ml_dsa_44_public.pem'], ['ml-kem-768', 'ml_kem_768_public.pem'], @@ -122,7 +122,7 @@ if (hasOpenSSL(3, 5)) { const unsupportedKeyTypes = [ ['rsa', 'rsa_public_2048.pem', 'rsa_private_2048.pem'], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { unsupportedKeyTypes.push(['dsa', 'dsa_public.pem', 'dsa_private.pem']); } else { common.printSkipMessage('Skipping unsupported dsa test case'); @@ -148,7 +148,7 @@ if (hasOpenSSL(3, 5)) { } // DH keys also don't support raw formats - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { const privKeyObj = crypto.createPrivateKey( fixtures.readKey('dh_private.pem', 'ascii')); assert.throws(() => privKeyObj.export({ format: 'raw-private' }), @@ -170,7 +170,7 @@ if (hasOpenSSL(3, 5)) { // PQC import throws when PQC is not supported if (!hasOpenSSL(3, 5)) { - const unsupported = process.features.openssl_is_boringssl ? + const unsupported = isBoringSSL() ? // BoringSSL supports ML-DSA and ML-KEM-{768,1024}, but not ML-KEM-512 or SLH-DSA. ['ml-kem-512', 'slh-dsa-sha2-128f', 'slh-dsa-shake-128f'] : [ @@ -232,7 +232,7 @@ if (!hasOpenSSL(3, 5)) { } // ML-KEM: public keys of different type cannot be imported as the other type -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { const mlKem768Pub = crypto.createPublicKey( fixtures.readKey('ml_kem_768_public.pem', 'ascii')); const mlKem1024Pub = crypto.createPublicKey( @@ -251,7 +251,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { } // ML-DSA: -44 and -65 public keys cannot be imported as the other type -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { const mlDsa44Pub = crypto.createPublicKey( fixtures.readKey('ml_dsa_44_public.pem', 'ascii')); const mlDsa65Pub = crypto.createPublicKey( @@ -333,10 +333,10 @@ if (hasOpenSSL(3, 5)) { namedCurve: 'P-256', }), { code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS' }); - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { common.printSkipMessage('Skipping unsupported ed448/x448 test cases'); } - for (const type of process.features.openssl_is_boringssl ? + for (const type of isBoringSSL() ? ['ed25519', 'x25519'] : ['ed25519', 'ed448', 'x25519', 'x448']) { const priv = crypto.createPrivateKey( @@ -364,7 +364,7 @@ if (hasOpenSSL(3, 5)) { } // raw-private cannot be used for ml-kem and ml-dsa -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { for (const type of ['ml-kem-768', 'ml-dsa-44']) { const priv = crypto.createPrivateKey( fixtures.readKey(`${type.replaceAll('-', '_')}_private_seed_only.pem`, 'ascii')); @@ -472,7 +472,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { { code: 'ERR_INVALID_ARG_VALUE' }); // PQC raw-seed -> createPublicKey - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { const mlDsaPriv = crypto.createPrivateKey( fixtures.readKey('ml_dsa_44_private_seed_only.pem', 'ascii')); const mlDsaPub = crypto.createPublicKey( @@ -521,10 +521,10 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { // x25519, ed25519, x448, and ed448 cannot be used as 'ec' namedCurve values { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { common.printSkipMessage('Skipping unsupported ed448/x448 test cases'); } - for (const type of process.features.openssl_is_boringssl ? + for (const type of isBoringSSL() ? ['ed25519', 'x25519'] : ['ed25519', 'x25519', 'ed448', 'x448']) { const priv = crypto.createPrivateKey( diff --git a/test/parallel/test-crypto-key-objects.js b/test/parallel/test-crypto-key-objects.js index ba9a05387f21..5a84d5e24ef4 100644 --- a/test/parallel/test-crypto-key-objects.js +++ b/test/parallel/test-crypto-key-objects.js @@ -25,8 +25,8 @@ const { } = require('crypto'); const { - hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); const fips3 = hasFIPS(3); @@ -349,20 +349,14 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', // This should not cause a crash: https://github.com/nodejs/node/issues/25247 assert.throws(() => { createPrivateKey({ key: '' }); - }, hasOpenSSL(3) ? { - message: 'error:1E08010C:DECODER routines::unsupported', - } : process.features.openssl_is_boringssl ? { + }, isBoringSSL() ? { message: 'error:0900006e:PEM routines:OPENSSL_internal:NO_START_LINE', code: 'ERR_OSSL_PEM_NO_START_LINE', reason: 'NO_START_LINE', library: 'PEM routines', function: 'OPENSSL_internal', } : { - message: 'error:0909006C:PEM routines:get_name:no start line', - code: 'ERR_OSSL_PEM_NO_START_LINE', - reason: 'no start line', - library: 'PEM routines', - function: 'get_name', + message: 'error:1E08010C:DECODER routines::unsupported', }); // This should not abort either: https://github.com/nodejs/node/issues/29904 @@ -381,15 +375,12 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', type: 'pkcs1' }); createPrivateKey({ key, format: 'der', type: 'pkcs1' }); - }, hasOpenSSL(3) ? { - message: /error:1E08010C:DECODER routines::unsupported/, - library: 'DECODER routines' - } : process.features.openssl_is_boringssl ? { + }, isBoringSSL() ? { library: 'public key routines', message: 'error:06000066:public key routines:OPENSSL_internal:DECODE_ERROR' } : { - message: /asn1 encoding/, - library: 'asn1 encoding routines' + message: /error:1E08010C:DECODER routines::unsupported/, + library: 'DECODER routines' }); } @@ -439,7 +430,7 @@ for (const info of [ const fipsUnsupported = rejectsXCurves && keyType.startsWith('x'); - if (process.features.openssl_is_boringssl && keyType.endsWith('448')) { + if (isBoringSSL() && keyType.endsWith('448')) { common.printSkipMessage(`Skipping unsupported ${keyType} test case`); continue; } @@ -631,7 +622,7 @@ for (const info of [ const { keyType, namedCurve } = info; const fipsUnsupported = fips3 && namedCurve === 'secp256k1'; - if (process.features.openssl_is_boringssl && !getCurves().includes(namedCurve)) { + if (isBoringSSL() && !getCurves().includes(namedCurve)) { common.printSkipMessage(`Skipping unsupported ${keyType} test case`); continue; } @@ -790,14 +781,14 @@ for (const info of [ { // Reading an encrypted key without a passphrase should fail. - assert.throws(() => createPrivateKey(privateDsa), hasOpenSSL(3) ? { - name: 'Error', - message: 'error:07880109:common libcrypto routines::interrupted or ' + - 'cancelled', - } : { + assert.throws(() => createPrivateKey(privateDsa), isBoringSSL() ? { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' + } : { + name: 'Error', + message: 'error:07880109:common libcrypto routines::interrupted or ' + + 'cancelled', }); // Reading an encrypted key with a passphrase that exceeds OpenSSL's buffer @@ -806,10 +797,10 @@ for (const info of [ key: privateDsa, format: 'pem', passphrase: Buffer.alloc(1025, 'a') - }), hasOpenSSL(3) ? { name: 'Error' } : { + }), isBoringSSL() ? { code: 'ERR_OSSL_PEM_BAD_PASSWORD_READ', name: 'Error' - }); + } : { name: 'Error' }); // The buffer has a size of 1024 bytes, so this passphrase should be permitted // (but will fail decryption). @@ -861,7 +852,7 @@ for (const info of [ { code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE' }); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // Test RSA-PSS. { // This key pair does not restrict the message digest algorithm or salt diff --git a/test/parallel/test-crypto-key-store-pkcs11.js b/test/parallel/test-crypto-key-store-pkcs11.js index 0fec81a9c647..db6969c28b76 100644 --- a/test/parallel/test-crypto-key-store-pkcs11.js +++ b/test/parallel/test-crypto-key-store-pkcs11.js @@ -3,9 +3,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 0)) - common.skip('requires OpenSSL 3.x'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL provider support is required'); // The PKCS#11 token, the OpenSSL configuration that activates a provider for // it, and the PIN that unlocks it are all provided by the environment. See diff --git a/test/parallel/test-crypto-key-store.js b/test/parallel/test-crypto-key-store.js index 58a23192b28f..a6efce940506 100644 --- a/test/parallel/test-crypto-key-store.js +++ b/test/parallel/test-crypto-key-store.js @@ -2,9 +2,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasFIPS, hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - common.skip('requires OpenSSL 3.x'); +const { hasFIPS, hasOpenSSL, isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL provider support is required'); // Verifies that crypto.createPrivateKey() can pass a WHATWG URL (here a file: // URI) to an OpenSSL STORE loader, and that the resulting KeyObject works for diff --git a/test/parallel/test-crypto-keygen-async-dsa-key-object.js b/test/parallel/test-crypto-keygen-async-dsa-key-object.js index ea35facbdc7e..1aa6620c12af 100644 --- a/test/parallel/test-crypto-keygen-async-dsa-key-object.js +++ b/test/parallel/test-crypto-keygen-async-dsa-key-object.js @@ -4,7 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('not supported by BoringSSL'); const assert = require('assert'); @@ -12,25 +14,23 @@ const { generateKeyPair, } = require('crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); - // Test async DSA key object generation. { generateKeyPair('dsa', { - modulusLength: hasOpenSSL3 ? 2048 : 512, + modulusLength: 2048, divisorLength: 256 }, common.mustSucceed((publicKey, privateKey) => { assert.strictEqual(publicKey.type, 'public'); assert.strictEqual(publicKey.asymmetricKeyType, 'dsa'); assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { - modulusLength: hasOpenSSL3 ? 2048 : 512, + modulusLength: 2048, divisorLength: 256 }); assert.strictEqual(privateKey.type, 'private'); assert.strictEqual(privateKey.asymmetricKeyType, 'dsa'); assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { - modulusLength: hasOpenSSL3 ? 2048 : 512, + modulusLength: 2048, divisorLength: 256 }); })); diff --git a/test/parallel/test-crypto-keygen-async-dsa.js b/test/parallel/test-crypto-keygen-async-dsa.js index 6c7129c7efba..201436b4339e 100644 --- a/test/parallel/test-crypto-keygen-async-dsa.js +++ b/test/parallel/test-crypto-keygen-async-dsa.js @@ -4,21 +4,20 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) - common.skip('not supported by BoringSSL'); - -const assert = require('assert'); -const { - generateKeyPair, -} = require('crypto'); const { + isBoringSSL, assertApproximateSize, testSignVerify, spkiExp, } = require('../common/crypto'); -const { hasOpenSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('not supported by BoringSSL'); +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); // Test async DSA key generation. { const privateKeyEncoding = { @@ -27,7 +26,7 @@ const { hasOpenSSL } = require('../common/crypto'); }; generateKeyPair('dsa', { - modulusLength: hasOpenSSL(3) ? 2048 : 512, + modulusLength: 2048, divisorLength: 256, publicKeyEncoding: { type: 'spki', @@ -44,8 +43,8 @@ const { hasOpenSSL } = require('../common/crypto'); // The private key is DER-encoded. assert(Buffer.isBuffer(privateKeyDER)); - assertApproximateSize(publicKey, hasOpenSSL(3) ? 1194 : 440); - assertApproximateSize(privateKeyDER, hasOpenSSL(3) ? 721 : 336); + assertApproximateSize(publicKey, 1194); + assertApproximateSize(privateKeyDER, 721); // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => { diff --git a/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk-ec.js b/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk-ec.js index bde6dc1d694b..2821307850f3 100644 --- a/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk-ec.js +++ b/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk-ec.js @@ -8,12 +8,12 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); // Test async elliptic curve key generation with 'jwk' encoding and named // curve. for (const curve of ['P-384', 'P-256', 'P-521', 'secp256k1']) { - if (process.features.openssl_is_boringssl && curve === 'secp256k1') { + if (isBoringSSL() && curve === 'secp256k1') { common.printSkipMessage(`Skipping unsupported ${curve} test case`); continue; } diff --git a/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk.js b/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk.js index cfef18c889b6..188a5747650a 100644 --- a/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk.js +++ b/test/parallel/test-crypto-keygen-async-elliptic-curve-jwk.js @@ -8,13 +8,13 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const rejectsXCurves = hasFIPS(3, 5); // Test async elliptic curve key generation with 'jwk' encoding. { for (const type of ['ed25519', 'ed448', 'x25519', 'x448']) { - if (process.features.openssl_is_boringssl && type.endsWith('448')) { + if (isBoringSSL() && type.endsWith('448')) { common.printSkipMessage(`Skipping unsupported ${type} test case`); continue; } diff --git a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js index 246cbe5dd1ac..0f5b7fc49f13 100644 --- a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js +++ b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js @@ -4,21 +4,20 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) - common.skip('BoringSSL does not support paramEncoding: explicit'); - -const assert = require('assert'); -const { - generateKeyPair, -} = require('crypto'); const { + isBoringSSL, testSignVerify, spkiExp, pkcs8EncExp, } = require('../common/crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('BoringSSL does not support paramEncoding: explicit'); +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); // Test async elliptic curve key generation, e.g. for ECDSA, with an encrypted // private key with paramEncoding explicit. { @@ -43,13 +42,9 @@ const { hasOpenSSL3 } = require('../common/crypto'); // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => testSignVerify(publicKey, privateKey), - hasOpenSSL3 ? { + { message: 'error:07880109:common libcrypto ' + 'routines::interrupted or cancelled' - } : { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' }); testSignVerify(publicKey, { diff --git a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted.js.js b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted.js.js index 081e709f46ec..60606c760b85 100644 --- a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted.js.js +++ b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted.js.js @@ -4,21 +4,22 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) - common.skip('BoringSSL does not support paramEncoding: explicit'); - -const assert = require('assert'); -const { - generateKeyPair, -} = require('crypto'); const { + isBoringSSL, hasFIPS, testSignVerify, spkiExp, sec1EncExp, - hasOpenSSL, } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('BoringSSL does not support paramEncoding: explicit'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + { // Test async explicit elliptic curve key generation with an encrypted // private key. @@ -48,13 +49,9 @@ const { // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => testSignVerify(publicKey, privateKey), - hasOpenSSL(3) ? { + { message: 'error:07880109:common libcrypto ' + 'routines::interrupted or cancelled' - } : { - name: 'TypeError', - code: 'ERR_MISSING_PASSPHRASE', - message: 'Passphrase required for encrypted key' }); testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' }); diff --git a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve.js b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve.js index 8084cdfc0b3b..3835d07c85ee 100644 --- a/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve.js +++ b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve.js @@ -4,18 +4,20 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { + isBoringSSL, + testSignVerify, + spkiExp, + sec1Exp, +} = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support paramEncoding: explicit'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { - testSignVerify, - spkiExp, - sec1Exp, -} = require('../common/crypto'); // Test async explicit elliptic curve key generation, e.g. for ECDSA, // with a SEC1 private key with paramEncoding explicit. diff --git a/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js b/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js index 4c11401d0fc5..4dcc2917b093 100644 --- a/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js +++ b/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js @@ -12,7 +12,7 @@ const { testSignVerify, spkiExp, pkcs8EncExp, - hasOpenSSL3, + isBoringSSL, } = require('../common/crypto'); // Test async elliptic curve key generation, e.g. for ECDSA, with an encrypted @@ -39,13 +39,13 @@ const { // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => testSignVerify(publicKey, privateKey), - hasOpenSSL3 ? { - message: 'error:07880109:common libcrypto ' + - 'routines::interrupted or cancelled' - } : { + isBoringSSL() ? { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' + } : { + message: 'error:07880109:common libcrypto ' + + 'routines::interrupted or cancelled' }); testSignVerify(publicKey, { diff --git a/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted.js b/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted.js index 84ea9d2f7a9a..3a365c5cca22 100644 --- a/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted.js +++ b/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted.js @@ -13,7 +13,7 @@ const { testSignVerify, spkiExp, sec1EncExp, - hasOpenSSL, + isBoringSSL, } = require('../common/crypto'); { @@ -45,13 +45,13 @@ const { // Since the private key is encrypted, signing shouldn't work anymore. assert.throws(() => testSignVerify(publicKey, privateKey), - hasOpenSSL(3) ? { - message: 'error:07880109:common libcrypto ' + - 'routines::interrupted or cancelled' - } : { + isBoringSSL() ? { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' + } : { + message: 'error:07880109:common libcrypto ' + + 'routines::interrupted or cancelled' }); testSignVerify(publicKey, { key: privateKey, passphrase: 'secret' }); diff --git a/test/parallel/test-crypto-keygen-async-rsa.js b/test/parallel/test-crypto-keygen-async-rsa.js index 7a372ded9fc5..328f68884479 100644 --- a/test/parallel/test-crypto-keygen-async-rsa.js +++ b/test/parallel/test-crypto-keygen-async-rsa.js @@ -14,7 +14,7 @@ const { testEncryptDecrypt, testSignVerify, pkcs1EncExp, - hasOpenSSL, + isBoringSSL, } = require('../common/crypto'); // Test async RSA key generation with an encrypted private key. @@ -51,14 +51,14 @@ const { type: 'pkcs1', format: 'der', }; - const expectedError = hasOpenSSL(3) ? { - name: 'Error', - message: 'error:07880109:common libcrypto routines::interrupted or ' + - 'cancelled' - } : { + const expectedError = isBoringSSL() ? { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' + } : { + name: 'Error', + message: 'error:07880109:common libcrypto routines::interrupted or ' + + 'cancelled' }; assert.throws(() => testSignVerify(publicKey, privateKey), expectedError); diff --git a/test/parallel/test-crypto-keygen-bit-length.js b/test/parallel/test-crypto-keygen-bit-length.js index 52765f3d7fe7..47953d24bf57 100644 --- a/test/parallel/test-crypto-keygen-bit-length.js +++ b/test/parallel/test-crypto-keygen-bit-length.js @@ -4,7 +4,12 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { + isBoringSSL, + hasFIPS, +} = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support arbitrary RSA modulus length ' + 'or RSA-PSS/DSA key generation'); @@ -12,8 +17,6 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); - const fips3 = hasFIPS(3); // This tests check that generateKeyPair returns correct bit length in @@ -44,18 +47,16 @@ const fips3 = hasFIPS(3); assert.strictEqual(publicKey.asymmetricKeyDetails.modulusLength, 513); })); - if (hasOpenSSL(3)) { - generateKeyPair('dsa', { - modulusLength: 2049, - divisorLength: 256, - }, common.mustCall((err, publicKey, privateKey) => { - if (fips3) { - assert.strictEqual(err?.code, 'ERR_OSSL_DSA_BAD_FFC_PARAMETERS'); - return; - } - assert.ifError(err); - assert.strictEqual(privateKey.asymmetricKeyDetails.modulusLength, 2049); - assert.strictEqual(publicKey.asymmetricKeyDetails.modulusLength, 2049); - })); - } + generateKeyPair('dsa', { + modulusLength: 2049, + divisorLength: 256, + }, common.mustCall((err, publicKey, privateKey) => { + if (fips3) { + assert.strictEqual(err?.code, 'ERR_OSSL_DSA_BAD_FFC_PARAMETERS'); + return; + } + assert.ifError(err); + assert.strictEqual(privateKey.asymmetricKeyDetails.modulusLength, 2049); + assert.strictEqual(publicKey.asymmetricKeyDetails.modulusLength, 2049); + })); } diff --git a/test/parallel/test-crypto-keygen-dh-classic.js b/test/parallel/test-crypto-keygen-dh-classic.js index 13c5db2d0603..7c6373f82555 100644 --- a/test/parallel/test-crypto-keygen-dh-classic.js +++ b/test/parallel/test-crypto-keygen-dh-classic.js @@ -4,14 +4,15 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support DH key pair generation'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); // Test classic Diffie-Hellman key generation. { diff --git a/test/parallel/test-crypto-keygen-eddsa.js b/test/parallel/test-crypto-keygen-eddsa.js index 5dbdf9a7aeea..d51ff6ce58e2 100644 --- a/test/parallel/test-crypto-keygen-eddsa.js +++ b/test/parallel/test-crypto-keygen-eddsa.js @@ -8,13 +8,13 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const rejectsXCurves = hasFIPS(3, 5); // Test EdDSA key generation. { for (const keyType of ['ed25519', 'ed448', 'x25519', 'x448']) { - if (process.features.openssl_is_boringssl && keyType.endsWith('448')) { + if (isBoringSSL() && keyType.endsWith('448')) { common.printSkipMessage(`Skipping unsupported ${keyType} test case`); continue; } diff --git a/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js b/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js index ccf98bcd3766..2feddbd9bec6 100644 --- a/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js +++ b/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js @@ -12,7 +12,7 @@ const { const { hasFIPS, testSignVerify, - hasOpenSSL, + isBoringSSL, } = require('../common/crypto'); const fips4 = hasFIPS(4); @@ -56,14 +56,14 @@ for (const type of ['pkcs1', 'pkcs8']) { // the key, and not specifying a passphrase should fail when decoding it. assert.throws(() => { return testSignVerify(publicKey, privateKey); - }, hasOpenSSL(3) ? { - name: 'Error', - code: 'ERR_OSSL_CRYPTO_INTERRUPTED_OR_CANCELLED', - message: 'error:07880109:common libcrypto routines::interrupted or cancelled' - } : { + }, isBoringSSL() ? { name: 'TypeError', code: 'ERR_MISSING_PASSPHRASE', message: 'Passphrase required for encrypted key' + } : { + name: 'Error', + code: 'ERR_OSSL_CRYPTO_INTERRUPTED_OR_CANCELLED', + message: 'error:07880109:common libcrypto routines::interrupted or cancelled' }); })); } diff --git a/test/parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js b/test/parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js index 9d1fdf23bc0b..c24c9bbc9498 100644 --- a/test/parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js +++ b/test/parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js @@ -4,7 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support DSA key pair generation'); const assert = require('assert'); @@ -12,7 +14,6 @@ const assert = require('assert'); const { generateKeyPairSync, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); const fips3 = hasFIPS(3); diff --git a/test/parallel/test-crypto-keygen-missing-oid.js b/test/parallel/test-crypto-keygen-missing-oid.js index afe95dbee40f..6b2a8823a3a4 100644 --- a/test/parallel/test-crypto-keygen-missing-oid.js +++ b/test/parallel/test-crypto-keygen-missing-oid.js @@ -11,36 +11,34 @@ const { getCurves, } = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); // This test creates EC key pairs on curves without associated OIDs. // Specifying a key encoding should not crash. { - if (process.versions.openssl >= '1.1.1i') { - for (const namedCurve of ['Oakley-EC2N-3', 'Oakley-EC2N-4']) { - if (!getCurves().includes(namedCurve)) - continue; + for (const namedCurve of ['Oakley-EC2N-3', 'Oakley-EC2N-4']) { + if (!getCurves().includes(namedCurve)) + continue; - const expectedErrorCode = - hasFIPS(3) ? 'ERR_OSSL_EC_UNKNOWN_GROUP' : - hasOpenSSL(3) ? 'ERR_OSSL_MISSING_OID' : 'ERR_OSSL_EC_MISSING_OID'; - const params = { - namedCurve, - publicKeyEncoding: { - format: 'der', - type: 'spki' - } - }; + const expectedErrorCode = + hasFIPS(3) ? 'ERR_OSSL_EC_UNKNOWN_GROUP' : + isBoringSSL() ? 'ERR_OSSL_EC_MISSING_OID' : 'ERR_OSSL_MISSING_OID'; + const params = { + namedCurve, + publicKeyEncoding: { + format: 'der', + type: 'spki' + } + }; - assert.throws(() => { - generateKeyPairSync('ec', params); - }, { - code: expectedErrorCode - }); + assert.throws(() => { + generateKeyPairSync('ec', params); + }, { + code: expectedErrorCode + }); - generateKeyPair('ec', params, common.mustCall((err) => { - assert.strictEqual(err.code, expectedErrorCode); - })); - } + generateKeyPair('ec', params, common.mustCall((err) => { + assert.strictEqual(err.code, expectedErrorCode); + })); } } diff --git a/test/parallel/test-crypto-keygen-no-rsassa-pss-params.js b/test/parallel/test-crypto-keygen-no-rsassa-pss-params.js index 778899972863..892397164ef8 100644 --- a/test/parallel/test-crypto-keygen-no-rsassa-pss-params.js +++ b/test/parallel/test-crypto-keygen-no-rsassa-pss-params.js @@ -4,14 +4,15 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support RSA-PSS key pair generation'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); // 'rsa-pss' should not add a RSASSA-PSS-params sequence by default. // Regression test for: https://github.com/nodejs/node/issues/39936 diff --git a/test/parallel/test-crypto-keygen-raw.js b/test/parallel/test-crypto-keygen-raw.js index 41ef9362dcac..8ee2e71247fd 100644 --- a/test/parallel/test-crypto-keygen-raw.js +++ b/test/parallel/test-crypto-keygen-raw.js @@ -11,14 +11,14 @@ const { createPublicKey, createPrivateKey, } = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const rejectsXCurves = hasFIPS(3, 5); // Test generateKeyPairSync with raw encoding for EdDSA/ECDH key types. { const types = ['ed25519', 'x25519']; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { types.push('ed448', 'x448'); } for (const type of types) { @@ -59,7 +59,7 @@ const rejectsXCurves = hasFIPS(3, 5); // Test async generateKeyPair with raw encoding for EdDSA/ECDH key types. { const types = ['ed25519', 'x25519']; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { types.push('ed448', 'x448'); } for (const type of types) { @@ -174,7 +174,7 @@ const rejectsXCurves = hasFIPS(3, 5); } // Test error: raw with DSA. -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { assert.throws(() => generateKeyPairSync('dsa', { modulusLength: 2048, publicKeyEncoding: { format: 'raw-public' }, @@ -221,7 +221,7 @@ if (!process.features.openssl_is_boringssl) { } // PQC key types -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { // Test raw encoding for ML-DSA key types (raw-public + raw-seed only). { for (const type of ['ml-dsa-44', 'ml-dsa-65', 'ml-dsa-87']) { @@ -248,7 +248,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { // Test raw encoding for ML-KEM key types (raw-public + raw-seed only). { for (const type of ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']) { - if (process.features.openssl_is_boringssl && type === 'ml-kem-512') { + if (isBoringSSL() && type === 'ml-kem-512') { common.printSkipMessage(`Skipping unsupported ${type} test case`); continue; } @@ -275,7 +275,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { // Test raw encoding for SLH-DSA key types. { for (const type of ['slh-dsa-sha2-128f', 'slh-dsa-shake-128f']) { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { common.printSkipMessage(`Skipping unsupported ${type} test case`); continue; } @@ -290,7 +290,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { } // Test error: raw-seed with SLH-DSA (not supported). - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { assert.throws(() => generateKeyPairSync('slh-dsa-sha2-128f', { publicKeyEncoding: { format: 'raw-public' }, privateKeyEncoding: { format: 'raw-seed' }, diff --git a/test/parallel/test-crypto-keygen-rfc8017-9-1.js b/test/parallel/test-crypto-keygen-rfc8017-9-1.js index 3234084afe10..10836ba41f1a 100644 --- a/test/parallel/test-crypto-keygen-rfc8017-9-1.js +++ b/test/parallel/test-crypto-keygen-rfc8017-9-1.js @@ -4,14 +4,15 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support RSA-PSS key pair generation'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); // RFC 8017, 9.1.: "Assuming that the mask generation function is based on a // hash function, it is RECOMMENDED that the hash function be the same as the diff --git a/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js b/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js index f7cb70560e7e..e1da437827c2 100644 --- a/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js +++ b/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js @@ -4,14 +4,15 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support RSA-PSS key pair generation'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const { hasFIPS } = require('../common/crypto'); // RFC 8017, A.2.3.: "For a given hashAlgorithm, the default value of // saltLength is the octet length of the hash value." diff --git a/test/parallel/test-crypto-keygen-rsa-pss.js b/test/parallel/test-crypto-keygen-rsa-pss.js index 88d522a223b9..147253ba032d 100644 --- a/test/parallel/test-crypto-keygen-rsa-pss.js +++ b/test/parallel/test-crypto-keygen-rsa-pss.js @@ -4,7 +4,14 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) +const { + isBoringSSL, + hasFIPS, + testEncryptDecrypt, + testSignVerify, +} = require('../common/crypto'); + +if (isBoringSSL()) common.skip('BoringSSL does not support RSA-PSS key pair generation'); const assert = require('assert'); @@ -12,11 +19,6 @@ const { constants, generateKeyPair, } = require('crypto'); -const { - hasFIPS, - testEncryptDecrypt, - testSignVerify, -} = require('../common/crypto'); // Test RSA-PSS. { diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index c525a54aa434..e73ed2651901 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -14,8 +14,7 @@ const { } = require('crypto'); const { inspect } = require('util'); -const { hasOpenSSL3 } = require('../common/crypto'); -const isBoringSSL = process.features.openssl_is_boringssl; +const { isBoringSSL } = require('../common/crypto'); // Test invalid parameter encoding. { @@ -376,12 +375,7 @@ const isBoringSSL = process.features.openssl_is_boringssl; } // Test invalid exponents. (caught by OpenSSL) - let invalidExponentError = /bad e value/; - if (isBoringSSL) { - invalidExponentError = /BAD_E_VALUE/; - } else if (hasOpenSSL3) { - invalidExponentError = /exponent/; - } + const invalidExponentError = isBoringSSL() ? /BAD_E_VALUE/ : /exponent/; for (const publicExponent of [1, 1 + 0x10001]) { generateKeyPair('rsa', { modulusLength: 4096, @@ -516,7 +510,7 @@ const isBoringSSL = process.features.openssl_is_boringssl; }); })); - if (isBoringSSL) { + if (isBoringSSL()) { common.printSkipMessage('Skipping secp256k1 keygen test case ' + 'unsupported by BoringSSL'); } else { diff --git a/test/parallel/test-crypto-mac-cache-snapshot.js b/test/parallel/test-crypto-mac-cache-snapshot.js index 1fd37367d2a8..0af858997416 100644 --- a/test/parallel/test-crypto-mac-cache-snapshot.js +++ b/test/parallel/test-crypto-mac-cache-snapshot.js @@ -4,9 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); -if (!hasOpenSSL3 || process.features.openssl_is_boringssl) - common.skip('this test requires OpenSSL 3 EVP_MAC support'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL EVP_MAC support is required'); const assert = require('node:assert'); const { getMacs } = require('node:crypto'); diff --git a/test/parallel/test-crypto-mac-cache.js b/test/parallel/test-crypto-mac-cache.js index dfe99e943bb2..f255d00e78a3 100644 --- a/test/parallel/test-crypto-mac-cache.js +++ b/test/parallel/test-crypto-mac-cache.js @@ -5,9 +5,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); -if (!hasOpenSSL3 || process.features.openssl_is_boringssl) - common.skip('this test requires OpenSSL 3 EVP_MAC support'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL EVP_MAC support is required'); const assert = require('node:assert'); const { once } = require('node:events'); diff --git a/test/parallel/test-crypto-mac-errors.js b/test/parallel/test-crypto-mac-errors.js index 43e464bb737e..ff1637892138 100644 --- a/test/parallel/test-crypto-mac-errors.js +++ b/test/parallel/test-crypto-mac-errors.js @@ -6,10 +6,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 3 EVP_MAC support is required'); +if (isBoringSSL()) { + common.skip('OpenSSL EVP_MAC support is required'); } const assert = require('node:assert'); diff --git a/test/parallel/test-crypto-mac-unsupported.js b/test/parallel/test-crypto-mac-unsupported.js index 68bb79f301e5..738dc2f3c1cc 100644 --- a/test/parallel/test-crypto-mac-unsupported.js +++ b/test/parallel/test-crypto-mac-unsupported.js @@ -6,9 +6,9 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (hasOpenSSL3 && !process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { common.skip('this test requires a build without EVP_MAC support'); } diff --git a/test/parallel/test-crypto-mac-vectors.js b/test/parallel/test-crypto-mac-vectors.js index ec9f0cffe877..d45017ff4c4e 100644 --- a/test/parallel/test-crypto-mac-vectors.js +++ b/test/parallel/test-crypto-mac-vectors.js @@ -8,10 +8,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 3 EVP_MAC support is required'); +if (isBoringSSL()) { + common.skip('OpenSSL EVP_MAC support is required'); } const assert = require('node:assert'); diff --git a/test/parallel/test-crypto-mac.js b/test/parallel/test-crypto-mac.js index f41bd86509eb..3dd444fa4ff5 100644 --- a/test/parallel/test-crypto-mac.js +++ b/test/parallel/test-crypto-mac.js @@ -8,10 +8,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 3 EVP_MAC support is required'); +if (isBoringSSL()) { + common.skip('OpenSSL EVP_MAC support is required'); } const assert = require('node:assert'); diff --git a/test/parallel/test-crypto-negative-zero.js b/test/parallel/test-crypto-negative-zero.js index 0af9220569c3..cdfd0fced950 100644 --- a/test/parallel/test-crypto-negative-zero.js +++ b/test/parallel/test-crypto-negative-zero.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); function getOutcome(fn) { try { @@ -88,9 +88,9 @@ function assertSameErrorOrSuccess(actual, expected) { ); } - if (!hasOpenSSL(3)) { + if (isBoringSSL()) { common.printSkipMessage( - 'Skipping DSA divisorLength 0 key generation on OpenSSL 1.1.1'); + 'BoringSSL does not support DSA key pair generation'); } else { assertSameErrorOrSuccess( getOutcome(() => crypto.generateKeyPairSync('dsa', { @@ -110,7 +110,7 @@ function assertSameErrorOrSuccess(actual, expected) { })); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { assert.strictEqual( crypto.createHash('shake128', { outputLength: -0 }).digest('hex'), '', diff --git a/test/parallel/test-crypto-no-algorithm.js b/test/parallel/test-crypto-no-algorithm.js index 90d19ff97fcb..9889b97307a6 100644 --- a/test/parallel/test-crypto-no-algorithm.js +++ b/test/parallel/test-crypto-no-algorithm.js @@ -4,10 +4,10 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL3) - common.skip('this test requires OpenSSL 3.x'); +if (isBoringSSL()) + common.skip('this test requires OpenSSL'); const assert = require('node:assert/strict'); const crypto = require('node:crypto'); diff --git a/test/parallel/test-crypto-oneshot-hash-xof.js b/test/parallel/test-crypto-oneshot-hash-xof.js index 656e7944396e..4c1101a5412e 100644 --- a/test/parallel/test-crypto-oneshot-hash-xof.js +++ b/test/parallel/test-crypto-oneshot-hash-xof.js @@ -1,13 +1,15 @@ 'use strict'; + // This tests crypto.hash() works. const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const crypto = require('crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { common.skip('BoringSSL does not support XOF hash functions'); } diff --git a/test/parallel/test-crypto-padding.js b/test/parallel/test-crypto-padding.js index 6e7a7fffee58..809cf8c63c5e 100644 --- a/test/parallel/test-crypto-padding.js +++ b/test/parallel/test-crypto-padding.js @@ -26,7 +26,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); // Input data. const ODD_LENGTH_PLAIN = 'Hello node world!'; @@ -83,14 +83,14 @@ assert.strictEqual(enc(EVEN_LENGTH_PLAIN, true), EVEN_LENGTH_ENCRYPTED); assert.throws(function() { // Input must have block length %. enc(ODD_LENGTH_PLAIN, false); -}, hasOpenSSL3 ? { - message: /wrong[\s_]final[\s_]block[\s_]length/i, - code: /ERR_OSSL(_EVP)?_WRONG_FINAL_BLOCK_LENGTH/, - reason: /wrong[\s_]final[\s_]block[\s_]length/i, -} : { +}, isBoringSSL() ? { message: /data[\s_]not[\s_]multiple[\s_]of[\s_]block[\s_]length/i, code: /ERR_OSSL(_EVP)?_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH/, reason: /data[\s_]not[\s_]multiple[\s_]of[\s_]block[\s_]length/i, +} : { + message: /wrong[\s_]final[\s_]block[\s_]length/i, + code: /ERR_OSSL(_EVP)?_WRONG_FINAL_BLOCK_LENGTH/, + reason: /wrong[\s_]final[\s_]block[\s_]length/i, } ); diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js index 7cd1206f4f02..a2be86dbc3f6 100644 --- a/test/parallel/test-crypto-pbkdf2.js +++ b/test/parallel/test-crypto-pbkdf2.js @@ -6,8 +6,8 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); const { - hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); const fips4 = hasFIPS(4); @@ -331,7 +331,7 @@ assert.throws( } ); -if (!hasOpenSSL(3)) { +if (isBoringSSL()) { const kNotPBKDF2Supported = ['shake128', 'shake256']; crypto.getHashes() .filter((hash) => !kNotPBKDF2Supported.includes(hash)) diff --git a/test/parallel/test-crypto-pqc-encrypted-pkcs8.js b/test/parallel/test-crypto-pqc-encrypted-pkcs8.js index 8f2a10725c94..78dbd6f540c6 100644 --- a/test/parallel/test-crypto-pqc-encrypted-pkcs8.js +++ b/test/parallel/test-crypto-pqc-encrypted-pkcs8.js @@ -4,9 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); @@ -21,7 +21,7 @@ const algorithms = new Set([ 'ml-kem-512', 'ml-kem-768', 'ml-kem-1024', ]); // BoringSSL does not support ML-KEM-512. -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { algorithms.delete('ml-kem-512'); } diff --git a/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js index f2a19799c515..79eb4fdf322d 100644 --- a/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js +++ b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js @@ -4,7 +4,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { @@ -100,14 +100,14 @@ for (const [asymmetricKeyType, pubLen] of [ } } - if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { + if (!hasOpenSSL(3, 5) && !isBoringSSL()) { assert.throws(() => createPublicKey(keys.public), { - code: hasOpenSSL(3) ? 'ERR_OSSL_EVP_DECODE_ERROR' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: 'ERR_OSSL_EVP_DECODE_ERROR', }); for (const pem of [keys.private, keys.private_seed_only, keys.private_priv_only]) { assert.throws(() => createPrivateKey(pem), { - code: hasOpenSSL(3) ? 'ERR_OSSL_UNSUPPORTED' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: 'ERR_OSSL_UNSUPPORTED', }); } } else { @@ -120,7 +120,7 @@ for (const [asymmetricKeyType, pubLen] of [ [keys.private_seed_only, true, true], [keys.private_priv_only, false, false], ]) { - if (process.features.openssl_is_boringssl && !seedOnly) { + if (isBoringSSL() && !seedOnly) { common.printSkipMessage('Skipping unsupported private key format test'); continue; } diff --git a/test/parallel/test-crypto-pqc-key-objects-ml-kem.js b/test/parallel/test-crypto-pqc-key-objects-ml-kem.js index 81353b5115dd..6fdd7c824056 100644 --- a/test/parallel/test-crypto-pqc-key-objects-ml-kem.js +++ b/test/parallel/test-crypto-pqc-key-objects-ml-kem.js @@ -4,7 +4,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { @@ -100,17 +100,17 @@ for (const [asymmetricKeyType, pubLen] of [ } } - if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { + if (!hasOpenSSL(3, 5) && !isBoringSSL()) { assert.throws(() => createPublicKey(keys.public), { - code: hasOpenSSL(3) ? 'ERR_OSSL_EVP_DECODE_ERROR' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: 'ERR_OSSL_EVP_DECODE_ERROR', }); for (const pem of [keys.private, keys.private_seed_only, keys.private_priv_only]) { assert.throws(() => createPrivateKey(pem), { - code: hasOpenSSL(3) ? 'ERR_OSSL_UNSUPPORTED' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: 'ERR_OSSL_UNSUPPORTED', }); } - } else if (process.features.openssl_is_boringssl && asymmetricKeyType === 'ml-kem-512') { + } else if (isBoringSSL() && asymmetricKeyType === 'ml-kem-512') { // BoringSSL does not support ML-KEM-512. assert.throws(() => createPublicKey(keys.public), { code: 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM' }); @@ -123,7 +123,7 @@ for (const [asymmetricKeyType, pubLen] of [ assertPublicKey(publicKey); { - const entries = process.features.openssl_is_boringssl ? + const entries = isBoringSSL() ? // BoringSSL only supports the seed-only PKCS#8 private key encoding. [[keys.private_seed_only, true]] : [ diff --git a/test/parallel/test-crypto-pqc-key-objects-slh-dsa.js b/test/parallel/test-crypto-pqc-key-objects-slh-dsa.js index eff309468c31..7c5e5155e346 100644 --- a/test/parallel/test-crypto-pqc-key-objects-slh-dsa.js +++ b/test/parallel/test-crypto-pqc-key-objects-slh-dsa.js @@ -4,7 +4,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { @@ -101,11 +101,11 @@ for (const asymmetricKeyType of [ if (!hasOpenSSL(3, 5)) { assert.throws(() => createPublicKey(keys.public), { - code: hasOpenSSL(3) ? 'ERR_OSSL_EVP_DECODE_ERROR' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: isBoringSSL() ? 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM' : 'ERR_OSSL_EVP_DECODE_ERROR', }); assert.throws(() => createPrivateKey(keys.private), { - code: hasOpenSSL(3) ? 'ERR_OSSL_UNSUPPORTED' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM', + code: isBoringSSL() ? 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM' : 'ERR_OSSL_UNSUPPORTED', }); } else { const publicKey = createPublicKey(keys.public); diff --git a/test/parallel/test-crypto-pqc-keygen-ml-dsa.js b/test/parallel/test-crypto-pqc-keygen-ml-dsa.js index e6534c988c4e..c21cb0706dad 100644 --- a/test/parallel/test-crypto-pqc-keygen-ml-dsa.js +++ b/test/parallel/test-crypto-pqc-keygen-ml-dsa.js @@ -4,14 +4,14 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { +if (!hasOpenSSL(3, 5) && !isBoringSSL()) { for (const asymmetricKeyType of ['ml-dsa-44', 'ml-dsa-65', 'ml-dsa-87']) { assert.throws(() => generateKeyPair(asymmetricKeyType, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', diff --git a/test/parallel/test-crypto-pqc-keygen-ml-kem.js b/test/parallel/test-crypto-pqc-keygen-ml-kem.js index 620f65c3a8d1..483c9c0904c3 100644 --- a/test/parallel/test-crypto-pqc-keygen-ml-kem.js +++ b/test/parallel/test-crypto-pqc-keygen-ml-kem.js @@ -4,19 +4,19 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { generateKeyPair, } = require('crypto'); -const algorithms = process.features.openssl_is_boringssl ? +const algorithms = isBoringSSL() ? // BoringSSL does not support ML-KEM-512. ['ml-kem-768', 'ml-kem-1024'] : ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']; -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { +if (!hasOpenSSL(3, 5) && !isBoringSSL()) { for (const asymmetricKeyType of ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']) { assert.throws(() => generateKeyPair(asymmetricKeyType, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', @@ -72,7 +72,7 @@ if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { } } -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { assert.throws(() => generateKeyPair('ml-kem-512', common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE', message: /The argument 'type' must be a supported key type/ diff --git a/test/parallel/test-crypto-pqc-sign-verify-ml-dsa.js b/test/parallel/test-crypto-pqc-sign-verify-ml-dsa.js index 535e6a33d5cc..a979280a2d5c 100644 --- a/test/parallel/test-crypto-pqc-sign-verify-ml-dsa.js +++ b/test/parallel/test-crypto-pqc-sign-verify-ml-dsa.js @@ -4,9 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); @@ -39,7 +39,7 @@ for (const [asymmetricKeyType, sigLen] of [ [keys.private_seed_only, true], [keys.private_priv_only, false], ]) { - if (process.features.openssl_is_boringssl && !seedOnly) { + if (isBoringSSL() && !seedOnly) { common.printSkipMessage('Skipping unsupported private key format test'); continue; } @@ -52,7 +52,7 @@ for (const [asymmetricKeyType, sigLen] of [ assert.strictEqual(verify(undefined, data, keys.public, Buffer.alloc(sigLen)), false); assert.strictEqual(verify(undefined, data, keys.public, signature), true); assert.strictEqual(verify(undefined, data, privateKey, signature), true); - const code = process.features.openssl_is_boringssl ? + const code = isBoringSSL() ? 'ERR_OSSL_EVP_COMMAND_NOT_SUPPORTED' : 'ERR_OSSL_INVALID_DIGEST'; assert.throws(() => sign('sha256', data, privateKey), { code }); assert.throws( @@ -72,7 +72,7 @@ for (const [asymmetricKeyType, sigLen] of [ })); })); - const message = process.features.openssl_is_boringssl ? /COMMAND_NOT_SUPPORTED/ : /invalid digest/; + const message = isBoringSSL() ? /COMMAND_NOT_SUPPORTED/ : /invalid digest/; sign('sha256', data, privateKey, common.expectsError(message)); verify('sha256', data, keys.public, Buffer.alloc(sigLen), common.expectsError(message)); } diff --git a/test/parallel/test-crypto-prime.js b/test/parallel/test-crypto-prime.js index 6f43e3a0bfbf..870f4494ce73 100644 --- a/test/parallel/test-crypto-prime.js +++ b/test/parallel/test-crypto-prime.js @@ -5,6 +5,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); +const { isBoringSSL } = require('../common/crypto'); const { generatePrime, @@ -165,7 +166,7 @@ generatePrime( // The behavior when specifying only add without rem should depend on the // safe option. - if (process.versions.openssl >= '1.1.1f') { + if (!isBoringSSL()) { generatePrime(128, { bigint: true, add: 5n @@ -215,7 +216,7 @@ generatePrime( code: 'ERR_OUT_OF_RANGE' }); - if (process.versions.openssl >= '1.1.1f') { + if (!isBoringSSL()) { // This is possible and allowed (but makes little sense). assert.strictEqual(generatePrimeSync(4, { add: 15n, diff --git a/test/parallel/test-crypto-private-decrypt-gh32240.js b/test/parallel/test-crypto-private-decrypt-gh32240.js index a38fcba6775e..c2a4d0165984 100644 --- a/test/parallel/test-crypto-private-decrypt-gh32240.js +++ b/test/parallel/test-crypto-private-decrypt-gh32240.js @@ -15,8 +15,8 @@ const { } = require('crypto'); const { - hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); const fips3 = hasFIPS(3); @@ -64,8 +64,8 @@ function decrypt(key) { } decrypt(pkey); -assert.throws(() => decrypt(pkeyEncrypted), hasOpenSSL(3) ? +assert.throws(() => decrypt(pkeyEncrypted), isBoringSSL() ? + { code: 'ERR_MISSING_PASSPHRASE' } : { message: 'error:07880109:common libcrypto routines::interrupted or ' + - 'cancelled' } : - { code: 'ERR_MISSING_PASSPHRASE' }); + 'cancelled' }); decrypt(pkey); // Should not throw. diff --git a/test/parallel/test-crypto-provider-cipher-cache-snapshot.js b/test/parallel/test-crypto-provider-cipher-cache-snapshot.js index 1afc5df8d94d..f17a96542070 100644 --- a/test/parallel/test-crypto-provider-cipher-cache-snapshot.js +++ b/test/parallel/test-crypto-provider-cipher-cache-snapshot.js @@ -5,13 +5,13 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { buildSnapshot, runWithSnapshot } = require('../common/snapshot'); -if (!hasOpenSSL3) - common.skip('this test requires OpenSSL 3.x'); +if (isBoringSSL()) + common.skip('OpenSSL provider support is required'); const entry = fixtures.path('snapshot', 'crypto-provider-cipher-cache.js'); const buildEnv = { diff --git a/test/parallel/test-crypto-provider-cipher-cache.js b/test/parallel/test-crypto-provider-cipher-cache.js index bde9988480ed..7e673de757c4 100644 --- a/test/parallel/test-crypto-provider-cipher-cache.js +++ b/test/parallel/test-crypto-provider-cipher-cache.js @@ -5,9 +5,9 @@ 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 { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL provider support is required'); const assert = require('assert'); const { diff --git a/test/parallel/test-crypto-provider-hash-options.js b/test/parallel/test-crypto-provider-hash-options.js index 609d00d7f7b0..e801e49a8b6c 100644 --- a/test/parallel/test-crypto-provider-hash-options.js +++ b/test/parallel/test-crypto-provider-hash-options.js @@ -3,13 +3,15 @@ const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); + if (!common.hasCrypto) { common.skip('missing crypto'); } if (Number(process.versions.openssl.split('.')[0]) < 4 || - process.features.openssl_is_boringssl) { - common.skip('OpenSSL 4 provider support is required'); + isBoringSSL()) { + common.skip('OpenSSL 4.0 or later is required'); } const assert = require('node:assert'); diff --git a/test/parallel/test-crypto-provider-hashes.js b/test/parallel/test-crypto-provider-hashes.js index 166efaa0d7fd..d51bf2384238 100644 --- a/test/parallel/test-crypto-provider-hashes.js +++ b/test/parallel/test-crypto-provider-hashes.js @@ -26,10 +26,10 @@ const { sign, verify, } = require('node:crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL3 || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 3 provider support is required'); +if (isBoringSSL()) { + common.skip('OpenSSL provider support is required'); } const { internalBinding } = require('internal/test/binding'); diff --git a/test/parallel/test-crypto-publicDecrypt-fails-first-time.js b/test/parallel/test-crypto-publicDecrypt-fails-first-time.js index 21cc5f3ebce2..c819f9ee2e74 100644 --- a/test/parallel/test-crypto-publicDecrypt-fails-first-time.js +++ b/test/parallel/test-crypto-publicDecrypt-fails-first-time.js @@ -7,10 +7,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) { - common.skip('only openssl3'); // https://github.com/nodejs/node/pull/42793#issuecomment-1107491901 +if (isBoringSSL()) { + common.skip('this test is not supported with BoringSSL'); // https://github.com/nodejs/node/pull/42793#issuecomment-1107491901 } const assert = require('assert'); diff --git a/test/parallel/test-crypto-rsa-dsa.js b/test/parallel/test-crypto-rsa-dsa.js index bda98652cf59..e2e43eaff9a4 100644 --- a/test/parallel/test-crypto-rsa-dsa.js +++ b/test/parallel/test-crypto-rsa-dsa.js @@ -12,12 +12,11 @@ const fixtures = require('../common/fixtures'); const { hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); const fips3 = hasFIPS(3); const fips35 = hasFIPS(3, 5); -const fips30 = fips3 && !fips35; const fips4 = hasFIPS(4); -const fipsDigestErrorCode = 'ERR_OSSL_DIGEST_NOT_ALLOWED'; const wrongPassphrase = 'wrong-password'; // Test certificates @@ -62,34 +61,25 @@ if (fips3) { } } -const openssl1DecryptError = { - message: 'error:06065064:digital envelope routines:EVP_DecryptFinal_ex:' + - 'bad decrypt', - code: 'ERR_OSSL_EVP_BAD_DECRYPT', - reason: 'bad decrypt', - function: 'EVP_DecryptFinal_ex', - library: 'digital envelope routines', -}; - const decryptError = fips4 ? - { code: 'ERR_OSSL_BAD_DECRYPT' } : hasOpenSSL(3) ? - { message: 'error:1C800064:Provider routines::bad decrypt' } : - process.features.openssl_is_boringssl ? { - message: 'error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT', - code: 'ERR_OSSL_BAD_DECRYPT', - reason: 'BAD_DECRYPT', - function: 'OPENSSL_internal', - library: 'Cipher functions', - } : - openssl1DecryptError; + { code: 'ERR_OSSL_BAD_DECRYPT' } : + isBoringSSL() ? { + message: 'error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT', + code: 'ERR_OSSL_BAD_DECRYPT', + reason: 'BAD_DECRYPT', + function: 'OPENSSL_internal', + library: 'Cipher functions', + } : { + message: 'error:1C800064:Provider routines::bad decrypt', + }; const decryptPrivateKeyError = fips4 ? { code: 'ERR_OSSL_BAD_DECRYPT', -} : hasOpenSSL(3) ? { - message: 'error:1C800064:Provider routines::bad decrypt', -} : process.features.openssl_is_boringssl ? { +} : isBoringSSL() ? { message: 'error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT', -} : openssl1DecryptError; +} : { + message: 'error:1C800064:Provider routines::bad decrypt', +}; function getBufferCopy(buf) { return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); @@ -190,10 +180,8 @@ function getBufferCopy(buf) { }, encryptedBuffer); assert.strictEqual(decryptedBufferWithPassword.toString(), input); - // Now with RSA_NO_PADDING. Plaintext needs to match key size. - // OpenSSL 3.x has a rsa_check_padding that will cause an error if - // RSA_NO_PADDING is used. - if (!hasOpenSSL(3)) { + // BoringSSL does not apply OpenSSL's rsa_check_padding validation here. + if (isBoringSSL()) { { const plaintext = 'x'.repeat(rsaKeySize / 8); encryptedBuffer = crypto.privateEncrypt({ @@ -373,7 +361,7 @@ function test_rsa(padding, encryptOaepHash, decryptOaepHash) { test_rsa('RSA_NO_PADDING'); test_rsa('RSA_PKCS1_OAEP_PADDING'); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { test_rsa('RSA_PKCS1_PADDING'); } else { common.printSkipMessage('Skipping unsupported RSA_PKCS1_PADDING test case'); @@ -548,7 +536,7 @@ assert.throws(() => { // // Test DSA signing and verification // -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const input = 'I AM THE WALRUS'; // DSA signatures vary across runs so there is no static string to verify @@ -563,21 +551,6 @@ if (!process.features.openssl_is_boringssl) { assert.strictEqual(verify.verify(dsaPubPem, signature, 'hex'), true); - // Test the legacy 'DSS1' name. - const sign2 = crypto.createSign('DSS1'); - sign2.update(input); - if (fips30) { - assert.throws(() => sign2.sign(dsaKeyPem, 'hex'), { - code: fipsDigestErrorCode, - }); - } else { - const signature2 = sign2.sign(dsaKeyPem, 'hex'); - - const verify2 = crypto.createVerify('DSS1'); - verify2.update(input); - - assert.strictEqual(verify2.verify(dsaPubPem, signature2, 'hex'), true); - } } else { common.printSkipMessage('Skipping unsupported DSA test case'); } @@ -586,7 +559,7 @@ if (!process.features.openssl_is_boringssl) { // // Test DSA signing and verification with PKCS#8 private key // -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const input = 'I AM THE WALRUS'; // DSA signatures vary across runs so there is no static string to verify @@ -618,7 +591,7 @@ const input = 'I AM THE WALRUS'; }, decryptPrivateKeyError); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // DSA signatures vary across runs so there is no static string to verify // against. const dsaDigest = fips3 ? 'SHA256' : 'SHA1'; diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js index 3012a8fa55d5..d69e66b4925a 100644 --- a/test/parallel/test-crypto-scrypt.js +++ b/test/parallel/test-crypto-scrypt.js @@ -5,7 +5,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const isFips = hasFIPS(3); if (typeof crypto.scrypt !== 'function' || typeof crypto.scryptSync !== 'function') @@ -203,7 +203,7 @@ for (const options of toobig) { const expected = isFips ? { code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS', } : { - message: process.features.openssl_is_boringssl ? + message: isBoringSSL() ? /Invalid scrypt params:.*(INVALID_PARAMETERS|MEMORY_LIMIT_EXCEEDED)/ : /Invalid scrypt params:.*memory limit exceeded/, code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS', diff --git a/test/parallel/test-crypto-sec-level.js b/test/parallel/test-crypto-sec-level.js index f2c0e3900624..809a0c589023 100644 --- a/test/parallel/test-crypto-sec-level.js +++ b/test/parallel/test-crypto-sec-level.js @@ -2,6 +2,8 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -11,11 +13,11 @@ 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(); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { assert.strictEqual(secLevel, 0); } else { assert.ok(secLevel >= 0 && secLevel <= 5); diff --git a/test/parallel/test-crypto-secure-heap.js b/test/parallel/test-crypto-secure-heap.js index 8bd93c5281da..cd4e5a2ee082 100644 --- a/test/parallel/test-crypto-secure-heap.js +++ b/test/parallel/test-crypto-secure-heap.js @@ -13,18 +13,21 @@ if (common.isASan) { common.skip('ASan does not play well with secure heap allocations'); } -if (process.features.openssl_is_boringssl) { +const { + isBoringSSL, + hasFIPS, +} = require('../common/crypto'); + +if (isBoringSSL()) { common.skip('BoringSSL does not support secure heap'); } const assert = require('assert'); const { fork } = require('child_process'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); const { secureHeapUsed, createDiffieHellman, - getFips, } = require('crypto'); if (process.argv[2] === 'child') { @@ -38,8 +41,7 @@ if (process.argv[2] === 'child') { assert.strictEqual(a.used, 0); { - const size = hasFIPS(3) ? - 2048 : (getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + const size = hasFIPS(3) ? 2048 : 1024; const dh1 = createDiffieHellman(size); const p1 = dh1.getPrime('buffer'); const dh2 = createDiffieHellman(p1, 'buffer'); diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index e8398c21bafd..8493a91d24f8 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -12,6 +12,7 @@ const { hasOpenSSL, hasFIPS, opensslCli, + isBoringSSL, } = require('../common/crypto'); // Test certificates @@ -78,11 +79,9 @@ if (fips30) { key: keyPem, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }); - }, { message: hasOpenSSL(3) ? - 'error:1C8000A5:Provider routines::illegal or unsupported padding mode' : - process.features.openssl_is_boringssl ? - 'error:0600006d:public key routines:OPENSSL_internal:ILLEGAL_OR_UNSUPPORTED_PADDING_MODE' : - 'bye, bye, error stack' }); + }, { message: isBoringSSL() ? + 'error:0600006d:public key routines:OPENSSL_internal:ILLEGAL_OR_UNSUPPORTED_PADDING_MODE' : + 'error:1C8000A5:Provider routines::illegal or unsupported padding mode' }); delete Object.prototype.opensslErrorStack; } @@ -373,19 +372,12 @@ assert.throws( key: keyPem, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }); - }, hasOpenSSL(3) ? { - code: 'ERR_OSSL_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', - message: /illegal or unsupported padding mode/, - } : process.features.openssl_is_boringssl ? { + }, isBoringSSL() ? { code: 'ERR_OSSL_EVP_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', message: /ILLEGAL_OR_UNSUPPORTED_PADDING_MODE/, } : { - code: 'ERR_OSSL_RSA_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', + code: 'ERR_OSSL_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE', message: /illegal or unsupported padding mode/, - opensslErrorStack: [ - 'error:06089093:digital envelope routines:EVP_PKEY_CTX_ctrl:' + - 'command not supported', - ], }); } @@ -460,7 +452,7 @@ for (const pair of [ raw: true }, { private: fixtures.readKey('ed448_private.pem', 'ascii'), public: fixtures.readKey('ed448_public.pem', 'ascii'), - skip: process.features.openssl_is_boringssl, + skip: isBoringSSL(), algo: null, supportsContext: hasOpenSSL(3, 2), sigLen: 114, @@ -681,7 +673,7 @@ if (hasOpenSSL(3, 2)) { // Preserve the current behavior from https://github.com/nodejs/node/issues/53761: // one-shot verify does not accept SM2 signatures produced by the streaming path. -if (hasOpenSSL(3) && crypto.getHashes().includes('sm3')) { +if (!isBoringSSL() && crypto.getHashes().includes('sm3')) { const data = Buffer.from('AABB'); const privateKey = crypto.createPrivateKey(`-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgbjCNHopgvyGVfLaP @@ -721,7 +713,7 @@ MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1fiOx1BhdoAvpolZdyX46aGWlNoa const keys = [['ec-key.pem', 64], dsaKey]; for (const [file, length] of keys) { - if (process.features.openssl_is_boringssl && file.startsWith('dsa_')) { + if (isBoringSSL() && file.startsWith('dsa_')) { common.printSkipMessage(`Skipping unsupported ${file} test case`); continue; } @@ -857,7 +849,7 @@ if (!opensslCli) { })); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // Test RSA-PSS. { // This key pair does not restrict the message digest algorithm or salt @@ -1022,7 +1014,7 @@ if (!process.features.openssl_is_boringssl) { // Ed25519 and Ed448 must use the one-shot methods const keys = [{ privateKey: fixtures.readKey('ed25519_private.pem', 'ascii'), publicKey: fixtures.readKey('ed25519_public.pem', 'ascii') }]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { keys.push({ privateKey: fixtures.readKey('ed448_private.pem', 'ascii'), publicKey: fixtures.readKey('ed448_public.pem', 'ascii') }); } else { @@ -1042,7 +1034,7 @@ if (!process.features.openssl_is_boringssl) { } } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { // Dh, x25519 and x448 should not be used for signing/verifying // https://github.com/nodejs/node/issues/53742 for (const algo of ['dh', 'x25519', 'x448']) { diff --git a/test/parallel/test-crypto-stream.js b/test/parallel/test-crypto-stream.js index ed0916b036a9..8abaf4b8a73a 100644 --- a/test/parallel/test-crypto-stream.js +++ b/test/parallel/test-crypto-stream.js @@ -28,7 +28,6 @@ if (!common.hasCrypto) { const assert = require('assert'); const stream = require('stream'); const crypto = require('crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); if (!crypto.getFips()) { // Small stream to buffer converter @@ -73,15 +72,10 @@ const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); const decipher = crypto.createDecipheriv('aes-128-cbc', badkey, iv); cipher.pipe(decipher) - .on('error', common.expectsError((hasOpenSSL3 || process.features.openssl_is_boringssl) ? { + .on('error', common.expectsError({ message: /bad[\s_]decrypt/i, library: /Provider routines|Cipher functions/, reason: /bad[\s_]decrypt/i, - } : { - message: /bad[\s_]decrypt/i, - function: 'EVP_DecryptFinal_ex', - library: 'digital envelope routines', - reason: /bad[\s_]decrypt/i, })); cipher.end('Papaya!'); // Should not cause an unhandled exception. diff --git a/test/parallel/test-crypto-x509.js b/test/parallel/test-crypto-x509.js index 353699cf9117..364f7ccc6f68 100644 --- a/test/parallel/test-crypto-x509.js +++ b/test/parallel/test-crypto-x509.js @@ -19,7 +19,7 @@ const { const assert = require('assert'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { readFileSync } = require('fs'); const cert = readFileSync(fixtures.path('keys', 'agent1-cert.pem')); @@ -28,8 +28,8 @@ const ca = readFileSync(fixtures.path('keys', 'ca1-cert.pem')); const privateKey = createPrivateKey(key); -if (!process.features.openssl_is_boringssl) { - const expectedPubkeys = hasOpenSSL3 ? [ +if (!isBoringSSL()) { + const expectedPubkeys = [ [ 'rsa_pss_cert_2048.pem', 292, @@ -40,17 +40,6 @@ if (!process.features.openssl_is_boringssl) { 342, 'da0bcd53fbe3969c7cc2730f86abc34e0e1c340264bbdfa3faf01484c2eeece0', ], - ] : [ - [ - 'rsa_pss_cert_2048.pem', - 294, - '4d4f2f076aced4f0df922b84b466b0a60ba4cb50a23d695ae12ddc5fff7aca14', - ], - [ - 'rsa_pss_cert_2048_sha256_sha256_16.pem', - 294, - 'd37942c3bd02bc25c724fcd31efd647824e536c13d62d9ad0b5db8c0900d3cba', - ], ]; for (const [name, length, digest] of expectedPubkeys) { @@ -88,7 +77,7 @@ emailAddress=ry@tinyclouds.org`; let infoAccessCheck = `OCSP - URI:http://ocsp.nodejs.org/ CA Issuers - URI:http://ca.nodejs.org/ca.cert`; -if (!hasOpenSSL3) +if (isBoringSSL()) infoAccessCheck += '\n'; const der = Buffer.from( @@ -156,7 +145,7 @@ const der = Buffer.from( assert.deepStrictEqual(x509.raw, der); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { assert.deepStrictEqual(x509.validFromDate, new Date('2022-09-03T21:40:37Z')); assert.deepStrictEqual(x509.validToDate, new Date('2296-06-17T21:40:37Z')); } @@ -399,10 +388,10 @@ tAt3hIKFD1bJt6c6WtMH2Su3syosWxmdmGk5ihslB00lvLpfj/wed8i3bkcB1doq UcXd/5qu2GhokrKU2cPttU+XAN2Om6a0 -----END CERTIFICATE-----`; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { const cert = new X509Certificate(certPem); assert.throws(() => cert.publicKey, { - message: hasOpenSSL3 ? /decode error/ : /wrong tag/, + message: /decode error/, name: 'Error' }); @@ -446,7 +435,7 @@ UidvpWWipVLZgK+oDks+bKTobcoXGW9oXobiIYqslXPy -----END CERTIFICATE-----`.trim(); const c1 = new X509Certificate(certPemUTCTime); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { assert.deepStrictEqual(c1.validFromDate, new Date('1949-12-25T23:59:58Z')); assert.deepStrictEqual(c1.validToDate, new Date('1950-01-01T23:59:58Z')); } @@ -483,7 +472,7 @@ CWwQO8JZjJqFtqtuzy2n+gLCvqePgG/gmSqHOPm2ZbLW -----END CERTIFICATE-----`.trim(); const c2 = new X509Certificate(certPemGeneralizedTime); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { assert.deepStrictEqual(c2.validFromDate, new Date('2049-12-26T00:00:01Z')); assert.deepStrictEqual(c2.validToDate, new Date('2050-01-02T00:00:01Z')); } diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 047f051d1e94..d9c02c0d7f32 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -29,7 +29,7 @@ const assert = require('assert'); const crypto = require('crypto'); const tls = require('tls'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const isFips = hasFIPS(3); // Test Certificates @@ -154,7 +154,7 @@ assert(crypto.getHashes().includes('sha1')); assert(crypto.getHashes().includes('sha256')); assert(!crypto.getHashes().includes('SHA1')); assert(!crypto.getHashes().includes('SHA256')); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { assert(crypto.getHashes().includes('RSA-SHA1')); assert(!crypto.getHashes().includes('rsa-sha1')); } @@ -230,7 +230,7 @@ assert.throws(() => { assert.throws(() => { throw err; }, { code: 'ERR_OSSL_INVALID_KEY_LENGTH', }); - } else if (process.features.openssl_is_boringssl) { + } else if (isBoringSSL()) { // BoringSSL rejects the tiny RSA key while decoding it, before signing. assert.throws(() => { throw err; }, { name: 'Error', @@ -244,25 +244,16 @@ assert.throws(() => { assert(Array.isArray(err.opensslErrorStack)); assert(err.opensslErrorStack.length > 0); } else { - if (!hasOpenSSL(3)) - assert.ok(!('opensslErrorStack' in err)); - assert.throws(() => { throw err; }, hasOpenSSL(3) ? { + assert.throws(() => { throw err; }, { name: 'Error', message: 'error:02000070:rsa routines::digest too big for rsa key', library: 'rsa routines', - } : { - name: 'Error', - message: /routines:RSA_sign:digest too big for rsa key$/, - library: /rsa routines/i, - function: 'RSA_sign', - reason: /digest[\s_]too[\s_]big[\s_]for[\s_]rsa[\s_]key/i, - code: 'ERR_OSSL_RSA_DIGEST_TOO_BIG_FOR_RSA_KEY' }); } return true; }); -if (!hasOpenSSL(3)) { +if (isBoringSSL()) { // The correct header inside `rsa_private_pkcs8_bad.pem` should have been // -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- // instead of @@ -270,32 +261,10 @@ if (!hasOpenSSL(3)) { const sha1_privateKey = fixtures.readKey('rsa_private_pkcs8_bad.pem', 'ascii'); - if (process.features.openssl_is_boringssl) { - // BoringSSL accepts the PKCS#8 payload despite the legacy PEM label. - const signature = crypto.createSign('sha1').sign(sha1_privateKey); - assert(Buffer.isBuffer(signature)); - assert.strictEqual(signature.length, 256); - } else { - assert.throws(() => { - // This would inject errors onto OpenSSL's error stack - crypto.createSign('sha1').sign(sha1_privateKey); - }, (err) => { - // Do the standard checks, but then do some custom checks afterwards. - assert.throws(() => { throw err; }, { - message: 'error:0D0680A8:asn1 encoding routines:asn1_check_tlen:' + - 'wrong tag', - library: 'asn1 encoding routines', - function: 'asn1_check_tlen', - reason: 'wrong tag', - code: 'ERR_OSSL_ASN1_WRONG_TAG', - }); - // Throws crypto error, so there is an opensslErrorStack property. - // The openSSL stack should have content. - assert(Array.isArray(err.opensslErrorStack)); - assert(err.opensslErrorStack.length > 0); - return true; - }); - } + // BoringSSL accepts the PKCS#8 payload despite the legacy PEM label. + const signature = crypto.createSign('sha1').sign(sha1_privateKey); + assert(Buffer.isBuffer(signature)); + assert.strictEqual(signature.length, 256); } // Make sure memory isn't released before being returned diff --git a/test/parallel/test-diagnostics-channel-crypto-fips-indicator.js b/test/parallel/test-diagnostics-channel-crypto-fips-indicator.js index 0d7366dd3438..2ad900cbf356 100644 --- a/test/parallel/test-diagnostics-channel-crypto-fips-indicator.js +++ b/test/parallel/test-diagnostics-channel-crypto-fips-indicator.js @@ -26,7 +26,7 @@ const channelName = 'crypto.fips.indicator'; if (!hasOpenSSL(3, 4)) { common.skip('OpenSSL 3.4 or later is required'); } else if (!hasFIPS(3, 4)) { - common.skip('an active OpenSSL 3.4+ FIPS provider is required'); + common.skip('an active OpenSSL FIPS provider is required'); } else if (!process.execArgv.includes('--enable-fips-indicator-events')) { spawnSyncAndExitWithoutError( process.execPath, diff --git a/test/parallel/test-dsa-fips-invalid-key.js b/test/parallel/test-dsa-fips-invalid-key.js index 3df51bfbed35..43ac7e22ced6 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-https-agent-additional-options.js b/test/parallel/test-https-agent-additional-options.js index 3707855ed5c8..02ec2cba8b54 100644 --- a/test/parallel/test-https-agent-additional-options.js +++ b/test/parallel/test-https-agent-additional-options.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); const https = require('https'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); const fips3 = hasFIPS(3); @@ -17,7 +17,7 @@ const options = { minVersion: fips3 ? 'TLSv1.2' : 'TLSv1.1', }; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { options.ciphers = fips3 ? 'ECDHE-RSA-AES256-GCM-SHA384' : 'ALL@SECLEVEL=0'; } @@ -36,7 +36,7 @@ function getBaseOptions(port) { servername: 'agent1', }; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { baseOptions.ciphers = fips3 ? 'ECDHE-RSA-AES256-GCM-SHA384' : 'ALL@SECLEVEL=0'; } diff --git a/test/parallel/test-https-agent-getname.js b/test/parallel/test-https-agent-getname.js index 8ead852b1df5..27dca59fec6e 100644 --- a/test/parallel/test-https-agent-getname.js +++ b/test/parallel/test-https-agent-getname.js @@ -13,13 +13,13 @@ const agent = new https.Agent(); // empty argument assert.strictEqual( agent.getName(), - 'localhost::::::::::::::::::::::' + 'localhost:::::::::::::::::::' ); // empty options assert.strictEqual( agent.getName({}), - 'localhost::::::::::::::::::::::' + 'localhost:::::::::::::::::::' ); // Pass all options arguments @@ -29,7 +29,6 @@ const options = { localAddress: '192.168.1.1', ca: 'ca', cert: 'cert', - clientCertEngine: 'dynamic', ciphers: 'ciphers', crl: [Buffer.from('c'), Buffer.from('r'), Buffer.from('l')], dhparam: 'dhparam', @@ -43,15 +42,13 @@ const options = { servername: 'localhost', sessionIdContext: 'sessionIdContext', sigalgs: 'sigalgs', - privateKeyIdentifier: 'privateKeyIdentifier', - privateKeyEngine: 'privateKeyEngine', }; assert.strictEqual( agent.getName(options), - '0.0.0.0:443:192.168.1.1:ca:cert:dynamic:ciphers:key:pfx:false:localhost:' + + '0.0.0.0:443:192.168.1.1:ca:cert:ciphers:key:pfx:false:localhost:' + '::secureProtocol:c,r,l:false:ecdhCurve:dhparam:0:sessionIdContext:' + - '"sigalgs":privateKeyIdentifier:privateKeyEngine' + '"sigalgs"' ); { diff --git a/test/parallel/test-https-agent-session-eviction.js b/test/parallel/test-https-agent-session-eviction.js index 971a8f359a6f..b62ab42d96b1 100644 --- a/test/parallel/test-https-agent-session-eviction.js +++ b/test/parallel/test-https-agent-session-eviction.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) { } const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const https = require('https'); const { constants: { SSL_OP_NO_TICKET } } = require('crypto'); @@ -25,7 +25,7 @@ if (fips3) { options.maxVersion = 'TLSv1.3'; } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { options.ciphers = fips3 ? 'ECDHE-RSA-AES256-GCM-SHA384' : 'RSA@SECLEVEL=0'; } @@ -84,7 +84,7 @@ function second(server, session) { // Offering the cached session to a server using another TLS version should // not prevent a fresh connection. req.on('response', common.mustCall(function(res) { - // The test is now complete for OpenSSL 1.1.0. + // The test is now complete. server.close(); })); diff --git a/test/parallel/test-https-agent-session-reuse.js b/test/parallel/test-https-agent-session-reuse.js index c5b7b78b8e02..1b8d0052c3cf 100644 --- a/test/parallel/test-https-agent-session-reuse.js +++ b/test/parallel/test-https-agent-session-reuse.js @@ -1,11 +1,13 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testTls13SessionTicketSemanticsDiffer(); return; } diff --git a/test/parallel/test-https-client-renegotiation-limit.js b/test/parallel/test-https-client-renegotiation-limit.js index 729176b7c1aa..9aef8d79345b 100644 --- a/test/parallel/test-https-client-renegotiation-limit.js +++ b/test/parallel/test-https-client-renegotiation-limit.js @@ -20,12 +20,14 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testRenegotiationUnsupported(); return; } diff --git a/test/parallel/test-https-options-boolean-check.js b/test/parallel/test-https-options-boolean-check.js index fa02a165b80f..3702b5560dd6 100644 --- a/test/parallel/test-https-options-boolean-check.js +++ b/test/parallel/test-https-options-boolean-check.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); if (!common.hasCrypto) @@ -41,7 +43,7 @@ const certDataView = toDataView(certBuff); const caArrDataView = toDataView(caCert); function filterBoringSSLKeyCertArrayCases(options, setName) { - if (!process.features.openssl_is_boringssl) + if (!isBoringSSL()) return options; // The array-valued cases exercise multi-identity key/cert handling. diff --git a/test/parallel/test-https-selfsigned-no-keycertsign-no-crash.js b/test/parallel/test-https-selfsigned-no-keycertsign-no-crash.js index ec1b8dda8ca1..1497f8a47aaa 100644 --- a/test/parallel/test-https-selfsigned-no-keycertsign-no-crash.js +++ b/test/parallel/test-https-selfsigned-no-keycertsign-no-crash.js @@ -12,18 +12,9 @@ const fixtures = require('../common/fixtures'); if (!common.hasCrypto) common.skip('missing crypto'); -const crypto = require('crypto'); -const { hasOpenSSL } = require('../common/crypto'); - -// See #37990 for details on why this is problematic with FIPS. -if (crypto.getFips() === 1 && !hasOpenSSL(3)) - common.skip('Skipping as test uses non-fips compliant EC curve'); - -// This test will fail for OpenSSL < 1.1.1h -const minOpenSSL = 269488271; - -if (crypto.constants.OPENSSL_VERSION_NUMBER < minOpenSSL) - common.skip('OpenSSL < 1.1.1h'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('not supported by BoringSSL'); const https = require('https'); const path = require('path'); diff --git a/test/parallel/test-permission-openssl-store.js b/test/parallel/test-permission-openssl-store.js index ca2f240a9520..6c0972b2e02f 100644 --- a/test/parallel/test-permission-openssl-store.js +++ b/test/parallel/test-permission-openssl-store.js @@ -4,9 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); -if (!hasOpenSSL3) - common.skip('requires OpenSSL 3.x'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL()) + common.skip('OpenSSL provider support is required'); // Verifies the openssl.store permission: allowed when --allow-openssl-store is // set, can be dropped at runtime, and denied by default in a child process. 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 8349d4c3af6f..d6ed173d74e0 100644 --- a/test/parallel/test-process-env-allowed-flags-are-documented.js +++ b/test/parallel/test-process-env-allowed-flags-are-documented.js @@ -5,7 +5,7 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); const path = require('path'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const rootDir = path.resolve(__dirname, '..', '..'); const cliMd = path.join(rootDir, 'doc', 'api', 'cli.md'); @@ -44,7 +44,7 @@ for (const line of [...nodeOptionsLines, ...v8OptionsLines]) { } } -if (!hasOpenSSL3) { +if (isBoringSSL()) { documented.delete('--openssl-legacy-provider'); documented.delete('--openssl-shared-config'); } @@ -63,8 +63,8 @@ const conditionalOpts = [ filter: (opt) => { return [ '--openssl-config', - hasOpenSSL3 ? '--openssl-legacy-provider' : '', - hasOpenSSL3 ? '--openssl-shared-config' : '', + isBoringSSL() ? '' : '--openssl-legacy-provider', + isBoringSSL() ? '' : '--openssl-shared-config', '--tls-cipher-list', '--use-bundled-ca', '--use-openssl-ca', diff --git a/test/parallel/test-process-versions.js b/test/parallel/test-process-versions.js index 14ac88d76cd2..9cb122448edf 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, such as + // '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-alert-handling.js b/test/parallel/test-tls-alert-handling.js index c319e766ce8a..ee1a77c2aa20 100644 --- a/test/parallel/test-tls-alert-handling.js +++ b/test/parallel/test-tls-alert-handling.js @@ -5,10 +5,6 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { - hasOpenSSL3, -} = require('../common/crypto'); - const assert = require('assert'); const net = require('net'); const tls = require('tls'); @@ -38,8 +34,6 @@ const errorHandler = common.mustCall((err) => { assert.match(err.code, /ERR_SSL_(WRONG_VERSION_NUMBER|PACKET_LENGTH_TOO_LONG|BAD_RECORD_TYPE)/); assert.strictEqual(err.library, 'SSL routines'); - if (!hasOpenSSL3 && !process.features.openssl_is_boringssl) - assert.strictEqual(err.function, 'ssl3_get_record'); assert.match(err.reason, /wrong[\s_]version[\s_]number|packet[\s_]length[\s_]too[\s_]long|bad[\s_]record[\s_]type/i); errorReceived = true; @@ -99,8 +93,6 @@ function sendBADTLSRecord() { assert.match(err.code, /ERR_SSL_(TLSV1_ALERT_PROTOCOL_VERSION|TLSV1_ALERT_RECORD_OVERFLOW|(SSL\/)?TLS_ALERT_UNEXPECTED_MESSAGE)/); assert.strictEqual(err.library, 'SSL routines'); - if (!hasOpenSSL3 && !process.features.openssl_is_boringssl) - assert.strictEqual(err.function, 'ssl3_read_bytes'); assert.match(err.reason, /tlsv1[\s_]alert[\s_]protocol[\s_]version|tlsv1[\s_]alert[\s_]record[\s_]overflow|(ssl\/)?tls[\s_]alert[\s_]unexpected[\s_]message/i); })); diff --git a/test/parallel/test-tls-alert.js b/test/parallel/test-tls-alert.js index f20bf42a2dcd..94f72d311aa3 100644 --- a/test/parallel/test-tls-alert.js +++ b/test/parallel/test-tls-alert.js @@ -29,6 +29,7 @@ const { hasOpenSSL, hasFIPS, opensslCli, + isBoringSSL, } = require('../common/crypto'); if (!opensslCli) { @@ -56,7 +57,7 @@ if (hasFIPS(3)) { } const server = tls.Server(serverOptions, null).listen(0, common.mustCall(() => { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { let gotClientError = false; let gotServerError = false; function maybeClose() { diff --git a/test/parallel/test-tls-cert-ext-encoding.js b/test/parallel/test-tls-cert-ext-encoding.js index 154e0cdcf022..3c22252f2ade 100644 --- a/test/parallel/test-tls-cert-ext-encoding.js +++ b/test/parallel/test-tls-cert-ext-encoding.js @@ -3,17 +3,11 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (hasOpenSSL3) - // TODO(danbev) This test fails with the following error: - // error:0D00008F:asn1 encoding routines::no matching choice type - // - // I've not been able to figure out the reason for this but there - // is a note in https://wiki.openssl.org/index.php/OpenSSL_3.0 which - // indicates that this might not work at the moment: - // "OCSP, PEM, ASN.1 have some very limited library context support" - common.skip('when using OpenSSL 3.x'); +if (!isBoringSSL()) { + common.skip('this test only applies to BoringSSL'); +} // NOTE: This certificate is hand-generated, hence it is not located in // `test/fixtures/keys` to avoid confusion. diff --git a/test/parallel/test-tls-client-auth.js b/test/parallel/test-tls-client-auth.js index 517054c6e290..3ee327cf00fb 100644 --- a/test/parallel/test-tls-client-auth.js +++ b/test/parallel/test-tls-client-auth.js @@ -6,7 +6,7 @@ const fixtures = require('../common/fixtures'); if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const { assert, connect, keys, tls @@ -111,7 +111,7 @@ if (tls.DEFAULT_MAX_VERSION === 'TLSv1.3') connect({ // and sends a fatal Alert to the client that the client discovers there has // been a fatal error. pair.client.conn.once('error', common.mustCall((err) => { - const expectedErr = process.features.openssl_is_boringssl ? + const expectedErr = isBoringSSL() ? 'ERR_SSL_TLSV1_ALERT_CERTIFICATE_REQUIRED' : 'ERR_SSL_TLSV13_ALERT_CERTIFICATE_REQUIRED'; assert.strictEqual(err.code, expectedErr); diff --git a/test/parallel/test-tls-client-getephemeralkeyinfo.js b/test/parallel/test-tls-client-getephemeralkeyinfo.js index 638df3ff0141..8ba810768987 100644 --- a/test/parallel/test-tls-client-getephemeralkeyinfo.js +++ b/test/parallel/test-tls-client-getephemeralkeyinfo.js @@ -3,13 +3,18 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +const { + isBoringSSL, + hasOpenSSL, + hasFIPS, +} = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').testEphemeralKeyInfo(); return; } const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); const assert = require('assert'); const { X509Certificate } = require('crypto'); diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index 8f3b2eafbb8a..e3a6f467b09e 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -8,12 +8,12 @@ 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'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const fips3 = hasFIPS(3); const fips4 = hasFIPS(4); @@ -88,7 +88,7 @@ function testDHE3072() { test(3072, false, null); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { if (fips3 && !fips4) { // The FIPS provider rejects explicit DH parameters without a validated // subgroup, while OpenSSL's built-in FFDHE group remains available. @@ -129,7 +129,7 @@ for (const minDHSize of [true, false, null, undefined, {}, [], '', '1']) { }); } -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { process.on('exit', function() { assert.strictEqual(nsuccess, 1); assert.strictEqual(nerror, 1); diff --git a/test/parallel/test-tls-client-reject.js b/test/parallel/test-tls-client-reject.js index cff0aabc89a7..d467fd371919 100644 --- a/test/parallel/test-tls-client-reject.js +++ b/test/parallel/test-tls-client-reject.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -31,7 +33,7 @@ const fixtures = require('../common/fixtures'); const options = { key: fixtures.readKey('rsa_private.pem'), cert: fixtures.readKey('rsa_cert.crt'), - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }; const server = tls.createServer(options, function(socket) { @@ -48,7 +50,7 @@ function unauthorized() { port: server.address().port, servername: 'localhost', rejectUnauthorized: false, - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustCall(function() { let _data; assert(!socket.authorized); @@ -70,7 +72,7 @@ function rejectUnauthorized() { console.log('reject unauthorized'); const socket = tls.connect(server.address().port, { servername: 'localhost', - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustNotCall()); socket.on('data', common.mustNotCall()); socket.on('error', common.mustCall(function(err) { @@ -84,7 +86,7 @@ function rejectUnauthorizedUndefined() { const socket = tls.connect(server.address().port, { servername: 'localhost', rejectUnauthorized: undefined, - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustNotCall()); socket.on('data', common.mustNotCall()); socket.on('error', common.mustCall(function(err) { @@ -98,7 +100,7 @@ function authorized() { const socket = tls.connect(server.address().port, { ca: [fixtures.readKey('rsa_cert.crt')], servername: 'localhost', - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustCall(function() { console.log('... authorized'); assert(socket.authorized); diff --git a/test/parallel/test-tls-client-renegotiation-13.js b/test/parallel/test-tls-client-renegotiation-13.js index 80c4753d065e..a5b761788df8 100644 --- a/test/parallel/test-tls-client-renegotiation-13.js +++ b/test/parallel/test-tls-client-renegotiation-13.js @@ -5,7 +5,7 @@ const common = require('../common'); if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); @@ -32,7 +32,7 @@ connect({ assert.strictEqual(client.getProtocol(), 'TLSv1.3'); const ok = client.renegotiate({}, common.mustCall((err) => { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { assert.throws(() => { throw err; }, { message: 'TLS session renegotiation is unsupported by this TLS ' + 'implementation', @@ -40,9 +40,7 @@ connect({ }); } else { assert.throws(() => { throw err; }, { - message: hasOpenSSL3 ? - 'error:0A00010A:SSL routines::wrong ssl version' : - 'error:1420410A:SSL routines:SSL_renegotiate:wrong ssl version', + message: 'error:0A00010A:SSL routines::wrong ssl version', code: 'ERR_SSL_WRONG_SSL_VERSION', library: 'SSL routines', reason: 'wrong ssl version', diff --git a/test/parallel/test-tls-client-renegotiation-limit.js b/test/parallel/test-tls-client-renegotiation-limit.js index 9b7f62865b33..03550f00a7ef 100644 --- a/test/parallel/test-tls-client-renegotiation-limit.js +++ b/test/parallel/test-tls-client-renegotiation-limit.js @@ -25,13 +25,13 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { opensslCli } = require('../common/crypto'); +const { opensslCli, isBoringSSL } = require('../common/crypto'); if (!opensslCli) { common.skip('node compiled without OpenSSL CLI.'); } -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testRenegotiationUnsupported(); return; } diff --git a/test/parallel/test-tls-clientcertengine-invalid-arg-type.js b/test/parallel/test-tls-clientcertengine-invalid-arg-type.js deleted file mode 100644 index 811e320b0788..000000000000 --- a/test/parallel/test-tls-clientcertengine-invalid-arg-type.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -{ - assert.throws( - () => { tls.createSecureContext({ clientCertEngine: 0 }); }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)/ }); -} diff --git a/test/parallel/test-tls-clientcertengine-unsupported.js b/test/parallel/test-tls-clientcertengine-unsupported.js deleted file mode 100644 index aa0bf4a18d6a..000000000000 --- a/test/parallel/test-tls-clientcertengine-unsupported.js +++ /dev/null @@ -1,39 +0,0 @@ -// Flags: --expose-internals -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); - -common.expectWarning({ - 'internal/test/binding': - 'These APIs are for internal testing only. Do not use them.', - 'DeprecationWarning': { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -// Monkey-patch SecureContext -const { internalBinding } = require('internal/test/binding'); -const binding = internalBinding('crypto'); -const NativeSecureContext = binding.SecureContext; - -binding.SecureContext = function() { - const rv = new NativeSecureContext(); - rv.setClientCertEngine = undefined; - return rv; -}; - -const tls = require('tls'); - -{ - assert.throws( - () => { tls.createSecureContext({ clientCertEngine: 'Cannonmouth' }); }, - { - code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - message: 'Custom engines not supported by this OpenSSL' - } - ); -} diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js index 65f3dc6867c4..600accfe736c 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -26,7 +26,9 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +const { isBoringSSL } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').assertFiniteFieldDheUnsupported(); return; } @@ -41,7 +43,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) { @@ -65,7 +67,7 @@ const ciphers = `${dheCipher}:${ecdheCipher}`; if (secLevel < 2 && !hasFIPS(3)) { // Test will emit a warning because the DH parameter size is < 2048 bits - // when the test is run on versions lower than OpenSSL32 + // when the test is run on OpenSSL versions earlier than 3.2 common.expectWarning('SecurityWarning', 'DH parameter is less than 2048 bits'); } diff --git a/test/parallel/test-tls-dhparam-auto-boringssl.js b/test/parallel/test-tls-dhparam-auto-boringssl.js index 54f2190d1a94..2da81ae0606e 100644 --- a/test/parallel/test-tls-dhparam-auto-boringssl.js +++ b/test/parallel/test-tls-dhparam-auto-boringssl.js @@ -1,9 +1,11 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); -if (!process.features.openssl_is_boringssl) +if (!isBoringSSL()) common.skip('only applies to BoringSSL builds'); const assert = require('assert'); diff --git a/test/parallel/test-tls-disable-renegotiation.js b/test/parallel/test-tls-disable-renegotiation.js index 84a6ead4a544..e461788ad732 100644 --- a/test/parallel/test-tls-disable-renegotiation.js +++ b/test/parallel/test-tls-disable-renegotiation.js @@ -1,5 +1,7 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const fixtures = require('../common/fixtures'); @@ -8,7 +10,7 @@ const fixtures = require('../common/fixtures'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testRenegotiationUnsupported(); return; } diff --git a/test/parallel/test-tls-ecdh-multiple.js b/test/parallel/test-tls-ecdh-multiple.js index b01051d5b457..cfd4b667e06a 100644 --- a/test/parallel/test-tls-ecdh-multiple.js +++ b/test/parallel/test-tls-ecdh-multiple.js @@ -12,6 +12,7 @@ const { opensslCli, hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); const crypto = require('crypto'); @@ -31,7 +32,7 @@ function loadPEM(n) { // The FIPS provider and OpenSSL 4.0 disable support for deprecated elliptic // curves from RFC 8422 (including secp256k1) by default. -const ecdhCurve = process.features.openssl_is_boringssl || +const ecdhCurve = isBoringSSL() || hasOpenSSL(4, 0) || hasFIPS(3) ? 'prime256v1:secp521r1' : 'secp256k1:prime256v1:secp521r1'; @@ -82,7 +83,7 @@ const server = tls.createServer(options, (conn) => { } // Deprecated RFC 8422 curves are disabled by default in OpenSSL 4.0. - if (process.features.openssl_is_boringssl || hasOpenSSL(4, 0)) { + if (isBoringSSL() || hasOpenSSL(4, 0)) { unsupportedCurves.push('secp256k1'); } diff --git a/test/parallel/test-tls-empty-sni-context.js b/test/parallel/test-tls-empty-sni-context.js index 6ecdfbeecbe3..265be711e98d 100644 --- a/test/parallel/test-tls-empty-sni-context.js +++ b/test/parallel/test-tls-empty-sni-context.js @@ -3,7 +3,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const tls = require('tls'); @@ -26,7 +26,7 @@ const server = tls.createServer(options, (c) => { }, common.mustNotCall()); c.on('error', common.mustCall((err) => { - const expectedErr = process.features.openssl_is_boringssl ? + const expectedErr = isBoringSSL() ? 'ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR' : hasOpenSSL(4, 0) ? 'ERR_SSL_TLS_ALERT_HANDSHAKE_FAILURE' : hasOpenSSL(3, 2) ? 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE'; diff --git a/test/parallel/test-tls-error-stack.js b/test/parallel/test-tls-error-stack.js deleted file mode 100644 index 0a952a46bdd4..000000000000 --- a/test/parallel/test-tls-error-stack.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -// This tests that the crypto error stack can be correctly converted. -const common = require('../common'); -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -const secureContext = tls.createSecureContext(); -if (typeof secureContext.context.setClientCertEngine !== 'function') - common.skip('OpenSSL dropped engine support'); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -assert.throws(() => { - tls.createSecureContext({ clientCertEngine: 'x' }); -}, (err) => { - return err.name === 'Error' && - /could not load the shared library/.test(err.message) && - Array.isArray(err.opensslErrorStack) && - err.opensslErrorStack.length > 0; -}); diff --git a/test/parallel/test-tls-finished.js b/test/parallel/test-tls-finished.js index b23b4567d27e..325d5055d0de 100644 --- a/test/parallel/test-tls-finished.js +++ b/test/parallel/test-tls-finished.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); if (!common.hasCrypto) @@ -21,7 +23,7 @@ const pem = (n) => fixtures.readKey(`${n}.pem`); const server = tls.createServer({ key: pem('agent1-key'), cert: pem('agent1-cert'), - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustCall((alice) => { msg.server = { alice: alice.getFinished(), @@ -34,7 +36,7 @@ server.listen(0, common.mustCall(() => { const bob = tls.connect({ port: server.address().port, rejectUnauthorized: false, - ...(process.features.openssl_is_boringssl ? { maxVersion: 'TLSv1.2' } : {}), + ...(isBoringSSL() ? { maxVersion: 'TLSv1.2' } : {}), }, common.mustCall(() => { msg.client = { alice: bob.getPeerFinished(), diff --git a/test/parallel/test-tls-getcipher.js b/test/parallel/test-tls-getcipher.js index 2d4de5639afb..41924cd6daaf 100644 --- a/test/parallel/test-tls-getcipher.js +++ b/test/parallel/test-tls-getcipher.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -36,16 +38,15 @@ const options = { honorCipherOrder: true }; -const isBoringSSL = process.features.openssl_is_boringssl; let clients = 0; -const expectedClients = isBoringSSL ? 1 : 2; +const expectedClients = isBoringSSL() ? 1 : 2; const server = tls.createServer(options, common.mustCall(() => { if (--clients === 0) server.close(); }, expectedClients)); server.listen(0, '127.0.0.1', common.mustCall(function() { - if (isBoringSSL) { + if (isBoringSSL()) { // BoringSSL does not provide this static RSA TLS 1.2 cipher suite on // Node's supported cipher surface, so keep the OpenSSL getCipher() // assertion below limited to backends that can create the context. @@ -85,7 +86,7 @@ server.listen(0, '127.0.0.1', common.mustCall(function() { assert.strictEqual(cipher.name, 'ECDHE-RSA-AES256-GCM-SHA384'); assert.strictEqual(cipher.standardName, 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'); - assert.strictEqual(cipher.version, isBoringSSL ? + assert.strictEqual(cipher.version, isBoringSSL() ? 'TLSv1/SSLv3' : 'TLSv1.2'); this.end(); @@ -107,12 +108,12 @@ tls.createServer({ rejectUnauthorized: false }, common.mustCall(() => { const cipher = client.getCipher(); - const expectedCipher = isBoringSSL ? + const expectedCipher = isBoringSSL() ? 'TLS_AES_128_GCM_SHA256' : 'TLS_AES_256_GCM_SHA384'; assert.strictEqual(cipher.name, expectedCipher); assert.strictEqual(cipher.standardName, cipher.name); - assert.strictEqual(cipher.version, isBoringSSL ? + assert.strictEqual(cipher.version, isBoringSSL() ? 'TLSv1/SSLv3' : 'TLSv1.3'); client.end(); diff --git a/test/parallel/test-tls-getprotocol.js b/test/parallel/test-tls-getprotocol.js index 2fe971444271..8a5fbb83dae8 100644 --- a/test/parallel/test-tls-getprotocol.js +++ b/test/parallel/test-tls-getprotocol.js @@ -3,7 +3,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); // This test ensures that `getProtocol` returns the right protocol // from a TLS connection @@ -28,7 +28,7 @@ let clientConfigs = [ }, ]; -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { // Remove the TLSv1 and TLSv1.1 cases. BoringSSL does not negotiate those // legacy protocols in this configuration; keep TLSv1.2 to cover getProtocol() // on a successful BoringSSL TLS handshake. @@ -42,7 +42,7 @@ const serverConfig = { cert: fixtures.readKey('agent2-cert.pem') }; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { serverConfig.ciphers = fips3 ? 'ECDHE-RSA-AES256-GCM-SHA384' : 'RSA@SECLEVEL=0'; } diff --git a/test/parallel/test-tls-honorcipherorder.js b/test/parallel/test-tls-honorcipherorder.js index fbee483d83b9..3374757f4707 100644 --- a/test/parallel/test-tls-honorcipherorder.js +++ b/test/parallel/test-tls-honorcipherorder.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const mustCall = common.mustCall; const tls = require('tls'); const util = require('util'); @@ -17,7 +17,7 @@ const util = require('util'); // default method is updated in the future const SSL_Method = 'TLSv1_2_method'; const localhost = '127.0.0.1'; -const config = process.features.openssl_is_boringssl || hasFIPS(3) ? { +const config = isBoringSSL() || hasFIPS(3) ? { serverCiphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256', clientPreferenceCiphers: diff --git a/test/parallel/test-tls-junk-closes-server.js b/test/parallel/test-tls-junk-closes-server.js index 08c2d39c6844..a90fbc60c9b8 100644 --- a/test/parallel/test-tls-junk-closes-server.js +++ b/test/parallel/test-tls-junk-closes-server.js @@ -42,7 +42,7 @@ server.listen(0, common.mustCall(function() { c.on('data', function() { // We must consume all data sent by the server. Otherwise the // end event will not be sent and the test will hang. - // For example, when compiled with OpenSSL32 we see the + // For example, when compiled with OpenSSL 3.2 we see the // following response '15 03 03 00 02 02 16' which // decodes as a fatal (0x02) TLS error alert number 22 (0x16), // which corresponds to TLS1_AD_RECORD_OVERFLOW which matches @@ -51,7 +51,7 @@ server.listen(0, common.mustCall(function() { // but the TLS spec seems to indicate there should be one // https://datatracker.ietf.org/doc/html/rfc8446#page-85 // and error handling seems to have been re-written/improved - // in OpenSSL32. Consuming the data allows the test to pass + // in OpenSSL 3.2. Consuming the data allows the test to pass // either way. }); diff --git a/test/parallel/test-tls-key-mismatch.js b/test/parallel/test-tls-key-mismatch.js index 797c7c171dc5..090d5d229e6d 100644 --- a/test/parallel/test-tls-key-mismatch.js +++ b/test/parallel/test-tls-key-mismatch.js @@ -27,15 +27,13 @@ if (!common.hasCrypto) { } const fixtures = require('../common/fixtures'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const tls = require('tls'); -const errorMessageRegex = process.features.openssl_is_boringssl ? +const errorMessageRegex = isBoringSSL() ? /^Error: error:0b000074:X\.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH$/ : - hasOpenSSL3 ? - /^Error: error:05800074:x509 certificate routines::key values mismatch$/ : - /^Error: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch$/; + /^Error: error:05800074:x509 certificate routines::key values mismatch$/; const options = { key: fixtures.readKey('agent1-key.pem'), diff --git a/test/parallel/test-tls-keyengine-invalid-arg-type.js b/test/parallel/test-tls-keyengine-invalid-arg-type.js deleted file mode 100644 index 72fe526daffa..000000000000 --- a/test/parallel/test-tls-keyengine-invalid-arg-type.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -assert.throws( - () => { - tls.createSecureContext({ privateKeyEngine: 0, - privateKeyIdentifier: 'key' }); - }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)$/ }); - -assert.throws( - () => { - tls.createSecureContext({ privateKeyEngine: 'engine', - privateKeyIdentifier: 0 }); - }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)$/ }); diff --git a/test/parallel/test-tls-keyengine-unsupported.js b/test/parallel/test-tls-keyengine-unsupported.js deleted file mode 100644 index 3473fe533f22..000000000000 --- a/test/parallel/test-tls-keyengine-unsupported.js +++ /dev/null @@ -1,44 +0,0 @@ -// Flags: --expose-internals -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); - -common.expectWarning({ - 'internal/test/binding': - 'These APIs are for internal testing only. Do not use them.', - 'DeprecationWarning': { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -// Monkey-patch SecureContext -const { internalBinding } = require('internal/test/binding'); -const binding = internalBinding('crypto'); -const NativeSecureContext = binding.SecureContext; - -binding.SecureContext = function() { - const rv = new NativeSecureContext(); - rv.setEngineKey = undefined; - return rv; -}; - -const tls = require('tls'); - -{ - assert.throws( - () => { - tls.createSecureContext({ - privateKeyEngine: 'engine', - privateKeyIdentifier: 'key' - }); - }, - { - code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - message: 'Custom engines not supported by this OpenSSL' - } - ); -} diff --git a/test/parallel/test-tls-legacy-pfx.js b/test/parallel/test-tls-legacy-pfx.js index 5106217718db..2eb4989a3d08 100644 --- a/test/parallel/test-tls-legacy-pfx.js +++ b/test/parallel/test-tls-legacy-pfx.js @@ -4,10 +4,10 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL3) { - common.skip('OpenSSL legacy failures are only testable with OpenSSL 3+'); +if (isBoringSSL()) { + common.skip('OpenSSL legacy failures are not testable with BoringSSL'); } const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-tls-max-send-fragment.js b/test/parallel/test-tls-max-send-fragment.js index 2e319fcdaeaf..5cb6bae983d1 100644 --- a/test/parallel/test-tls-max-send-fragment.js +++ b/test/parallel/test-tls-max-send-fragment.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); if (!common.hasCrypto) @@ -64,7 +66,7 @@ const server = tls.createServer({ // both out-of-range values and reports success, so assert that difference // explicitly instead of using a truthiness shortcut. const acceptsOutOfRangeFragmentSize = - process.features.openssl_is_boringssl; + isBoringSSL(); assert.strictEqual(c.setMaxSendFragment(511), acceptsOutOfRangeFragmentSize); assert.strictEqual(c.setMaxSendFragment(16385), diff --git a/test/parallel/test-tls-min-max-version.js b/test/parallel/test-tls-min-max-version.js index 83797238cf4b..e4e7b28afb99 100644 --- a/test/parallel/test-tls-min-max-version.js +++ b/test/parallel/test-tls-min-max-version.js @@ -5,15 +5,17 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { - require('../common/boringssl').testLegacyProtocolUnsupported(); - return; -} - const { + isBoringSSL, hasOpenSSL, hasFIPS, } = require('../common/crypto'); + +if (isBoringSSL()) { + require('../common/boringssl').testLegacyProtocolUnsupported(); + return; +} + const fixtures = require('../common/fixtures'); const { inspect } = require('util'); @@ -46,9 +48,9 @@ function test(cmin, cmax, cprot, smin, smax, sprot, proto, cerr, serr) { } let ciphers; - if (hasOpenSSL(3) && (proto === 'TLSv1' || proto === 'TLSv1.1' || + if (proto === 'TLSv1' || proto === 'TLSv1.1' || proto === 'TLSv1_1_method' || proto === 'TLSv1_method' || - sprot === 'TLSv1_1_method' || sprot === 'TLSv1_method')) { + sprot === 'TLSv1_1_method' || sprot === 'TLSv1_method') { if (serr !== 'ERR_SSL_UNSUPPORTED_PROTOCOL') ciphers = 'ALL@SECLEVEL=0'; } @@ -174,12 +176,9 @@ test(U, U, 'TLS_method', U, U, 'TLSv1_2_method', 'TLSv1.2'); test(U, U, 'TLS_method', U, U, 'TLSv1_1_method', 'TLSv1.1'); test(U, U, 'TLS_method', U, U, 'TLSv1_method', 'TLSv1'); -// OpenSSL 1.1.1 and 3.0 use a different error code and alert (sent to the -// client) when no protocols are enabled on the server. -const NO_PROTOCOLS_AVAILABLE_SERVER = hasOpenSSL(3) ? - 'ERR_SSL_NO_PROTOCOLS_AVAILABLE' : 'ERR_SSL_INTERNAL_ERROR'; -const NO_PROTOCOLS_AVAILABLE_SERVER_ALERT = hasOpenSSL(3) ? - 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION' : 'ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR'; +const NO_PROTOCOLS_AVAILABLE_SERVER = 'ERR_SSL_NO_PROTOCOLS_AVAILABLE'; +const NO_PROTOCOLS_AVAILABLE_SERVER_ALERT = + 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'; // SSLv23 also means "any supported protocol" greater than the default // minimum (which is configurable via command line). diff --git a/test/parallel/test-tls-multi-key.js b/test/parallel/test-tls-multi-key.js index 239cb8aec725..d46acd01dc01 100644 --- a/test/parallel/test-tls-multi-key.js +++ b/test/parallel/test-tls-multi-key.js @@ -27,7 +27,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').assertMultiKeyUnsupported(); return; } @@ -35,7 +37,6 @@ if (process.features.openssl_is_boringssl) { const fixtures = require('../common/fixtures'); const assert = require('assert'); const tls = require('tls'); -const { hasFIPS } = require('../common/crypto'); // Key is ordered as ec, rsa, cert is ordered as rsa, ec. test({ diff --git a/test/parallel/test-tls-multi-pfx.js b/test/parallel/test-tls-multi-pfx.js index b5bbb6decc12..26292c68ea67 100644 --- a/test/parallel/test-tls-multi-pfx.js +++ b/test/parallel/test-tls-multi-pfx.js @@ -3,14 +3,15 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +const { isBoringSSL, hasFIPS } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').testMultiPfxSelectionDifference(); return; } const assert = require('assert'); const tls = require('tls'); -const { hasFIPS } = require('../common/crypto'); const fixtures = require('../common/fixtures'); const fips3 = hasFIPS(3); const fips4 = hasFIPS(4); diff --git a/test/parallel/test-tls-no-cert-required.js b/test/parallel/test-tls-no-cert-required.js index 499ab2dfd14e..d6ada6fbe5cc 100644 --- a/test/parallel/test-tls-no-cert-required.js +++ b/test/parallel/test-tls-no-cert-required.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -28,7 +30,7 @@ const assert = require('assert'); const tls = require('tls'); // Omitting the cert or pfx option to tls.createServer() should not throw. -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { // AECDH-NULL-SHA is a no-authentication/no-encryption cipher and hence // does not need a certificate. BoringSSL does not provide that anonymous // cipher suite, so only this cipher-specific no-cert case is skipped. diff --git a/test/parallel/test-tls-options-boolean-check.js b/test/parallel/test-tls-options-boolean-check.js index f7dd7bb102f3..94de3012b451 100644 --- a/test/parallel/test-tls-options-boolean-check.js +++ b/test/parallel/test-tls-options-boolean-check.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); if (!common.hasCrypto) @@ -41,7 +43,7 @@ const certDataView = toDataView(certBuff); const caArrDataView = toDataView(caCert); function filterBoringSSLKeyCertArrayCases(options, setName) { - if (!process.features.openssl_is_boringssl) + if (!isBoringSSL()) return options; // The array-valued cases exercise multi-identity key/cert handling. diff --git a/test/parallel/test-tls-psk-alpn-callback-exception-handling.js b/test/parallel/test-tls-psk-alpn-callback-exception-handling.js index 0ba55f9153b9..bbf3e3c27f3d 100644 --- a/test/parallel/test-tls-psk-alpn-callback-exception-handling.js +++ b/test/parallel/test-tls-psk-alpn-callback-exception-handling.js @@ -10,11 +10,12 @@ // throw exceptions during validation. const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testPskTls13Unsupported(); return; } diff --git a/test/parallel/test-tls-psk-circuit.js b/test/parallel/test-tls-psk-circuit.js index c9c93d533501..9fddb851cbe3 100644 --- a/test/parallel/test-tls-psk-circuit.js +++ b/test/parallel/test-tls-psk-circuit.js @@ -5,12 +5,13 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +const { isBoringSSL, hasOpenSSL } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').testPskTls13Unsupported(); return; } -const { hasOpenSSL } = require('../common/crypto'); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-tls-psk-server.js b/test/parallel/test-tls-psk-server.js index 692550fc1c19..67e89a42017b 100644 --- a/test/parallel/test-tls-psk-server.js +++ b/test/parallel/test-tls-psk-server.js @@ -5,7 +5,9 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +const { isBoringSSL } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').testPskTls13Unsupported(); return; } diff --git a/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js b/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js index cca22067a0fe..605bc13861a1 100644 --- a/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js +++ b/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js @@ -1,10 +1,12 @@ 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').assertOpenSSLSecurityLevelsUnsupported(); return; } diff --git a/test/parallel/test-tls-server-verify.js b/test/parallel/test-tls-server-verify.js index 439e32131030..fce658cc2ac3 100644 --- a/test/parallel/test-tls-server-verify.js +++ b/test/parallel/test-tls-server-verify.js @@ -26,7 +26,7 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { opensslCli } = require('../common/crypto'); +const { opensslCli, isBoringSSL } = require('../common/crypto'); if (!opensslCli) { common.skip('node compiled without OpenSSL CLI.'); @@ -125,7 +125,7 @@ let testCases = ] }, ]; -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { // Remove the delayed client-certificate verification case. It depends on TLS // renegotiation to request a client certificate after the initial handshake, // but BoringSSL does not support caller-initiated renegotiation. diff --git a/test/parallel/test-tls-session-cache.js b/test/parallel/test-tls-session-cache.js index 0789879e1dce..a020288ce160 100644 --- a/test/parallel/test-tls-session-cache.js +++ b/test/parallel/test-tls-session-cache.js @@ -28,6 +28,7 @@ const { hasOpenSSL, hasFIPS, opensslCli, + isBoringSSL, } = require('../common/crypto'); if (!opensslCli) { @@ -38,8 +39,6 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const tls = require('tls'); const { spawn } = require('child_process'); -const isBoringSSL = process.features.openssl_is_boringssl; - doTest({ tickets: false }, function() { doTest({ tickets: true }, function() { doTest({ tickets: false, invalidSession: true }, function() { @@ -61,7 +60,7 @@ function doTest(testOptions, callback) { // BoringSSL supports the RSA cipher selector, but not OpenSSL's // cipher-string policy command syntax. ciphers: hasFIPS(3) ? 'ECDHE-RSA-AES256-GCM-SHA384' : - (isBoringSSL ? 'RSA' : 'RSA@SECLEVEL=0') + (isBoringSSL() ? 'RSA' : 'RSA@SECLEVEL=0') }; let requestCount = 0; let resumeCount = 0; @@ -110,7 +109,7 @@ function doTest(testOptions, callback) { server.listen(0, common.mustCall(function() { const args = [ 's_client', - isBoringSSL || hasFIPS(3) ? '-tls1_2' : '-tls1', + isBoringSSL() || hasFIPS(3) ? '-tls1_2' : '-tls1', '-cipher', hasFIPS(3) ? 'ECDHE-RSA-AES256-GCM-SHA384' : (hasOpenSSL(3, 1) ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT'), '-connect', `localhost:${this.address().port}`, diff --git a/test/parallel/test-tls-set-ciphers-error.js b/test/parallel/test-tls-set-ciphers-error.js index b79bd512ffe1..5b84d205aa0d 100644 --- a/test/parallel/test-tls-set-ciphers-error.js +++ b/test/parallel/test-tls-set-ciphers-error.js @@ -7,7 +7,7 @@ if (!common.hasCrypto) const assert = require('assert'); const tls = require('tls'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); { const options = { @@ -21,7 +21,7 @@ const { hasOpenSSL } = require('../common/crypto'); assert.throws(() => tls.createServer(options, common.mustNotCall()), /no[_ ]cipher[_ ]match/i); options.ciphers = 'TLS_not_a_cipher'; - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { tls.createServer(options).close(); } else { assert.throws(() => tls.createServer(options, common.mustNotCall()), diff --git a/test/parallel/test-tls-set-ciphers.js b/test/parallel/test-tls-set-ciphers.js index 57fb35991121..30ed16fa3696 100644 --- a/test/parallel/test-tls-set-ciphers.js +++ b/test/parallel/test-tls-set-ciphers.js @@ -1,16 +1,17 @@ 'use strict'; const common = require('../common'); if (!common.hasCrypto) { - common.skip('missing crypto, or OpenSSL version lower than 3'); + common.skip('missing crypto'); } const { hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../common/crypto'); -if (!hasOpenSSL(3)) { - common.skip('missing crypto, or OpenSSL version lower than 3'); +if (isBoringSSL()) { + common.skip('this test requires OpenSSL'); } const fixtures = require('../common/fixtures'); @@ -152,7 +153,7 @@ if (hasFIPS(3)) { // TLS_AES_128_CCM_8_SHA256 & TLS_AES_128_CCM_SHA256 are not enabled by // default, but work. - // However, for OpenSSL32 AES_128 is not enabled due to the + // However, for OpenSSL 3.2 AES_128 is not enabled due to the // default security level if (!hasOpenSSL(3, 2)) { test('TLS_AES_128_CCM_8_SHA256', U, diff --git a/test/parallel/test-tls-set-default-ca-certificates-recovery.js b/test/parallel/test-tls-set-default-ca-certificates-recovery.js index ea6f98d5686e..974042162fe6 100644 --- a/test/parallel/test-tls-set-default-ca-certificates-recovery.js +++ b/test/parallel/test-tls-set-default-ca-certificates-recovery.js @@ -3,6 +3,7 @@ // This tests error recovery and fallback behavior for tls.setDefaultCACertificates() const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); @@ -27,7 +28,7 @@ function testRecovery(expectedCerts) { { const invalidCert = '-----BEGIN CERTIFICATE-----\nvalid cert content\n-----END CERTIFICATE-----'; assert.throws(() => tls.setDefaultCACertificates([fixtureCert, invalidCert]), { - code: process.features.openssl_is_boringssl ? + code: isBoringSSL() ? 'ERR_OSSL_PEM_ASN.1_ENCODING_ROUTINES' : 'ERR_OSSL_PEM_ASN1_LIB', }); diff --git a/test/parallel/test-tls-set-sigalgs.js b/test/parallel/test-tls-set-sigalgs.js index e1bf8b93f8a3..77b7d807d437 100644 --- a/test/parallel/test-tls-set-sigalgs.js +++ b/test/parallel/test-tls-set-sigalgs.js @@ -3,7 +3,7 @@ const common = require('../common'); if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); // Test sigalgs: option for TLS. @@ -41,7 +41,7 @@ function test(csigalgs, ssigalgs, shared_sigalgs, cerr, serr) { assert(pair.client.conn); // BoringSSL's OpenSSL-compatible SSL_get_shared_sigalgs() API always // returns zero, so a successful handshake still reports an empty list. - const expectedSharedSigalgs = process.features.openssl_is_boringssl ? + const expectedSharedSigalgs = isBoringSSL() ? [] : shared_sigalgs; assert.deepStrictEqual( @@ -74,7 +74,7 @@ test('RSA-PSS+SHA256:RSA-PSS+SHA512:ECDSA+SHA256', const handshakeErr = hasOpenSSL(4, 0) ? 'ERR_SSL_TLS_ALERT_HANDSHAKE_FAILURE' : hasOpenSSL(3, 2) ? 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE'; -const noSharedSigalgsErr = process.features.openssl_is_boringssl ? +const noSharedSigalgsErr = isBoringSSL() ? 'ERR_SSL_NO_COMMON_SIGNATURE_ALGORITHMS' : 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS'; test('RSA-PSS+SHA384', 'ECDSA+SHA256', diff --git a/test/parallel/test-tls-ticket-cluster.js b/test/parallel/test-tls-ticket-cluster.js index f183b53f24c0..41d77b5c4eb9 100644 --- a/test/parallel/test-tls-ticket-cluster.js +++ b/test/parallel/test-tls-ticket-cluster.js @@ -20,11 +20,13 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { require('../common/boringssl').testTls13SessionTicketSemanticsDiffer(); return; } diff --git a/test/parallel/test-tls-ticket.js b/test/parallel/test-tls-ticket.js index 8316f5e8da8d..9a5736655ed2 100644 --- a/test/parallel/test-tls-ticket.js +++ b/test/parallel/test-tls-ticket.js @@ -20,7 +20,9 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; + const common = require('../common'); +const { isBoringSSL } = require('../common/crypto'); if (!common.hasCrypto) common.skip('missing crypto'); @@ -30,7 +32,7 @@ const net = require('net'); const crypto = require('crypto'); const fixtures = require('../common/fixtures'); -if (process.features.openssl_is_boringssl && +if (isBoringSSL() && tls.DEFAULT_MAX_VERSION !== 'TLSv1.2') { require('../common/boringssl').testTls13SessionTicketSemanticsDiffer(); return; diff --git a/test/parallel/test-tls-write-error.js b/test/parallel/test-tls-write-error.js index f6ec7b9bd245..67b4c944dcad 100644 --- a/test/parallel/test-tls-write-error.js +++ b/test/parallel/test-tls-write-error.js @@ -7,7 +7,7 @@ const { TestTLSSocket, ccs } = require('../common/tls'); const fixtures = require('../common/fixtures'); const assert = require('assert'); const https = require('https'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); // Regression test for an use-after-free bug in the TLS implementation that // would occur when `SSL_write()` failed. @@ -22,7 +22,7 @@ const opts = { }; const rejectsClientHello = hasFIPS(3) && !hasFIPS(3, 5); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { opts.ciphers = 'ALL@SECLEVEL=0'; } diff --git a/test/parallel/test-trace-env.js b/test/parallel/test-trace-env.js index 7a7b80fa4c10..956d78a15ef0 100644 --- a/test/parallel/test-trace-env.js +++ b/test/parallel/test-trace-env.js @@ -19,8 +19,8 @@ spawnSyncAndAssert(process.execPath, ['--trace-env', fixtures.path('empty.js')], if (common.hasCrypto) { assert.match(output, /get "NODE_EXTRA_CA_CERTS"/); - const { hasOpenSSL3 } = require('../common/crypto'); - if (hasOpenSSL3) { + const { isBoringSSL } = require('../common/crypto'); + if (!isBoringSSL()) { assert.match(output, /get "OPENSSL_CONF"/); } } diff --git a/test/parallel/test-webcrypto-aead-decrypt-detached-buffer.js b/test/parallel/test-webcrypto-aead-decrypt-detached-buffer.js index 5960c46f8aa8..31fa2f46e8af 100644 --- a/test/parallel/test-webcrypto-aead-decrypt-detached-buffer.js +++ b/test/parallel/test-webcrypto-aead-decrypt-detached-buffer.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const fips3 = hasFIPS(3); @@ -55,7 +55,7 @@ if (fips3) { tests.push(test('ChaCha20-Poly1305', 32, 12, 'raw-secret')); } -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { tests.push(test( 'AES-OCB', 32, diff --git a/test/parallel/test-webcrypto-crypto-job-mode.js b/test/parallel/test-webcrypto-crypto-job-mode.js index 327c6a6f154c..eb540cc1e774 100644 --- a/test/parallel/test-webcrypto-crypto-job-mode.js +++ b/test/parallel/test-webcrypto-crypto-job-mode.js @@ -7,7 +7,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const { types: { isCryptoKey } } = require('util'); const { internalBinding } = require('internal/test/binding'); const { @@ -211,7 +211,7 @@ async function withObjectPrototypeSetters(names, fn) { } } - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { const pair = await subtle.generateKey( { name: 'ML-KEM-768' }, true, diff --git a/test/parallel/test-webcrypto-deduplicate-usages.js b/test/parallel/test-webcrypto-deduplicate-usages.js index d27675d873ce..d7172f3f1a62 100644 --- a/test/parallel/test-webcrypto-deduplicate-usages.js +++ b/test/parallel/test-webcrypto-deduplicate-usages.js @@ -13,7 +13,7 @@ if (!common.hasCrypto) const assert = require('assert'); const { createSecretKey } = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; function assertSameSet(actual, expected, msg) { @@ -54,7 +54,7 @@ function assertSameSet(actual, expected, msg) { symmetric.splice(symmetric.findIndex(({ algorithm }) => algorithm.name === 'ChaCha20-Poly1305'), 1); - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { symmetric.push({ algorithm: { name: 'AES-OCB', length: 128 }, usages: ['decrypt', 'encrypt', 'decrypt', 'encrypt'], @@ -66,7 +66,7 @@ function assertSameSet(actual, expected, msg) { expected: ['sign', 'verify'], }); } else { - common.printSkipMessage('AES-OCB and KMAC require OpenSSL >= 3'); + common.printSkipMessage('AES-OCB and KMAC are not supported by BoringSSL'); } for (const { algorithm, usages, expected } of symmetric) { @@ -115,7 +115,7 @@ function assertSameSet(actual, expected, msg) { asymmetric.splice(asymmetric.findIndex(({ algorithm }) => algorithm.name === 'X25519'), 1); - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { asymmetric.push({ algorithm: { name: 'ML-DSA-65' }, usages: ['verify', 'sign', 'verify', 'sign'], @@ -171,7 +171,7 @@ function assertSameSet(actual, expected, msg) { expected: ['wrapKey', 'unwrapKey'] }, ]; - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { // KMAC does not support `raw` format, only `raw-secret` and `jwk`. tests.push((async () => { const key = await subtle.importKey( @@ -196,7 +196,7 @@ function assertSameSet(actual, expected, msg) { assert.strictEqual(key.usages.length, 2); })()); } else { - common.printSkipMessage('AES-OCB and KMAC require OpenSSL >= 3'); + common.printSkipMessage('AES-OCB and KMAC are not supported by BoringSSL'); } for (const { algorithm, keyData, usages, expected } of rawSymmetric) { @@ -297,7 +297,7 @@ function assertSameSet(actual, expected, msg) { assert.deepStrictEqual(imported.usages, ['sign']); })()); - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { // ML-DSA JWK roundtrip. tests.push((async () => { const { privateKey } = await subtle.generateKey( @@ -360,7 +360,7 @@ function assertSameSet(actual, expected, msg) { })()); // AES-OCB raw-secret import. - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { tests.push((async () => { const key = await subtle.importKey( 'raw-secret', @@ -372,7 +372,7 @@ function assertSameSet(actual, expected, msg) { assert.strictEqual(key.usages.length, 2); })()); } else { - common.printSkipMessage('AES-OCB requires OpenSSL >= 3'); + common.printSkipMessage('AES-OCB is not supported by BoringSSL'); } Promise.all(tests).then(common.mustCall()); @@ -448,7 +448,7 @@ function assertSameSet(actual, expected, msg) { expected: ['wrapKey', 'unwrapKey'] }, ]; - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { jwkVectors.push({ algorithm: { name: 'AES-OCB', length: 128 }, usages: ['decrypt', 'encrypt', 'decrypt', 'encrypt'], @@ -460,7 +460,7 @@ function assertSameSet(actual, expected, msg) { expected: ['sign', 'verify'], }); } else { - common.printSkipMessage('AES-OCB and KMAC require OpenSSL >= 3'); + common.printSkipMessage('AES-OCB and KMAC are not supported by BoringSSL'); } for (const { algorithm, usages, expected } of jwkVectors) { @@ -508,7 +508,7 @@ function assertSameSet(actual, expected, msg) { jwkPairVectors.splice(jwkPairVectors.findIndex(({ algorithm }) => algorithm.name === 'X25519'), 1); - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { jwkPairVectors.push({ algorithm: { name: 'ML-DSA-65' }, usages: ['verify', 'sign', 'verify', 'sign'], diff --git a/test/parallel/test-webcrypto-derivebits-cfrg.js b/test/parallel/test-webcrypto-derivebits-cfrg.js index fae39ac89c5e..0151b5624fe0 100644 --- a/test/parallel/test-webcrypto-derivebits-cfrg.js +++ b/test/parallel/test-webcrypto-derivebits-cfrg.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const rejectsXCurves = hasFIPS(3, 5); @@ -22,7 +22,7 @@ const kTests = [ }, ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { kTests.push( { name: 'X448', diff --git a/test/parallel/test-webcrypto-derivebits-hkdf.js b/test/parallel/test-webcrypto-derivebits-hkdf.js index 539440ea7c31..d7ef5ffe81ac 100644 --- a/test/parallel/test-webcrypto-derivebits-hkdf.js +++ b/test/parallel/test-webcrypto-derivebits-hkdf.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; function getDeriveKeyInfo(name, length, hash, ...usages) { @@ -28,7 +28,7 @@ const kDerivedKeyTypes = [ ['AES-KW', 256, undefined, 'wrapKey', 'unwrapKey'], ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { kDerivedKeyTypes.push( ['HMAC', 256, 'SHA3-256', 'sign', 'verify'], ['HMAC', 256, 'SHA3-384', 'sign', 'verify'], @@ -38,13 +38,13 @@ if (!process.features.openssl_is_boringssl) { common.printSkipMessage('Skipping unsupported test cases'); } -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { kDerivedKeyTypes.push( ['AES-OCB', 128, undefined, 'encrypt', 'decrypt'], ['AES-OCB', 256, undefined, 'encrypt', 'decrypt'], ); } else { - common.printSkipMessage('Skipping unsupported test cases'); + common.printSkipMessage('Skipping AES-OCB test cases unsupported by BoringSSL'); } const kDerivedKeys = { @@ -91,7 +91,7 @@ const kDerivations = { empty: '9e4b719033742101e90f1ad61e2ff3b4' + '256863667296d74389f1f02af2c4e6a6' }, - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': { normal: '386b0693d7a58c4ddf01b49bfbbd2fa87c6f911991543995170ba20ed28df599', empty: 'd029bc828b6c6c8bb16ce3d25f5058f19c7d2517745e11c5d65c6d242e82e47f', @@ -131,7 +131,7 @@ const kDerivations = { empty: 'c8e12774135305c9147f2cc4766e5ead' + '25d8f457b9a1953d52677361ced558fb' }, - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': { normal: '9befc557f5baf4075b5fb38c014b41b92ab7534150baf64201069e8807d0e83d', empty: '54d1fa1aa7cad99dab0622b772170e775c103756183bac36a228fd817a98a3f6', @@ -173,7 +173,7 @@ const kDerivations = { empty: 'e579d1f9e7f08e6f990ffcfcce1ed201' + 'c5e37e62cdf606f0ba4aca80427fbc44' }, - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': { normal: '24f38fd1905554b7cbf8395cc3976292d11ce24a0b3131da0fd4b109832d27e3', empty: '33d0a5151c0f52e4bb7fb67cf7a17063127624dc3e685903f49ebb07872084d1', @@ -213,7 +213,7 @@ const kDerivations = { empty: 'b4f7e7557674d501cbfbc0148ad800c0' + '750189fe295a2aca5e1bf4122c85edf9' }, - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'SHA3-256': { normal: 'fe32459f7339dd2e8df6c6fc874ed9e81e3b7aad669edad9b71196f53ed95b12', empty: '04519be1eb94079c91306cc5b21946b3de6a78ad35ec83d4f4a37bafbda678d7', diff --git a/test/parallel/test-webcrypto-derivebits.js b/test/parallel/test-webcrypto-derivebits.js index 6ef2227ab2d2..4c938c5120a9 100644 --- a/test/parallel/test-webcrypto-derivebits.js +++ b/test/parallel/test-webcrypto-derivebits.js @@ -7,7 +7,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const requiresLongHkdfInputs = hasFIPS(3) && !hasFIPS(3, 5); const rejectsWeakPbkdf2Inputs = hasFIPS(4); @@ -152,7 +152,7 @@ const rejectsXCurves = hasFIPS(3, 5); } } else { test('X25519').then(common.mustCall()); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { test('X448').then(common.mustCall()); } else { common.printSkipMessage('Skipping unsupported X448 test case'); diff --git a/test/parallel/test-webcrypto-derivekey-cfrg.js b/test/parallel/test-webcrypto-derivekey-cfrg.js index 13c4e56ce5b0..5af0df7b7306 100644 --- a/test/parallel/test-webcrypto-derivekey-cfrg.js +++ b/test/parallel/test-webcrypto-derivekey-cfrg.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const rejectsXCurves = hasFIPS(3, 5); @@ -22,7 +22,7 @@ const kTests = [ }, ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { kTests.push( { name: 'X448', diff --git a/test/parallel/test-webcrypto-derivekey.js b/test/parallel/test-webcrypto-derivekey.js index 631951c3f767..8b0ae7966a18 100644 --- a/test/parallel/test-webcrypto-derivekey.js +++ b/test/parallel/test-webcrypto-derivekey.js @@ -6,7 +6,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { subtle } = globalThis.crypto; @@ -87,7 +87,7 @@ const fips4 = hasFIPS(4); 'a7abd704d0be364c6d4a530b6f93fcaff95474a2eee5a127ff86c5d095a2a812'], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { kTests.push( ['hello hello hello', 'there', 'my friend indeed', 'SHA3-256', '89b3751df2ada85322a57ec82f7d0a5c233c6def91c92e681bc5118bd5768dca'], @@ -140,7 +140,7 @@ const fips4 = hasFIPS(4); '12790ce09027db067d680670f4dc704715b5120d139e8fde810afc34fb66f9f1'], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { kTests.push( ['hello hello hello', 'my friend indeed', 1000, 'SHA3-256', '0f69b46660cba27b95215d5676492c64ed6abf6d426669a4a02b0ca3a1c36c11'], @@ -176,7 +176,7 @@ const fips4 = hasFIPS(4); [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { vectors.push( [{ name: 'HMAC', hash: 'SHA3-256', length: 256 }, 'sign', 256], [{ name: 'HMAC', hash: 'SHA3-384', length: 384 }, 'sign', 384], @@ -191,7 +191,7 @@ const fips4 = hasFIPS(4); common.printSkipMessage('Skipping unsupported SHA-3 test cases'); } - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { vectors.push( ['KMAC128', 'sign', 128], [{ name: 'KMAC128', length: 384 }, 'sign', 384], @@ -236,7 +236,7 @@ const fips4 = hasFIPS(4); [{ name: 'HMAC', hash: 'SHA-512' }, 'sign', 1024], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { vectors.push( [{ name: 'HMAC', hash: 'SHA3-256', length: 256 }, 'sign', 256], [{ name: 'HMAC', hash: 'SHA3-384', length: 384 }, 'sign', 384], @@ -251,7 +251,7 @@ const fips4 = hasFIPS(4); common.printSkipMessage('Skipping unsupported SHA-3 test cases'); } - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { vectors.push( ['KMAC128', 'sign', 128], [{ name: 'KMAC128', length: 384 }, 'sign', 384], @@ -284,7 +284,7 @@ const fips4 = hasFIPS(4); })().then(common.mustCall()); } -if (hasOpenSSL(3) && !hasFIPS()) { +if (!isBoringSSL() && !hasFIPS()) { (async () => { const derivedKeyAlgorithm = { name: 'KMAC128', length: 0 }; const usages = ['sign']; @@ -372,7 +372,7 @@ if (hasOpenSSL(3) && !hasFIPS()) { } } else { test('X25519').then(common.mustCall()); - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { test('X448').then(common.mustCall()); } else { common.printSkipMessage('Skipping unsupported X448 test case'); diff --git a/test/parallel/test-webcrypto-digest.js b/test/parallel/test-webcrypto-digest.js index 7c0ef7668c61..4c0791c3ffe5 100644 --- a/test/parallel/test-webcrypto-digest.js +++ b/test/parallel/test-webcrypto-digest.js @@ -9,7 +9,7 @@ const assert = require('assert'); const { Buffer } = require('buffer'); const { subtle } = globalThis.crypto; const { createHash, getHashes } = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const fips = hasFIPS(); const kTests = [ @@ -19,7 +19,7 @@ const kTests = [ ['SHA-512', ['sha512'], 512], ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { kTests.push( [{ name: 'cSHAKE128', outputLength: 256 }, ['shake128', { outputLength: 256 >> 3 }], 256], [{ name: 'cSHAKE256', outputLength: 512 }, ['shake256', { outputLength: 512 >> 3 }], 512], @@ -150,7 +150,7 @@ const kDigestedData = { '60b22aab8d36a4c2a3affdb71234f49276737c575ddf7' + '4d14054cbd6fdb98fd0ddcbcb46f91ad76b6ee' }, - ...(!process.features.openssl_is_boringssl ? { + ...(!isBoringSSL() ? { 'cshake128': { empty: '7f9c2ba4e88f827d616045507605853ed73b8093f6e' + 'fbc88eb1a6eacfa66ef26', @@ -306,7 +306,7 @@ if (getHashes().includes('shake128')) { message: 'CShakeParams.customization must be at most 512 bytes', }); - if (!hasOpenSSL(3)) return; + if (isBoringSSL()) return; const nistCShakeShortInput = Buffer.from('00010203', 'hex'); const nistCShakeLongInput = diff --git a/test/parallel/test-webcrypto-encap-decap-ml-kem.js b/test/parallel/test-webcrypto-encap-decap-ml-kem.js index dbb0a7d3fa8b..1daf434707fb 100644 --- a/test/parallel/test-webcrypto-encap-decap-ml-kem.js +++ b/test/parallel/test-webcrypto-encap-decap-ml-kem.js @@ -6,9 +6,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); @@ -288,7 +288,7 @@ async function testDecapsulateBits({ name, publicKeyPem, privateKeyPem, results const variations = []; for (const vector of vectors) { - if (process.features.openssl_is_boringssl && vector.name === 'ML-KEM-512') { + if (isBoringSSL() && vector.name === 'ML-KEM-512') { common.printSkipMessage(`Skipping unsupported ${vector.name} test`); continue; } diff --git a/test/parallel/test-webcrypto-encrypt-decrypt-aes.js b/test/parallel/test-webcrypto-encrypt-decrypt-aes.js index 00c294839bfe..5295c8cea7d1 100644 --- a/test/parallel/test-webcrypto-encrypt-decrypt-aes.js +++ b/test/parallel/test-webcrypto-encrypt-decrypt-aes.js @@ -5,7 +5,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { getFips } = require('crypto'); @@ -230,7 +230,7 @@ async function testDecrypt({ keyBuffer, algorithm, result }) { } // Test aes-ocb vectors -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { const { passing, failing, diff --git a/test/parallel/test-webcrypto-encrypt-decrypt.js b/test/parallel/test-webcrypto-encrypt-decrypt.js index 1015752a8b0a..fb7648426a22 100644 --- a/test/parallel/test-webcrypto-encrypt-decrypt.js +++ b/test/parallel/test-webcrypto-encrypt-decrypt.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { getFips } = require('crypto'); const { subtle } = globalThis.crypto; @@ -59,7 +59,7 @@ const { subtle } = globalThis.crypto; } // Test Encrypt/Decrypt RSA-OAEP w/ SHA-3 -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); async function test() { @@ -185,7 +185,7 @@ if (!process.features.openssl_is_boringssl) { } // Test Encrypt/Decrypt AES-OCB -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); const iv = globalThis.crypto.getRandomValues(new Uint8Array(12)); @@ -218,5 +218,5 @@ if (hasOpenSSL(3)) { test().then(common.mustCall()); } } else { - common.printSkipMessage('Skipping unsupported AES-OCB test cases'); + common.printSkipMessage('Skipping AES-OCB test cases unsupported by BoringSSL'); } diff --git a/test/parallel/test-webcrypto-export-import-cfrg.js b/test/parallel/test-webcrypto-export-import-cfrg.js index fb8014840f34..c100e57cedf9 100644 --- a/test/parallel/test-webcrypto-export-import-cfrg.js +++ b/test/parallel/test-webcrypto-export-import-cfrg.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const rejectsXCurves = hasFIPS(3, 5); @@ -96,7 +96,7 @@ const testVectors = [ }, ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { testVectors.push( { name: 'Ed448', diff --git a/test/parallel/test-webcrypto-export-import-ml-dsa.js b/test/parallel/test-webcrypto-export-import-ml-dsa.js index 9c6e04da053c..c5c37dd49dd5 100644 --- a/test/parallel/test-webcrypto-export-import-ml-dsa.js +++ b/test/parallel/test-webcrypto-export-import-ml-dsa.js @@ -5,9 +5,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); @@ -105,7 +105,7 @@ async function testImportPkcs8({ name, privateUsages }, extractable) { extractable, privateUsages); } catch (err) { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { assert.strictEqual(err.name, 'DataError'); assert.strictEqual(err.cause.code, 'ERR_OSSL_EVP_PRIVATE_KEY_WAS_NOT_SEED'); common.printSkipMessage('Skipping unsupported private key format test'); @@ -525,7 +525,7 @@ async function testImportRawSeed({ name, privateUsages }, extractable) { } })().then(common.mustCall()); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { (async function() { for (const { name, privateUsages } of testVectors) { const pem = fixtures.readKey(getKeyFileName(name.toLowerCase(), 'private_priv_only'), 'ascii'); diff --git a/test/parallel/test-webcrypto-export-import-ml-kem.js b/test/parallel/test-webcrypto-export-import-ml-kem.js index 862eea96726d..34757b3710c0 100644 --- a/test/parallel/test-webcrypto-export-import-ml-kem.js +++ b/test/parallel/test-webcrypto-export-import-ml-kem.js @@ -5,9 +5,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); @@ -105,7 +105,7 @@ async function testImportPkcs8({ name, privateUsages }, extractable) { extractable, privateUsages); } catch (err) { - if (process.features.openssl_is_boringssl) { + if (isBoringSSL()) { assert.strictEqual(err.name, 'DataError'); assert.strictEqual(err.cause.code, 'ERR_OSSL_EVP_PRIVATE_KEY_WAS_NOT_SEED'); @@ -469,7 +469,7 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) (async function() { const tests = []; for (const vector of testVectors) { - if (process.features.openssl_is_boringssl && vector.name === 'ML-KEM-512') { + if (isBoringSSL() && vector.name === 'ML-KEM-512') { common.printSkipMessage('Skipping unsupported ML-KEM-512 test'); continue; } @@ -525,7 +525,7 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) } })().then(common.mustCall()); -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { (async function() { for (const { name, privateUsages } of testVectors) { const pem = fixtures.readKey(getKeyFileName(name.toLowerCase(), 'private_priv_only'), 'ascii'); diff --git a/test/parallel/test-webcrypto-export-import-rsa.js b/test/parallel/test-webcrypto-export-import-rsa.js index 294baff544a6..7e4626864d31 100644 --- a/test/parallel/test-webcrypto-export-import-rsa.js +++ b/test/parallel/test-webcrypto-export-import-rsa.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); if (!common.hasCrypto) @@ -19,7 +21,7 @@ const hashes = [ 'SHA-512', ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { hashes.push( 'SHA3-256', 'SHA3-384', diff --git a/test/parallel/test-webcrypto-export-import.js b/test/parallel/test-webcrypto-export-import.js index 30d1ea622fae..e0fff3a6028d 100644 --- a/test/parallel/test-webcrypto-export-import.js +++ b/test/parallel/test-webcrypto-export-import.js @@ -6,7 +6,7 @@ const fixtures = require('../common/fixtures'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { subtle } = globalThis.crypto; @@ -221,7 +221,7 @@ const { } // Import/Export KMAC Secret Key -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { async function test(name) { const keyData = globalThis.crypto.getRandomValues(new Uint8Array(32)); const key = await subtle.importKey( @@ -518,7 +518,7 @@ if (hasOpenSSL(3)) { } // SHA-3 hashes and JWK "alg" -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { const rsa = fixtures.readKey('rsa_private_2048.pem'); const privateKey = createPrivateKey(rsa); const publicKey = createPublicKey(privateKey); diff --git a/test/parallel/test-webcrypto-keygen-kmac.js b/test/parallel/test-webcrypto-keygen-kmac.js index 33716095751f..e0ef20c821d7 100644 --- a/test/parallel/test-webcrypto-keygen-kmac.js +++ b/test/parallel/test-webcrypto-keygen-kmac.js @@ -5,10 +5,10 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasFIPS, hasOpenSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - common.skip('requires OpenSSL >= 3'); +if (isBoringSSL()) + common.skip('KMAC is not supported by BoringSSL'); const assert = require('assert'); const { types: { isCryptoKey } } = require('util'); diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index 6e264031c4d1..9b3a887b4c31 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -6,7 +6,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { types: { isCryptoKey } } = require('util'); @@ -158,7 +158,7 @@ const vectors = { }, }; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { vectors.Ed448 = { result: 'CryptoKeyPair', usages: [ @@ -177,7 +177,7 @@ if (!process.features.openssl_is_boringssl) { common.printSkipMessage('Skipping unsupported test cases'); } -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { vectors['AES-OCB'] = { algorithm: { length: 256 }, result: 'CryptoKey', @@ -200,7 +200,7 @@ if (hasOpenSSL(3)) { } } -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { for (const name of ['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']) { vectors[name] = { result: 'CryptoKeyPair', @@ -504,7 +504,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { let fipsExponentTest; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { if (fips3) { fipsExponentTest = assert.rejects( subtle.generateKey({ @@ -722,7 +722,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { [1024, 'SHA-512', ['sign', 'verify']], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { kTests.push( [256, 'SHA3-256', ['sign', 'verify']], [384, 'SHA3-384', ['sign', 'verify']], @@ -808,7 +808,7 @@ assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); ], ]; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { kTests.push( [ 'Ed448', @@ -836,7 +836,7 @@ assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); } // Test ML-DSA Key Generation -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { async function test( name, privateUsages, @@ -879,7 +879,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { } // Test ML-KEM Key Generation -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { async function test( name, privateUsages, @@ -916,7 +916,7 @@ if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { const kTests = ['ML-KEM-768', 'ML-KEM-1024']; - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { kTests.unshift('ML-KEM-512'); } else { common.printSkipMessage('Skipping unsupported ML-KEM-512 test'); diff --git a/test/parallel/test-webcrypto-prototype-pollution.mjs b/test/parallel/test-webcrypto-prototype-pollution.mjs index 9f0b41ac10bb..73505c3055f2 100644 --- a/test/parallel/test-webcrypto-prototype-pollution.mjs +++ b/test/parallel/test-webcrypto-prototype-pollution.mjs @@ -14,7 +14,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const require = createRequire(import.meta.url); const { kSupportedAlgorithms } = require('internal/crypto/util'); const { getFips } = require('node:crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype); @@ -136,7 +136,7 @@ if (supports('digest', 'cSHAKE128')) { // asyncDigest() picks the cSHAKE job over plain SHAKE on a non-empty // customization. - if (hasOpenSSL(3)) { + if (!isBoringSSL()) { const algorithm = { name: 'cSHAKE128', outputLength: 256, diff --git a/test/parallel/test-webcrypto-sign-verify-eddsa.js b/test/parallel/test-webcrypto-sign-verify-eddsa.js index e34a3d43d2a3..8988e968b40f 100644 --- a/test/parallel/test-webcrypto-sign-verify-eddsa.js +++ b/test/parallel/test-webcrypto-sign-verify-eddsa.js @@ -5,7 +5,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const crypto = require('crypto'); @@ -31,7 +31,7 @@ const smallOrderVerifyVectors = [ }, ]; -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { smallOrderVerifyVectors.push({ name: 'Ed448', publicKey: Buffer.concat([Buffer.from([1]), Buffer.alloc(56)]), diff --git a/test/parallel/test-webcrypto-sign-verify-kmac.js b/test/parallel/test-webcrypto-sign-verify-kmac.js index ac0b738bcd57..9a0e37cf6930 100644 --- a/test/parallel/test-webcrypto-sign-verify-kmac.js +++ b/test/parallel/test-webcrypto-sign-verify-kmac.js @@ -5,10 +5,10 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasFIPS, hasOpenSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - common.skip('requires OpenSSL >= 3'); +if (isBoringSSL()) + common.skip('KMAC is not supported by BoringSSL'); const assert = require('assert'); const { subtle } = globalThis.crypto; diff --git a/test/parallel/test-webcrypto-sign-verify-ml-dsa.js b/test/parallel/test-webcrypto-sign-verify-ml-dsa.js index ba6eab08efb1..bd4b57847fda 100644 --- a/test/parallel/test-webcrypto-sign-verify-ml-dsa.js +++ b/test/parallel/test-webcrypto-sign-verify-ml-dsa.js @@ -5,9 +5,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) +if (!hasOpenSSL(3, 5) && !isBoringSSL()) common.skip('requires OpenSSL >= 3.5 or BoringSSL'); const assert = require('assert'); diff --git a/test/parallel/test-webcrypto-sign-verify-rsa.js b/test/parallel/test-webcrypto-sign-verify-rsa.js index 12633cd50de2..ab2b3578ebb0 100644 --- a/test/parallel/test-webcrypto-sign-verify-rsa.js +++ b/test/parallel/test-webcrypto-sign-verify-rsa.js @@ -6,7 +6,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; const fips3 = hasFIPS(3); const rejectsSha1Signing = hasFIPS(3) && !hasFIPS(3, 5); @@ -269,7 +269,7 @@ async function testSaltLength(keyLength, hash, hLen) { ['SHA-256', 32], ['SHA-384', 48], ['SHA-512', 64], - ...(!process.features.openssl_is_boringssl ? [ + ...(!isBoringSSL() ? [ ['SHA3-256', 32], ['SHA3-384', 48], ['SHA3-512', 64], diff --git a/test/parallel/test-webcrypto-sign-verify.js b/test/parallel/test-webcrypto-sign-verify.js index db6c9e093872..3a87333a95ef 100644 --- a/test/parallel/test-webcrypto-sign-verify.js +++ b/test/parallel/test-webcrypto-sign-verify.js @@ -5,7 +5,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { getFips } = require('crypto'); @@ -109,7 +109,7 @@ const { subtle } = globalThis.crypto; } // Test Sign/Verify KMAC -if (hasOpenSSL(3)) { +if (!isBoringSSL()) { async function test(name, data) { const ec = new TextEncoder(); @@ -152,7 +152,7 @@ if (hasOpenSSL(3)) { } // Test Sign/Verify Ed448 -if (!process.features.openssl_is_boringssl) { +if (!isBoringSSL()) { async function test(data) { const ec = new TextEncoder(); const { publicKey, privateKey } = await subtle.generateKey({ @@ -174,7 +174,7 @@ if (!process.features.openssl_is_boringssl) { } // Test Sign/Verify ML-DSA -if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { +if (hasOpenSSL(3, 5) || isBoringSSL()) { async function test(name, data) { const ec = new TextEncoder(); const { publicKey, privateKey } = await subtle.generateKey({ diff --git a/test/parallel/test-webcrypto-wrap-unwrap.js b/test/parallel/test-webcrypto-wrap-unwrap.js index 5ffffe230ac6..d6979aa6d032 100644 --- a/test/parallel/test-webcrypto-wrap-unwrap.js +++ b/test/parallel/test-webcrypto-wrap-unwrap.js @@ -5,7 +5,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { getFips } = require('crypto'); @@ -60,7 +60,7 @@ const kWrappingData = { if (fips3) delete kWrappingData['ChaCha20-Poly1305']; -if (hasOpenSSL(3) && !fips3) { +if (!isBoringSSL() && !fips3) { kWrappingData['AES-OCB'] = { generate: { length: 128 }, wrap: { @@ -206,7 +206,7 @@ async function generateKeysToWrap() { }, ]; - if (hasOpenSSL(3, 5) || process.features.openssl_is_boringssl) { + if (hasOpenSSL(3, 5) || isBoringSSL()) { for (const name of ['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']) { parameters.push({ algorithm: { name }, @@ -217,7 +217,7 @@ async function generateKeysToWrap() { } } - if (!process.features.openssl_is_boringssl) { + if (!isBoringSSL()) { parameters.push( { algorithm: { @@ -485,7 +485,7 @@ async function testNonByteLengthWrapUnwrap({ implicitAlgorithm: hmacAlgorithm, }); - if (hasOpenSSL(3) && getFips() !== 1) { + if (!isBoringSSL() && getFips() !== 1) { const kmacAlgorithm = { name: 'KMAC128' }; const kmacKey = await subtle.importKey( 'raw-secret', diff --git a/test/parallel/test-x509-escaping.js b/test/parallel/test-x509-escaping.js index ab91e3345556..e1bfaa3c0e4a 100644 --- a/test/parallel/test-x509-escaping.js +++ b/test/parallel/test-x509-escaping.js @@ -10,7 +10,7 @@ const { X509Certificate } = require('crypto'); const tls = require('tls'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); // Test that all certificate chains provided by the reporter are rejected. { @@ -59,8 +59,8 @@ const { hasOpenSSL3 } = require('../common/crypto'); 'IP Address:8.8.8.8', 'IP Address:8.8.4.4', // For backward-compatibility, include invalid IP address lengths. - hasOpenSSL3 ? 'IP Address:' : 'IP Address:', - hasOpenSSL3 ? 'IP Address:' : 'IP Address:', + isBoringSSL() ? 'IP Address:' : 'IP Address:', + isBoringSSL() ? 'IP Address:' : 'IP Address:', // IPv6 addresses are represented as OpenSSL does. 'IP Address:A0B:C0D:E0F:0:0:0:7A7B:7C7D', // Regular email addresses don't require escaping. @@ -88,22 +88,22 @@ const { hasOpenSSL3 } = require('../common/crypto'); // This is an OID that will likely never be assigned to anything, thus // OpenSSL should not know it. 'Registered ID:1.3.9999.12.34', - hasOpenSSL3 ? + !isBoringSSL() ? 'othername:XmppAddr:abc123' : 'othername:', - hasOpenSSL3 ? + !isBoringSSL() ? 'othername:"XmppAddr:abc123\\u002c DNS:good.example.com"' : 'othername:', - hasOpenSSL3 ? + !isBoringSSL() ? 'othername:"XmppAddr:good.example.com\\u0000abc123"' : 'othername:', // This is unsupported because the OID is not recognized. 'othername:', - hasOpenSSL3 ? 'othername:SRVName:abc123' : 'othername:', + isBoringSSL() ? 'othername:' : 'othername:SRVName:abc123', // This is unsupported because it is an SRVName with a UTF8String value, // which is not allowed for SRVName. 'othername:', - hasOpenSSL3 ? + !isBoringSSL() ? 'othername:"SRVName:abc\\u0000def"' : 'othername:', ]; @@ -173,7 +173,7 @@ const { hasOpenSSL3 } = require('../common/crypto'); ], }, }, - hasOpenSSL3 ? { + !isBoringSSL() ? { text: 'OCSP - othername:XmppAddr:good.example.com\n' + 'OCSP - othername:\n' + 'OCSP - othername:SRVName:abc123', @@ -196,7 +196,7 @@ const { hasOpenSSL3 } = require('../common/crypto'); ], }, }, - hasOpenSSL3 ? { + !isBoringSSL() ? { text: 'OCSP - othername:"XmppAddr:good.example.com\\u0000abc123"', legacy: { 'OCSP - othername': [ @@ -222,7 +222,7 @@ const { hasOpenSSL3 } = require('../common/crypto'); // Test the subjectAltName property of the X509Certificate API. const cert = new X509Certificate(pem); assert.strictEqual(cert.infoAccess, - `${expected.text}${hasOpenSSL3 ? '' : '\n'}`); + `${expected.text}${isBoringSSL() ? '\n' : ''}`); // Test that the certificate obtained by checkServerIdentity has the correct // subjectaltname property. @@ -439,7 +439,7 @@ const { hasOpenSSL3 } = require('../common/crypto'); // The hostname is the CN, but not a SAN entry. const servername = 'good.example.com'; - const cnFallback = process.features.openssl_is_boringssl ? undefined : + const cnFallback = isBoringSSL() ? undefined : servername; const certX509 = new X509Certificate(cert); assert.strictEqual(certX509.subject, `CN=${servername}`); @@ -485,7 +485,7 @@ const { hasOpenSSL3 } = require('../common/crypto'); assert.strictEqual(certX509.subjectAltName, 'IP Address:1.2.3.4'); // The newer X509Certificate API allows customizing this behavior: - const cnFallback = process.features.openssl_is_boringssl ? undefined : + const cnFallback = isBoringSSL() ? undefined : servername; assert.strictEqual(certX509.checkHost(servername), cnFallback); assert.strictEqual(certX509.checkHost(servername, { subject: 'default' }), diff --git a/test/pummel/test-crypto-dh-hash.js b/test/pummel/test-crypto-dh-hash.js index 03b4a9c831ae..e1304617c58d 100644 --- a/test/pummel/test-crypto-dh-hash.js +++ b/test/pummel/test-crypto-dh-hash.js @@ -30,10 +30,10 @@ if (common.isPi()) { common.skip('Too slow for Raspberry Pi devices'); } -const { hasOpenSSL3 } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL3) { - common.skip('Too slow when dynamically linked against OpenSSL 1.1.1'); +if (isBoringSSL()) { + common.skip('BoringSSL does not support all tested MODP groups'); } const assert = require('assert'); diff --git a/test/pummel/test-crypto-dh-keys.js b/test/pummel/test-crypto-dh-keys.js index 824628732a55..d1e99489625d 100644 --- a/test/pummel/test-crypto-dh-keys.js +++ b/test/pummel/test-crypto-dh-keys.js @@ -32,7 +32,7 @@ if (common.isPi()) { const assert = require('assert'); const crypto = require('crypto'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); for (const name of ['modp1', 'modp2', 'modp5', 'modp14', 'modp15', 'modp16', 'modp17']) { // modp1 is 768 bits, FIPS requires >= 1024. @@ -47,7 +47,7 @@ for (const name of ['modp1', 'modp2', 'modp5', 'modp14', 'modp15', 'modp16', 'mo continue; } if ((name === 'modp1' && crypto.getFips() === 1) || - (process.features.openssl_is_boringssl && + (isBoringSSL() && (name === 'modp1' || name === 'modp2'))) { common.printSkipMessage(`Skipping unsupported ${name} test case`); continue; diff --git a/test/pummel/test-dh-regr.js b/test/pummel/test-dh-regr.js index c442fbc3a809..7a45f824908a 100644 --- a/test/pummel/test-dh-regr.js +++ b/test/pummel/test-dh-regr.js @@ -32,7 +32,7 @@ if (common.isPi()) { const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); let p; let iterations = 2000; @@ -51,7 +51,7 @@ if (hasFIPS(3)) { } else { // FIPS requires length >= 1024, but small parameters keep this pummel test // from timing out in ordinary CI. - const length = crypto.getFips() === 1 ? 1024 : (hasOpenSSL(3) ? 512 : 256); + const length = crypto.getFips() === 1 ? 1024 : (isBoringSSL() ? 256 : 512); p = crypto.createDiffieHellman(length).getPrime(); } diff --git a/test/sequential/test-tls-psk-client.js b/test/sequential/test-tls-psk-client.js index 2eb6228f79f2..bd08e106ce74 100644 --- a/test/sequential/test-tls-psk-client.js +++ b/test/sequential/test-tls-psk-client.js @@ -5,7 +5,9 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -if (process.features.openssl_is_boringssl) { +const { isBoringSSL } = require('../common/crypto'); + +if (isBoringSSL()) { require('../common/boringssl').testPskTls13Unsupported(); return; } diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 095be39151ef..bb4a59da3a10 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -3,6 +3,7 @@ const { hasOpenSSL, hasFIPS, + isBoringSSL, } = require('../../common/crypto.js'); const conditionalFileSkips = {}; @@ -10,7 +11,7 @@ const conditionalSubtestSkips = {}; function skip(...files) { for (const file of files) { - const provider = process.features.openssl_is_boringssl ? + const provider = isBoringSSL() ? 'BoringSSL' : `OpenSSL ${process.versions.openssl}${hasFIPS(3) ? ' FIPS mode' : ''}`; conditionalFileSkips[file] = { @@ -29,7 +30,7 @@ function skipSubtests(...entries) { } } -if (!hasOpenSSL(3, 0)) { +if (isBoringSSL()) { skip( 'encrypt_decrypt/aes_ocb.tentative.https.any.js', 'generateKey/failures_AES-OCB.tentative.https.any.js', @@ -49,7 +50,7 @@ if (!hasOpenSSL(3, 2) || hasFIPS(3)) { 'import_export/Argon2_importKey.tentative.https.any.js'); } -if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { +if (!hasOpenSSL(3, 5) && !isBoringSSL()) { skip( 'encap_decap/encap_decap_bits.tentative.https.any.js', 'encap_decap/encap_decap_keys.tentative.https.any.js', @@ -71,7 +72,7 @@ if (!hasOpenSSL(3, 5) && !process.features.openssl_is_boringssl) { ]); } -if (process.features.openssl_is_boringssl) { +if (isBoringSSL()) { skip( 'derive_bits_keys/cfrg_curves_bits_curve448.tentative.https.any.js', 'derive_bits_keys/cfrg_curves_keys_curve448.tentative.https.any.js', diff --git a/tools/enable_fips_include.py b/tools/enable_fips_include.py deleted file mode 100644 index cb24c7d83b68..000000000000 --- 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 10862c1b160b..bd79303829bf 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/test.py b/tools/test.py index 2c2a4d78d80a..aa8c3fbddf53 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 5651b391b88e..e85f1a815a8e 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/constants.d.ts b/typings/internalBinding/constants.d.ts index 3c29df44c133..3182b8e088e0 100644 --- a/typings/internalBinding/constants.d.ts +++ b/typings/internalBinding/constants.d.ts @@ -193,7 +193,7 @@ export interface ConstantsBinding { COPYFILE_FICLONE_FORCE: 4; }; crypto: { - OPENSSL_VERSION_NUMBER: 269488319; + OPENSSL_VERSION_NUMBER: number; SSL_OP_ALL: 2147485780; SSL_OP_ALLOW_NO_DHE_KEX: 1024; SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: 262144; @@ -217,17 +217,6 @@ export interface ConstantsBinding { SSL_OP_NO_TLSv1_3: 536870912; SSL_OP_PRIORITIZE_CHACHA: 2097152; SSL_OP_TLS_ROLLBACK_BUG: 8388608; - ENGINE_METHOD_RSA: 1; - ENGINE_METHOD_DSA: 2; - ENGINE_METHOD_DH: 4; - ENGINE_METHOD_RAND: 8; - ENGINE_METHOD_EC: 2048; - ENGINE_METHOD_CIPHERS: 64; - ENGINE_METHOD_DIGESTS: 128; - ENGINE_METHOD_PKEY_METHS: 512; - ENGINE_METHOD_PKEY_ASN1_METHS: 1024; - ENGINE_METHOD_ALL: 65535; - ENGINE_METHOD_NONE: 0; DH_CHECK_P_NOT_SAFE_PRIME: 2; DH_CHECK_P_NOT_PRIME: 1; DH_UNABLE_TO_CHECK_GENERATOR: 4; diff --git a/typings/internalBinding/crypto.d.ts b/typings/internalBinding/crypto.d.ts index eb40d33c513c..0dd70ca7af5d 100644 --- a/typings/internalBinding/crypto.d.ts +++ b/typings/internalBinding/crypto.d.ts @@ -702,7 +702,6 @@ declare namespace InternalCryptoBinding { init(secureProtocol: string | undefined, minVersion: number, maxVersion: number): void; setKey(key: ByteSource, passphrase?: ByteSource): void; setSigalgs(sigalgs: string): void; - setEngineKey?(privateKeyIdentifier: string, privateKeyEngine: string): void; setCert(cert: ByteSource): void; setAllowPartialTrustChain(): void; addCACert(cert: ByteSource): void; @@ -722,7 +721,6 @@ declare namespace InternalCryptoBinding { setCertificateCompression(algorithms: number): void; close(): void; loadPKCS12(pfx: ByteSource, passphrase?: ByteSource): void; - setClientCertEngine(clientCertEngine: string): void; getTicketKeys(): Buffer; setTicketKeys(keys: ByteSource): void; enableTicketKeyCallback(): void; @@ -1022,7 +1020,6 @@ export interface CryptoBinding { resetRootCertStore(): void; secureBuffer(length: number): Uint8Array | undefined; secureHeapUsed(): bigint | undefined; - setEngine?(engine: string, flags: number): void; setupFipsIndicatorChannel(): void; setFipsCrypto(fips: boolean | number): void; startLoadingCertificatesOffThread(): void;