From 57d795384f4929f237696e220a664bc351e95d38 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 26 Jul 2026 14:18:37 +0200 Subject: [PATCH 01/10] build: require OpenSSL 3 or later configure now fails when --shared-openssl points at OpenSSL 1.x rather than failing later at compile or link time. The check skips BoringSSL, whose version macros claim 1.1.1. Stop setting the OpenSSL 1.1 API compatibility level for bundled builds. ncrypto selects the supported API level directly. Update the assembler capability check, shared-library matrix comments, and internal version-number typing for the new baseline. Signed-off-by: Filip Skokan Assisted-by: Codex --- .github/workflows/test-shared.yml | 4 ++-- BUILDING.md | 10 ++++++---- configure.py | 21 +++++++++++++++------ node.gypi | 1 - typings/internalBinding/constants.d.ts | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index 96e862c35916..f0ece530f729 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -257,8 +257,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..531373850321 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. @@ -1135,6 +1133,10 @@ A number of `configure` options are provided to support this use case. provide the ability to set the path to an external JavaScript file for the dependency to be used at runtime. +When building with `--shared-openssl`, Node.js requires OpenSSL 3.0 or later. +Support for building against OpenSSL 1.x was removed in Node.js 27.0.0, and +`configure` fails if an older version is detected. + It is the responsibility of any distribution shipping with these options to: diff --git a/configure.py b/configure.py index 99ce9326dc93..d5acdb8fa8e1 100755 --- a/configure.py +++ b/configure.py @@ -1392,8 +1392,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: @@ -2322,15 +2323,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''') @@ -2354,6 +2355,14 @@ def without_ssl_error(option): 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/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/typings/internalBinding/constants.d.ts b/typings/internalBinding/constants.d.ts index 3c29df44c133..ce962a32e2df 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; From 645c0d2dc01a11671f502a1c1af68ad2d460d2c8 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 26 Jul 2026 14:18:37 +0200 Subject: [PATCH 02/10] deps: remove ncrypto legacy OpenSSL backend Remove the OpenSSL 1.x backend and its legacy dss1 digest aliases. Rename the provider-backed path switch to NCRYPTO_USE_OPENSSL_PROVIDER and rewrite the remaining version guards as OPENSSL_IS_BORINGSSL checks. Remove version-adapter casts now that supported OpenSSL signatures are uniform. BoringSSL continues to use the legacy low-level key paths. Signed-off-by: Filip Skokan Assisted-by: Codex --- deps/ncrypto/engine.cc | 5 +- deps/ncrypto/ncrypto.cc | 288 ++++++++++++---------------- deps/ncrypto/ncrypto.gyp | 14 +- deps/ncrypto/ncrypto.h | 95 ++++----- src/crypto/crypto_context.cc | 16 +- src/crypto/crypto_context.h | 4 +- src/crypto/crypto_dh.cc | 2 +- src/crypto/crypto_hash.cc | 20 +- src/crypto/crypto_rsa.cc | 6 +- src/crypto/crypto_sig.cc | 4 +- src/crypto/crypto_tls.cc | 2 +- src/crypto/crypto_util.cc | 2 +- src/env.cc | 2 +- test/cctest/test_node_crypto_env.cc | 2 +- 14 files changed, 193 insertions(+), 269 deletions(-) diff --git a/deps/ncrypto/engine.cc b/deps/ncrypto/engine.cc index a8e64e250491..6b9514b8565e 100644 --- a/deps/ncrypto/engine.cc +++ b/deps/ncrypto/engine.cc @@ -1,8 +1,7 @@ #include "ncrypto.h" -#if !defined(OPENSSL_NO_ENGINE) && \ - ((defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT) || \ - NCRYPTO_USE_LEGACY_OPENSSL) +#if !defined(OPENSSL_NO_ENGINE) && defined(NCRYPTO_ENGINE_COMPAT) && \ + NCRYPTO_ENGINE_COMPAT #include #endif diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 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..e0c8e2b6e4b6 100644 --- a/deps/ncrypto/ncrypto.gyp +++ b/deps/ncrypto/ncrypto.gyp @@ -13,9 +13,6 @@ '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', @@ -36,24 +33,19 @@ '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': [ '../openssl/openssl.gyp:openssl' @@ -63,7 +55,7 @@ }, ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { + ['openssl_is_boringssl=="false"', { 'targets': [ { 'target_name': 'ncrypto_engine', diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 79f403788cf4..2830d20f9563 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -32,6 +32,11 @@ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20))) #endif +// BoringSSL reports itself as OpenSSL 1.1.1, so it has to be excluded here. +#if !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_VERSION_PREREQ(3, 0) +#error "OpenSSL 1.x is no longer supported, v3.0.0 or later is required." +#endif + // BoringSSL declares the EVP_*_do_all* APIs, but their implementation may // live in libdecrepit. This matches standalone ncrypto's build flag. #ifndef NCRYPTO_BSSL_LIBDECREPIT_MISSING @@ -45,46 +50,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 +#define NCRYPTO_USE_LEGACY_KEY_TYPES NCRYPTO_USE_BORINGSSL -#if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_LEGACY_OPENSSL -#define NCRYPTO_USE_LEGACY_KEY_TYPES 1 -#else -#define NCRYPTO_USE_LEGACY_KEY_TYPES 0 -#endif - -#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 +81,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 +148,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 +385,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 +410,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 +443,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 +462,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 +488,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 +529,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 +624,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 +636,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 +660,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 +675,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 +735,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 +755,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 +778,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 +1126,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 +1291,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 +1302,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 +1371,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 +1699,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 +1743,7 @@ class ECKeyPointer final { #endif private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr group_; DeleteFnPtr pub_; DeleteFnPtr priv_; diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 9dc68f4d9d2d..01b87f3d7d3c 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1634,7 +1634,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { 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 @@ -1946,7 +1946,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 +1970,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 +1979,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 } @@ -2384,7 +2384,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 +2392,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 +2416,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 +2513,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..866340079841 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -158,7 +158,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 +169,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, diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 7fbaf4fff5d9..a4b497727a1e 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -206,7 +206,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..681ca532df4a 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()) { diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index e80c70c961df..5c0ab2e2d814 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; @@ -365,7 +365,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 +437,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)); 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..3f22bfc33d7e 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -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_util.cc b/src/crypto/crypto_util.cc index 942e00accba9..10bf8e18cef4 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -934,7 +934,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); diff --git a/src/env.cc b/src/env.cc index 5626b2a7e10e..f6cd2ac91881 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/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index fddf584d7d41..1d31dc983296 100644 --- a/test/cctest/test_node_crypto_env.cc +++ b/test/cctest/test_node_crypto_env.cc @@ -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; From 43dd27dbae1c96a9e20adbfa38c4c84fedf31358 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 26 Jul 2026 14:18:38 +0200 Subject: [PATCH 03/10] crypto: remove legacy OpenSSL code paths Remove the OpenSSL 1.x branches and stale version-specific assumptions from src/. BoringSSL does not define OPENSSL_VERSION_MAJOR, so the remaining version guards were excluding it as well; use OPENSSL_IS_BORINGSSL checks instead. Make the OpenSSL legacy-provider command-line help version-neutral. Signed-off-by: Filip Skokan Assisted-by: Codex --- src/crypto/README.md | 4 ++-- src/crypto/crypto_aes.cc | 7 ++----- src/crypto/crypto_cipher.cc | 4 ++-- src/crypto/crypto_context.cc | 10 +++++----- src/crypto/crypto_context.h | 2 +- src/crypto/crypto_dh.cc | 14 ++------------ src/crypto/crypto_hash.cc | 2 +- src/crypto/crypto_kem.h | 6 +++--- src/crypto/crypto_keys.cc | 2 +- src/crypto/crypto_rsa.cc | 8 ++------ src/crypto/crypto_tls.cc | 12 ++++++------ src/crypto/crypto_tls.h | 2 +- src/crypto/crypto_util.cc | 14 ++------------ src/node.cc | 10 +++------- src/node_constants.cc | 4 ++-- src/node_constants.h | 2 +- src/node_metadata.cc | 2 +- src/node_options.cc | 6 +++--- src/node_options.h | 2 +- 19 files changed, 41 insertions(+), 72 deletions(-) diff --git a/src/crypto/README.md b/src/crypto/README.md index 7bc4dbe4e148..501018de4a25 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 01b87f3d7d3c..29b7fa0cd929 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1606,7 +1606,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,9 +1625,9 @@ 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_))) { @@ -2282,7 +2282,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { // TODO(@jasnell): Should this use ThrowCryptoError? unsigned long err = ERR_get_error(); // NOLINT(runtime/int) -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { // OpenSSL's "unsupported" error without any context is very // common and not very helpful, so we override it: diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 866340079841..d59f70d53c18 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -106,7 +106,7 @@ 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); diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index a4b497727a1e..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 diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 681ca532df4a..068a44f0ef86 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -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 49f3128f1fa0..27ea548f1cd1 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 5c0ab2e2d814..1aef184c2fa0 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -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; @@ -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_tls.cc b/src/crypto/crypto_tls.cc index 3f22bfc33d7e..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);"); 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 10bf8e18cef4..7e2ae374ec6a 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 @@ -453,7 +453,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 +507,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 +514,6 @@ void InitCryptoOnce() { fprintf(stderr, "Unable to load legacy provider.\n"); } } -#endif OPENSSL_init_ssl(0, settings); InstallFipsIndicatorCallback(); diff --git a/src/node.cc b/src/node.cc index a43eb28b779d..79e49733ba59 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 @@ -1174,7 +1174,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( @@ -1190,6 +1189,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. @@ -1246,11 +1246,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_constants.cc b/src/node_constants.cc index bd3b66414d18..cce1903f1c82 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -57,7 +57,7 @@ #if !defined(RSA_PKCS1_PSS_PADDING) #define RSA_PKCS1_PSS_PADDING 6 #endif -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // OpenSSL hides these deprecated DH check constants under // OPENSSL_NO_DEPRECATED, but the numeric verifyError values remain public API. #if !defined(DH_CHECK_P_NOT_PRIME) @@ -74,7 +74,7 @@ #endif #endif #ifndef OPENSSL_NO_ENGINE -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // Engine constants remain public API while engine implementation lives in the // dedicated compatibility target. #define ENGINE_METHOD_RSA (unsigned int)0x0001 diff --git a/src/node_constants.h b/src/node_constants.h index 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_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 9077325e393d..2291c0b5d7bf 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1613,9 +1613,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", @@ -1623,7 +1623,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 ffd76d70526c..6dec13aa1288 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -424,7 +424,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 From a16c37cf5e9523bafe3c017269d0e60d7bdabe23 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 26 Jul 2026 14:18:38 +0200 Subject: [PATCH 04/10] test,benchmark: drop OpenSSL 1.x-only coverage Delete test-crypto-ecb.js, which can no longer run anywhere: Blowfish is available only from OpenSSL's legacy provider and is absent from BoringSSL. The addon and cctest version guards become OPENSSL_IS_BORINGSSL checks. Remove legacy digest-alias coverage and unreachable OpenSSL 1.x branches. JavaScript test and benchmark gates, skip reasons, and TLS error expectations that distinguished OpenSSL 1.x from provider-backed OpenSSL now distinguish BoringSSL. Keep the CCM alternate finalization error only for BoringSSL. Provider-only test skips use version-neutral terminology or state the actual minimum OpenSSL version. Signed-off-by: Filip Skokan Assisted-by: Codex --- benchmark/crypto/kem.js | 4 +- benchmark/crypto/mac.js | 7 +-- test/addons/openssl-providers/binding.cc | 9 +-- test/addons/openssl-providers/providers.cjs | 6 +- test/cctest/test_node_crypto_env.cc | 2 +- test/common/crypto.js | 3 - .../webcrypto/supports-modern-algorithms.mjs | 4 +- test/parallel/test-cli-node-options.js | 4 +- test/parallel/test-config-json-schema.js | 6 +- .../parallel/test-crypto-async-sign-verify.js | 14 ++--- test/parallel/test-crypto-authenticated.js | 2 +- .../test-crypto-cipheriv-decipheriv.js | 6 +- test/parallel/test-crypto-classes.js | 4 +- test/parallel/test-crypto-dh-constructor.js | 4 +- test/parallel/test-crypto-dh-curves.js | 12 +--- test/parallel/test-crypto-dh-errors.js | 4 +- test/parallel/test-crypto-dh-generate-keys.js | 4 +- test/parallel/test-crypto-dh-leak.js | 4 +- test/parallel/test-crypto-dh-odd-key.js | 4 +- test/parallel/test-crypto-dh-stateless.js | 31 +++------ test/parallel/test-crypto-dh.js | 5 +- test/parallel/test-crypto-ecb.js | 63 ------------------- test/parallel/test-crypto-encap-decap.js | 7 +-- .../test-crypto-fips-indicator-strict.js | 2 +- test/parallel/test-crypto-getcipherinfo.js | 4 +- test/parallel/test-crypto-hkdf.js | 7 +-- test/parallel/test-crypto-hmac.js | 13 ---- test/parallel/test-crypto-job-error-parity.js | 4 +- test/parallel/test-crypto-key-objects.js | 34 ++++------ test/parallel/test-crypto-key-store-pkcs11.js | 6 +- test/parallel/test-crypto-key-store.js | 6 +- ...test-crypto-keygen-async-dsa-key-object.js | 8 +-- test/parallel/test-crypto-keygen-async-dsa.js | 8 +-- ...-explicit-elliptic-curve-encrypted-p256.js | 8 +-- ...nc-explicit-elliptic-curve-encrypted.js.js | 7 +-- ...ync-named-elliptic-curve-encrypted-p256.js | 10 +-- ...en-async-named-elliptic-curve-encrypted.js | 10 +-- test/parallel/test-crypto-keygen-async-rsa.js | 12 ++-- .../parallel/test-crypto-keygen-bit-length.js | 28 ++++----- ...rypto-keygen-empty-passphrase-no-prompt.js | 12 ++-- .../test-crypto-keygen-missing-oid.js | 46 +++++++------- test/parallel/test-crypto-keygen.js | 13 +--- .../test-crypto-mac-cache-snapshot.js | 6 +- test/parallel/test-crypto-mac-cache.js | 6 +- test/parallel/test-crypto-mac-errors.js | 6 +- test/parallel/test-crypto-mac-unsupported.js | 4 +- test/parallel/test-crypto-mac-vectors.js | 6 +- test/parallel/test-crypto-mac.js | 6 +- test/parallel/test-crypto-negative-zero.js | 6 +- test/parallel/test-crypto-no-algorithm.js | 6 +- test/parallel/test-crypto-padding.js | 12 ++-- test/parallel/test-crypto-pbkdf2.js | 4 +- .../test-crypto-pqc-key-objects-ml-dsa.js | 4 +- .../test-crypto-pqc-key-objects-ml-kem.js | 4 +- .../test-crypto-pqc-key-objects-slh-dsa.js | 6 +- test/parallel/test-crypto-prime.js | 5 +- .../test-crypto-private-decrypt-gh32240.js | 8 +-- ...t-crypto-provider-cipher-cache-snapshot.js | 6 +- .../test-crypto-provider-cipher-cache.js | 6 +- .../test-crypto-provider-hash-options.js | 2 +- test/parallel/test-crypto-provider-hashes.js | 6 +- ...t-crypto-publicDecrypt-fails-first-time.js | 6 +- test/parallel/test-crypto-rsa-dsa.js | 58 +++++------------ test/parallel/test-crypto-sec-level.js | 2 +- test/parallel/test-crypto-secure-heap.js | 5 +- test/parallel/test-crypto-sign-verify.js | 21 ++----- test/parallel/test-crypto-stream.js | 8 +-- test/parallel/test-crypto-x509.js | 19 ++---- test/parallel/test-crypto.js | 45 +++---------- ...agnostics-channel-crypto-fips-indicator.js | 2 +- .../test-https-agent-session-eviction.js | 2 +- ...ttps-selfsigned-no-keycertsign-no-crash.js | 15 +---- .../parallel/test-permission-openssl-store.js | 6 +- ...rocess-env-allowed-flags-are-documented.js | 8 +-- test/parallel/test-process-versions.js | 12 ++-- test/parallel/test-tls-alert-handling.js | 9 --- test/parallel/test-tls-cert-ext-encoding.js | 14 ++--- test/parallel/test-tls-client-mindhsize.js | 2 +- .../test-tls-client-renegotiation-13.js | 6 +- test/parallel/test-tls-dhe.js | 4 +- test/parallel/test-tls-junk-closes-server.js | 4 +- test/parallel/test-tls-key-mismatch.js | 6 +- test/parallel/test-tls-legacy-pfx.js | 6 +- test/parallel/test-tls-min-max-version.js | 13 ++-- test/parallel/test-tls-set-ciphers.js | 9 +-- test/parallel/test-trace-env.js | 4 +- ...-webcrypto-aead-decrypt-detached-buffer.js | 4 +- .../test-webcrypto-deduplicate-usages.js | 16 ++--- .../test-webcrypto-derivebits-hkdf.js | 6 +- test/parallel/test-webcrypto-derivekey.js | 8 +-- test/parallel/test-webcrypto-digest.js | 4 +- .../test-webcrypto-encrypt-decrypt-aes.js | 4 +- .../test-webcrypto-encrypt-decrypt.js | 6 +- test/parallel/test-webcrypto-export-import.js | 4 +- test/parallel/test-webcrypto-keygen-kmac.js | 6 +- test/parallel/test-webcrypto-keygen.js | 2 +- .../test-webcrypto-prototype-pollution.mjs | 4 +- .../test-webcrypto-sign-verify-kmac.js | 6 +- test/parallel/test-webcrypto-sign-verify.js | 2 +- test/parallel/test-webcrypto-wrap-unwrap.js | 4 +- test/parallel/test-x509-escaping.js | 22 +++---- test/pummel/test-crypto-dh-hash.js | 6 +- test/pummel/test-dh-regr.js | 4 +- test/wpt/status/WebCryptoAPI.cjs | 2 +- 104 files changed, 342 insertions(+), 610 deletions(-) delete mode 100644 test/parallel/test-crypto-ecb.js diff --git a/benchmark/crypto/kem.js b/benchmark/crypto/kem.js index a59a57b65956..56f875b0c850 100644 --- a/benchmark/crypto/kem.js +++ b/benchmark/crypto/kem.js @@ -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 ea9d3a56e59f..a6ff89f22ea8 100644 --- a/benchmark/crypto/mac.js +++ b/benchmark/crypto/mac.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL, isBoringSSL } = 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) || - isBoringSSL || +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/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 7e7a958b9005..08cab0d46876 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 { hasOpenSSL } = require('../../common/crypto'); +const { isBoringSSL } = require('../../common/crypto'); -if (!hasOpenSSL(3)) { - 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/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index 1d31dc983296..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); diff --git a/test/common/crypto.js b/test/common/crypto.js index 49678e0de43a..80a22c89aa10 100644 --- a/test/common/crypto.js +++ b/test/common/crypto.js @@ -147,9 +147,6 @@ module.exports = { hasOpenSSL, hasFIPS, isBoringSSL, - get hasOpenSSL3() { - return hasOpenSSL(3); - }, // opensslCli defined lazily to reduce overhead of spawnSync get opensslCli() { if (opensslCli !== null) return opensslCli; diff --git a/test/fixtures/webcrypto/supports-modern-algorithms.mjs b/test/fixtures/webcrypto/supports-modern-algorithms.mjs index 67fad15f7f39..839219976752 100644 --- a/test/fixtures/webcrypto/supports-modern-algorithms.mjs +++ b/test/fixtures/webcrypto/supports-modern-algorithms.mjs @@ -8,8 +8,8 @@ const argon2 = hasOpenSSL(3, 2); const shake128 = crypto.getHashes().includes('shake128'); const shake256 = crypto.getHashes().includes('shake256'); const sha3 = crypto.getHashes().includes('sha3-256'); -const ocb = hasOpenSSL(3); -const kmac = hasOpenSSL(3); +const ocb = !isBoringSSL; +const kmac = !isBoringSSL; const hybridKems = pqc && (!boringSSL || (sha3 && shake256)); const { subtle } = globalThis.crypto; diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index 375c46c11ab7..fa290d23c961 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 { hasOpenSSL } = 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 (!hasOpenSSL(3)) + 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 08973bd17ee2..ad8818c3cd96 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 { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) { - 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 a60dc73d67b3..f4c754d118fc 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, isBoringSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const util = require('util'); const crypto = require('crypto'); @@ -132,7 +132,7 @@ if (!isBoringSSL) { 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) || isBoringSSL) { - 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 f11778ee7708..dc6f454847d2 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -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/); diff --git a/test/parallel/test-crypto-cipheriv-decipheriv.js b/test/parallel/test-crypto-cipheriv-decipheriv.js index d2c216924ea8..ab429ecb1d31 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..e875f706110e 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-dh-constructor.js b/test/parallel/test-crypto-dh-constructor.js index 28747ac3a726..643025681566 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 22b05fb89609..e9e93cb63b7e 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, isBoringSSL } = 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 @@ -68,7 +67,7 @@ const bad_dh = isBoringSSL ? 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 (!isBoringSSL) { - assert.strictEqual( - crypto.createDiffieHellman(Buffer.from(p, 'hex'), - Buffer.from(p, 'hex')).verifyError, - DH_NOT_SUITABLE_GENERATOR); } const availableCurves = new Set(crypto.getCurves()); @@ -269,7 +263,7 @@ if (availableCurves.has('prime256v1') && availableHashes.has('sha256')) { crypto.createSign('SHA256').sign(ecPrivateKey); } -if (hasFIPS(3) && availableCurves.has('secp256k1')) { +if (hasFIPS() && availableCurves.has('secp256k1')) { const originalFips = crypto.getFips(); try { diff --git a/test/parallel/test-crypto-dh-errors.js b/test/parallel/test-crypto-dh-errors.js index d9f7065655cb..d697a72a09f6 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 { hasOpenSSL } = 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 (hasOpenSSL(3)) { + 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..db7fa48049a7 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-leak.js b/test/parallel/test-crypto-dh-leak.js index 8d5141eef4b1..80e7c907ee3d 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-odd-key.js b/test/parallel/test-crypto-dh-odd-key.js index c96227770e3d..32d83fe0d4f0 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 9c0270304f2a..d1e134aa4a15 100644 --- a/test/parallel/test-crypto-dh-stateless.js +++ b/test/parallel/test-crypto-dh-stateless.js @@ -20,7 +20,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'; @@ -341,15 +341,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, @@ -357,9 +348,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' }); } } @@ -420,9 +409,9 @@ 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' }); } @@ -576,9 +565,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({ @@ -607,8 +596,6 @@ for (const { privateKey: alicePriv, publicKey: bobPub } of [ 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/ }); + { code: 'ERR_OSSL_FAILED_DURING_DERIVATION' }); } } diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index 7b9a9d50d890..5ef9450b86af 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -7,14 +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'); @@ -60,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/, diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js deleted file mode 100644 index 65c373d35d25..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 { hasOpenSSL } = require('../common/crypto'); -const crypto = require('crypto'); - -if (crypto.getFips()) { - common.skip('BF-ECB is not FIPS 140-2 compatible'); -} - -if (hasOpenSSL(3)) { - 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-encap-decap.js b/test/parallel/test-crypto-encap-decap.js index 199ad68fa365..50a44f910510 100644 --- a/test/parallel/test-crypto-encap-decap.js +++ b/test/parallel/test-crypto-encap-decap.js @@ -16,11 +16,6 @@ const { promisify } = require('util'); const isBoringSSL = commonIsBoringSSL; 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', @@ -28,7 +23,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, diff --git a/test/parallel/test-crypto-fips-indicator-strict.js b/test/parallel/test-crypto-fips-indicator-strict.js index 5e003d7015b2..b1024fc5235a 100644 --- a/test/parallel/test-crypto-fips-indicator-strict.js +++ b/test/parallel/test-crypto-fips-indicator-strict.js @@ -31,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-getcipherinfo.js b/test/parallel/test-crypto-getcipherinfo.js index faf45c766c5c..8e707690355c 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, hasOpenSSL, isBoringSSL } = 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 (hasOpenSSL(3)) { +if (!isBoringSSL) { assert.deepStrictEqual( ciphers.filter((cipher) => cipher.includes('cbc-hmac')), []); for (const cipher of [ diff --git a/test/parallel/test-crypto-hkdf.js b/test/parallel/test-crypto-hkdf.js index 80a0a5dea4af..c71a3561f009 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, isBoringSSL } = 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) && !isBoringSSL) - 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..06cb3c93b14b 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.js b/test/parallel/test-crypto-key-objects.js index fbd2ae6ff1c4..421169b17ac6 100644 --- a/test/parallel/test-crypto-key-objects.js +++ b/test/parallel/test-crypto-key-objects.js @@ -25,7 +25,6 @@ const { } = require('crypto'); const { - hasOpenSSL, hasFIPS, isBoringSSL, } = require('../common/crypto'); @@ -350,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', - } : isBoringSSL ? { + }, 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 @@ -382,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' - } : isBoringSSL ? { + }, 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' }); } @@ -791,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 @@ -807,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). diff --git a/test/parallel/test-crypto-key-store-pkcs11.js b/test/parallel/test-crypto-key-store-pkcs11.js index 0fec81a9c647..659d1836ba5e 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..cf486c73f899 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 52c82ea5725c..9527383692ae 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,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { isBoringSSL, hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); if (isBoringSSL) common.skip('not supported by BoringSSL'); @@ -17,20 +17,20 @@ const { // Test async DSA key object generation. { generateKeyPair('dsa', { - modulusLength: hasOpenSSL(3) ? 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: hasOpenSSL(3) ? 2048 : 512, + modulusLength: 2048, divisorLength: 256 }); assert.strictEqual(privateKey.type, 'private'); assert.strictEqual(privateKey.asymmetricKeyType, 'dsa'); assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { - modulusLength: hasOpenSSL(3) ? 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 5d0254491cd2..884b4eca7dbb 100644 --- a/test/parallel/test-crypto-keygen-async-dsa.js +++ b/test/parallel/test-crypto-keygen-async-dsa.js @@ -9,7 +9,6 @@ const { assertApproximateSize, testSignVerify, spkiExp, - hasOpenSSL, } = require('../common/crypto'); if (isBoringSSL) @@ -19,7 +18,6 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); - // Test async DSA key generation. { const privateKeyEncoding = { @@ -28,7 +26,7 @@ const { }; generateKeyPair('dsa', { - modulusLength: hasOpenSSL(3) ? 2048 : 512, + modulusLength: 2048, divisorLength: 256, publicKeyEncoding: { type: 'spki', @@ -45,8 +43,8 @@ const { // 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-explicit-elliptic-curve-encrypted-p256.js b/test/parallel/test-crypto-keygen-async-explicit-elliptic-curve-encrypted-p256.js index cd7e59be97fa..b876596df611 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 @@ -9,7 +9,6 @@ const { testSignVerify, spkiExp, pkcs8EncExp, - hasOpenSSL, } = require('../common/crypto'); if (isBoringSSL) @@ -19,7 +18,6 @@ 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. { @@ -44,13 +42,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, { 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 5c0878fc634f..f79b92eeae2f 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 @@ -10,7 +10,6 @@ const { testSignVerify, spkiExp, sec1EncExp, - hasOpenSSL, } = require('../common/crypto'); if (isBoringSSL) @@ -50,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-named-elliptic-curve-encrypted-p256.js b/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js index ba86fcdb94e3..545190bbc48f 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, - hasOpenSSL, + 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), - 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, { 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..82f8705a2802 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..19f83bc38828 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 90d32cd73bc4..2c37ef18798e 100644 --- a/test/parallel/test-crypto-keygen-bit-length.js +++ b/test/parallel/test-crypto-keygen-bit-length.js @@ -6,7 +6,6 @@ if (!common.hasCrypto) const { isBoringSSL, - hasOpenSSL, hasFIPS, } = require('../common/crypto'); @@ -18,7 +17,6 @@ const assert = require('assert'); const { generateKeyPair, } = require('crypto'); - const fips3 = hasFIPS(3); // This tests check that generateKeyPair returns correct bit length in @@ -49,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-empty-passphrase-no-prompt.js b/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js index ccf98bcd3766..9f2fc9b55c8d 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-missing-oid.js b/test/parallel/test-crypto-keygen-missing-oid.js index afe95dbee40f..6fd811844809 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.js b/test/parallel/test-crypto-keygen.js index a68c7c07c936..37cb26294193 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -14,11 +14,7 @@ const { } = require('crypto'); const { inspect } = require('util'); -const { - hasOpenSSL, - isBoringSSL: commonIsBoringSSL, -} = require('../common/crypto'); -const isBoringSSL = commonIsBoringSSL; +const { isBoringSSL } = require('../common/crypto'); // Test invalid parameter encoding. { @@ -379,12 +375,7 @@ const isBoringSSL = commonIsBoringSSL; } // Test invalid exponents. (caught by OpenSSL) - let invalidExponentError = /bad e value/; - if (isBoringSSL) { - invalidExponentError = /BAD_E_VALUE/; - } else if (hasOpenSSL(3)) { - invalidExponentError = /exponent/; - } + const invalidExponentError = isBoringSSL ? /BAD_E_VALUE/ : /exponent/; for (const publicExponent of [1, 1 + 0x10001]) { generateKeyPair('rsa', { modulusLength: 4096, diff --git a/test/parallel/test-crypto-mac-cache-snapshot.js b/test/parallel/test-crypto-mac-cache-snapshot.js index 024a4afe8c36..080325c5b086 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) - 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 a836ef92657e..d1d060147f42 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) - 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 8bc8cebfcf51..7326ee88e953 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, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) { - 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 1721e9d1c1a7..84fa42996672 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (hasOpenSSL(3) && !isBoringSSL) { +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 19544ccf4ec1..7e965f78618f 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, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) { - 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 c275b87a0e6c..37d389451079 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, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) { - 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 0e9525fcaf6c..8bf5d305a2fc 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, isBoringSSL } = 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', { diff --git a/test/parallel/test-crypto-no-algorithm.js b/test/parallel/test-crypto-no-algorithm.js index 06aab7614ff5..e0a37230b84a 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 { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - 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-padding.js b/test/parallel/test-crypto-padding.js index dce34409400a..7ad837c64b29 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 { hasOpenSSL } = 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); -}, hasOpenSSL(3) ? { - 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..b583ae80ef83 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-key-objects-ml-dsa.js b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js index cd8f8c926f5b..1fb0fa19f08f 100644 --- a/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js +++ b/test/parallel/test-crypto-pqc-key-objects-ml-dsa.js @@ -102,12 +102,12 @@ for (const [asymmetricKeyType, pubLen] of [ 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 { 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 d08a479f421c..7ae706af400c 100644 --- a/test/parallel/test-crypto-pqc-key-objects-ml-kem.js +++ b/test/parallel/test-crypto-pqc-key-objects-ml-kem.js @@ -102,12 +102,12 @@ for (const [asymmetricKeyType, pubLen] of [ 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 (isBoringSSL && asymmetricKeyType === 'ml-kem-512') { 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..090aa65f9dc5 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-prime.js b/test/parallel/test-crypto-prime.js index 6f43e3a0bfbf..0831aee23e45 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..1e6c2d7626f4 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 3ca57279c00f..b2862f587cb5 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 { hasOpenSSL } = 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 (!hasOpenSSL(3)) - 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 3654ae982435..4f1eb6524da1 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 { hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - 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 ecccc02f01e4..997b179413af 100644 --- a/test/parallel/test-crypto-provider-hash-options.js +++ b/test/parallel/test-crypto-provider-hash-options.js @@ -11,7 +11,7 @@ if (!common.hasCrypto) { if (Number(process.versions.openssl.split('.')[0]) < 4 || isBoringSSL) { - common.skip('OpenSSL 4 provider support is required'); + 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 1cf453f9b22b..0f89ce3dce7f 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) { - 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..297a6c24a3d8 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 7c56dcd28dc8..61e40113a13b 100644 --- a/test/parallel/test-crypto-rsa-dsa.js +++ b/test/parallel/test-crypto-rsa-dsa.js @@ -16,9 +16,7 @@ const { } = 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 @@ -63,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' } : - isBoringSSL ? { - 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', } : 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); @@ -191,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({ @@ -564,21 +551,6 @@ if (!isBoringSSL) { 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'); } diff --git a/test/parallel/test-crypto-sec-level.js b/test/parallel/test-crypto-sec-level.js index ff32b29bb2b7..d4459bc5b75c 100644 --- a/test/parallel/test-crypto-sec-level.js +++ b/test/parallel/test-crypto-sec-level.js @@ -13,7 +13,7 @@ const assert = require('assert'); // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour // This test simply validates that we can get some value for the secLevel // when needed by tests. const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); diff --git a/test/parallel/test-crypto-secure-heap.js b/test/parallel/test-crypto-secure-heap.js index edf4a6d4667f..46f708c04a34 100644 --- a/test/parallel/test-crypto-secure-heap.js +++ b/test/parallel/test-crypto-secure-heap.js @@ -15,7 +15,6 @@ if (common.isASan) { const { isBoringSSL, - hasOpenSSL, hasFIPS, } = require('../common/crypto'); @@ -29,7 +28,6 @@ const fixtures = require('../common/fixtures'); const { secureHeapUsed, createDiffieHellman, - getFips, } = require('crypto'); if (process.argv[2] === 'child') { @@ -43,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 4b874a7e43fb..cb02c4ffd337 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -79,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' : - isBoringSSL ? - '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; } @@ -374,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/, - } : isBoringSSL ? { + }, 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', - ], }); } @@ -682,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 diff --git a/test/parallel/test-crypto-stream.js b/test/parallel/test-crypto-stream.js index 9584e48f2cbd..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 { hasOpenSSL, isBoringSSL } = 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((hasOpenSSL(3) || isBoringSSL) ? { + .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 c1416fd0703a..167f5de43728 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { readFileSync } = require('fs'); const cert = readFileSync(fixtures.path('keys', 'agent1-cert.pem')); @@ -29,7 +29,7 @@ const ca = readFileSync(fixtures.path('keys', 'ca1-cert.pem')); const privateKey = createPrivateKey(key); if (!isBoringSSL) { - const expectedPubkeys = hasOpenSSL(3) ? [ + const expectedPubkeys = [ [ 'rsa_pss_cert_2048.pem', 292, @@ -40,17 +40,6 @@ if (!isBoringSSL) { 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 (!hasOpenSSL(3)) +if (isBoringSSL) infoAccessCheck += '\n'; const der = Buffer.from( @@ -402,7 +391,7 @@ UcXd/5qu2GhokrKU2cPttU+XAN2Om6a0 if (!isBoringSSL) { const cert = new X509Certificate(certPem); assert.throws(() => cert.publicKey, { - message: hasOpenSSL(3) ? /decode error/ : /wrong tag/, + message: /decode error/, name: 'Error' }); diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 3e431c788c62..257c405324cb 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, isBoringSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const isFips = hasFIPS(3); // Test Certificates @@ -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 (isBoringSSL) { - // 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-https-agent-session-eviction.js b/test/parallel/test-https-agent-session-eviction.js index c4edc5b33db3..cd82fb0cbb74 100644 --- a/test/parallel/test-https-agent-session-eviction.js +++ b/test/parallel/test-https-agent-session-eviction.js @@ -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-selfsigned-no-keycertsign-no-crash.js b/test/parallel/test-https-selfsigned-no-keycertsign-no-crash.js index ec1b8dda8ca1..c9096c570fc5 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 f97657051ca9..08913fb047fa 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 { hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - 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 f5aeec017964..910fec097b69 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 { hasOpenSSL } = 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 (!hasOpenSSL(3)) { +if (isBoringSSL) { documented.delete('--openssl-legacy-provider'); documented.delete('--openssl-shared-config'); } @@ -63,8 +63,8 @@ const conditionalOpts = [ filter: (opt) => { return [ '--openssl-config', - hasOpenSSL(3) ? '--openssl-legacy-provider' : '', - hasOpenSSL(3) ? '--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 420625b01f59..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 { hasOpenSSL } = require('../common/crypto'); assert.match(process.versions.ncrypto, commonTemplate); if (process.config.variables.node_shared_openssl) { assert.ok(process.versions.openssl); } else { - const versionRegex = hasOpenSSL(3) ? - // 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 1b80571e70e6..ee1a77c2aa20 100644 --- a/test/parallel/test-tls-alert-handling.js +++ b/test/parallel/test-tls-alert-handling.js @@ -5,11 +5,6 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const { - hasOpenSSL, - isBoringSSL, -} = require('../common/crypto'); - const assert = require('assert'); const net = require('net'); const tls = require('tls'); @@ -39,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 (!hasOpenSSL(3) && !isBoringSSL) - 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; @@ -100,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 (!hasOpenSSL(3) && !isBoringSSL) - 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-cert-ext-encoding.js b/test/parallel/test-tls-cert-ext-encoding.js index 973e9fad32ee..5cbc6cdef5b2 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 { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (hasOpenSSL(3)) - // 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-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index f08be448dd19..c15ab7e28ee9 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-tls-client-renegotiation-13.js b/test/parallel/test-tls-client-renegotiation-13.js index 33e74af13eda..b69ddd126e58 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const fixtures = require('../common/fixtures'); @@ -40,9 +40,7 @@ connect({ }); } else { assert.throws(() => { throw err; }, { - message: hasOpenSSL(3) ? - '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-dhe.js b/test/parallel/test-tls-dhe.js index 6f54bbd97667..cad14df5529b 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -43,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) { @@ -67,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-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 8f60ef0520c4..fa26419fe5bb 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const tls = require('tls'); const errorMessageRegex = isBoringSSL ? /^Error: error:0b000074:X\.509 certificate routines:OPENSSL_internal:KEY_VALUES_MISMATCH$/ : - hasOpenSSL(3) ? - /^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-legacy-pfx.js b/test/parallel/test-tls-legacy-pfx.js index 77f9c0935025..2f3339196f4e 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 { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) { - 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-min-max-version.js b/test/parallel/test-tls-min-max-version.js index 932ad7f0f219..27017bb9baf0 100644 --- a/test/parallel/test-tls-min-max-version.js +++ b/test/parallel/test-tls-min-max-version.js @@ -48,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'; } @@ -176,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-set-ciphers.js b/test/parallel/test-tls-set-ciphers.js index 57fb35991121..f54e79dcb134 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-trace-env.js b/test/parallel/test-trace-env.js index 4d1a8165277e..6c3d144f8abc 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 { hasOpenSSL } = require('../common/crypto'); - if (hasOpenSSL(3)) { + 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..135e6aa7391b 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-deduplicate-usages.js b/test/parallel/test-webcrypto-deduplicate-usages.js index 1d7247644abd..514f7fdfe8c4 100644 --- a/test/parallel/test-webcrypto-deduplicate-usages.js +++ b/test/parallel/test-webcrypto-deduplicate-usages.js @@ -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) { @@ -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) { @@ -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) { diff --git a/test/parallel/test-webcrypto-derivebits-hkdf.js b/test/parallel/test-webcrypto-derivebits-hkdf.js index fafd6a7afa58..8bbd001d4a0d 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, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { subtle } = globalThis.crypto; function getDeriveKeyInfo(name, length, hash, ...usages) { @@ -38,13 +38,13 @@ if (!isBoringSSL) { 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 = { diff --git a/test/parallel/test-webcrypto-derivekey.js b/test/parallel/test-webcrypto-derivekey.js index 516838aaf0bf..7bd710746490 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, isBoringSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const assert = require('assert'); const { subtle } = globalThis.crypto; @@ -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], @@ -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']; diff --git a/test/parallel/test-webcrypto-digest.js b/test/parallel/test-webcrypto-digest.js index 47a56a912d69..67dff7639a8c 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, isBoringSSL } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const fips = hasFIPS(); const kTests = [ @@ -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-encrypt-decrypt-aes.js b/test/parallel/test-webcrypto-encrypt-decrypt-aes.js index 00c294839bfe..73ac3ec3caa3 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 9a10b214d7aa..f90092b8991e 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, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); const { getFips } = require('crypto'); const { subtle } = globalThis.crypto; @@ -185,7 +185,7 @@ if (!isBoringSSL) { } // 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.js b/test/parallel/test-webcrypto-export-import.js index 385ae8c65e9d..ab103266d38c 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, isBoringSSL } = 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( diff --git a/test/parallel/test-webcrypto-keygen-kmac.js b/test/parallel/test-webcrypto-keygen-kmac.js index 33716095751f..da190df06ece 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 e63ea8dfc7da..c556564e8cc7 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -177,7 +177,7 @@ if (!isBoringSSL) { common.printSkipMessage('Skipping unsupported test cases'); } -if (hasOpenSSL(3)) { +if (!isBoringSSL) { vectors['AES-OCB'] = { algorithm: { length: 256 }, result: 'CryptoKey', diff --git a/test/parallel/test-webcrypto-prototype-pollution.mjs b/test/parallel/test-webcrypto-prototype-pollution.mjs index 9f0b41ac10bb..b9427fde1874 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-kmac.js b/test/parallel/test-webcrypto-sign-verify-kmac.js index ac0b738bcd57..18b106855455 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.js b/test/parallel/test-webcrypto-sign-verify.js index 295f13782389..70148ee28aef 100644 --- a/test/parallel/test-webcrypto-sign-verify.js +++ b/test/parallel/test-webcrypto-sign-verify.js @@ -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(); diff --git a/test/parallel/test-webcrypto-wrap-unwrap.js b/test/parallel/test-webcrypto-wrap-unwrap.js index 60ceffd710c9..6e209e83662d 100644 --- a/test/parallel/test-webcrypto-wrap-unwrap.js +++ b/test/parallel/test-webcrypto-wrap-unwrap.js @@ -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: { @@ -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 47901140cac0..e33d13726633 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 { hasOpenSSL, isBoringSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); // Test that all certificate chains provided by the reporter are rejected. { @@ -59,8 +59,8 @@ const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); 'IP Address:8.8.8.8', 'IP Address:8.8.4.4', // For backward-compatibility, include invalid IP address lengths. - hasOpenSSL(3) ? 'IP Address:' : 'IP Address:', - hasOpenSSL(3) ? '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 { hasOpenSSL, isBoringSSL } = 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', - hasOpenSSL(3) ? + !isBoringSSL ? 'othername:XmppAddr:abc123' : 'othername:', - hasOpenSSL(3) ? + !isBoringSSL ? 'othername:"XmppAddr:abc123\\u002c DNS:good.example.com"' : 'othername:', - hasOpenSSL(3) ? + !isBoringSSL ? 'othername:"XmppAddr:good.example.com\\u0000abc123"' : 'othername:', // This is unsupported because the OID is not recognized. 'othername:', - hasOpenSSL(3) ? '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:', - hasOpenSSL(3) ? + !isBoringSSL ? 'othername:"SRVName:abc\\u0000def"' : 'othername:', ]; @@ -173,7 +173,7 @@ const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); ], }, }, - hasOpenSSL(3) ? { + !isBoringSSL ? { text: 'OCSP - othername:XmppAddr:good.example.com\n' + 'OCSP - othername:\n' + 'OCSP - othername:SRVName:abc123', @@ -196,7 +196,7 @@ const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); ], }, }, - hasOpenSSL(3) ? { + !isBoringSSL ? { text: 'OCSP - othername:"XmppAddr:good.example.com\\u0000abc123"', legacy: { 'OCSP - othername': [ @@ -222,7 +222,7 @@ const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); // Test the subjectAltName property of the X509Certificate API. const cert = new X509Certificate(pem); assert.strictEqual(cert.infoAccess, - `${expected.text}${hasOpenSSL(3) ? '' : '\n'}`); + `${expected.text}${isBoringSSL ? '\n' : ''}`); // Test that the certificate obtained by checkServerIdentity has the correct // subjectaltname property. diff --git a/test/pummel/test-crypto-dh-hash.js b/test/pummel/test-crypto-dh-hash.js index e428df491a34..f61fd5bf3ea5 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 { hasOpenSSL } = require('../common/crypto'); +const { isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) { - 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-dh-regr.js b/test/pummel/test-dh-regr.js index c442fbc3a809..0f387220fd4d 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/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 7715d5456152..a3f5dff6fa9f 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -30,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', From 89c7c400ea3e39b4007279e3601f89f4b64af1b0 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 26 Jul 2026 14:18:38 +0200 Subject: [PATCH 05/10] doc: remove OpenSSL 1.x references Rename the openssl30 footnote, which marks APIs unavailable on BoringSSL rather than ones requiring OpenSSL. Remove obsolete version qualifiers from the provider and FIPS documentation, drop the "As of OpenSSL 1.1.0" anchor from the PSK size limits, and point the man1.1.1 links at man3.0. Signed-off-by: Filip Skokan Assisted-by: Codex --- doc/api/cli.md | 10 ++--- doc/api/crypto.md | 89 +++++++++++++++++-------------------- doc/api/tls.md | 18 ++++---- doc/api/webcrypto.md | 8 ++-- doc/node-config-schema.json | 2 +- doc/node.1 | 10 ++--- 6 files changed, 62 insertions(+), 75 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 2fbbac6cd510..464bbef60063 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1010,9 +1010,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` @@ -2453,8 +2452,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. @@ -2466,7 +2464,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..c60affb2bf72 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) @@ -5192,11 +5192,10 @@ added: v10.0.0 * Returns: {number} `1` if FIPS mode is enabled, `0` otherwise. A future semver-major release may change the return type of this API to a {boolean}. -With OpenSSL 3, this reports whether the default property query includes -`fips=yes`. It does not establish that a FIPS provider is loaded or validated. -It can return `1` even when a requested cryptographic implementation cannot be -fetched because no loaded provider supplies a match for `fips=yes`. See [FIPS -mode][]. +This reports whether the default property query includes `fips=yes`. It does not +establish that a FIPS provider is loaded or validated. It can return `1` even +when a requested cryptographic implementation cannot be fetched because no +loaded provider supplies a match for `fips=yes`. See [FIPS mode][]. ### `crypto.getHashes()` @@ -5214,10 +5213,9 @@ changes: This is the authoritative Node.js list of hash algorithms available to [`crypto.createHash()`][] and [`crypto.hash()`][] in the current process. With -OpenSSL 3 or later, the list depends on the loaded providers and the default -property query in effect when the list is first generated. Some listed -algorithms can require API-specific options, such as `outputLength` for XOF -hash functions. +OpenSSL, the list depends on the loaded providers and the default property query +in effect when the list is first generated. Some listed algorithms can require +API-specific options, such as `outputLength` for XOF hash functions. A listed hash algorithm is not necessarily supported by APIs that combine a digest with another cryptographic operation, such as HMAC, key derivation, or @@ -6605,11 +6603,10 @@ added: v10.0.0 * `bool` {boolean} `true` to enable FIPS mode, `false` to disable it. -Changes [FIPS mode][]. With OpenSSL 3, this only adds or removes `fips=yes` in -the default property query. It does not install, load, initialize, or validate -a FIPS provider. For a usable FIPS configuration, install the provider and -configure OpenSSL to load it when Node.js starts, as described in [FIPS -mode][]. +Changes [FIPS mode][]. This only adds or removes `fips=yes` in the default +property query. It does not install, load, initialize, or validate a FIPS +provider. For a usable FIPS configuration, install the provider and configure +OpenSSL to load it when Node.js starts, as described in [FIPS mode][]. If no loaded provider supplies a requested cryptographic implementation matching `fips=yes`, the call can still succeed and `crypto.getFips()` can still @@ -6628,8 +6625,7 @@ flags additionally require a configured provider named `fips` to initialize and pass its self-test; Node.js fails to start otherwise. Throws an error if OpenSSL cannot change the state. FIPS mode cannot be -disabled when Node.js was started with `--force-fips`. With OpenSSL 1.1.1, -enabling FIPS mode requires a FIPS-capable OpenSSL build. +disabled when Node.js was started with `--force-fips`. ### `crypto.sign(algorithm, data, key[, callback])` @@ -7096,7 +7092,7 @@ variant: input. Encryption and decryption must use the same variant. The option is available -only with CBC-CTS provider ciphers on OpenSSL 3.0 or later. +only with CBC-CTS provider ciphers and is not available with BoringSSL. Applications which use this mode must adhere to these restrictions: @@ -7132,8 +7128,8 @@ For `sm4-xts`, the `xtsStandard` option to [`crypto.createCipheriv()`][] or [`crypto.createDecipheriv()`][] selects either the default `'GB'` variant from GB/T 17964-2021 or the `'IEEE'` variant from IEEE Std 1619-2007. Encryption and decryption must use the same variant. The option is available only for -`sm4-xts`; it does not apply to AES-XTS ciphers. OpenSSL's default provider -supports `sm4-xts` in OpenSSL 3.2 or later. +`sm4-xts`; it does not apply to AES-XTS ciphers. `sm4-xts` requires OpenSSL 3.2 +or later and availability from the default provider. ### AES key wrap modes @@ -7155,7 +7151,7 @@ restrictions: ### SIV and GCM-SIV modes -`SIV`[^openssl30] and `GCM-SIV`[^openssl32] are supported [AEAD algorithms][] +`SIV`[^noboringssl] and `GCM-SIV`[^openssl32] are supported [AEAD algorithms][] when supported by OpenSSL. Applications which use these modes must adhere to certain restrictions when using the cipher API: @@ -7192,13 +7188,11 @@ provider and only applies when it is deployed according to its security policy. Vendor-provided Node.js or OpenSSL builds can require a different configuration; follow the vendor's documentation for those builds. -With OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL library. +FIPS support uses the provider model described in the [OpenSSL FIPS module +guide][]. Using FIPS-approved implementations requires: -With OpenSSL 3, FIPS support uses the provider model described in the -[OpenSSL FIPS module guide][]. Using FIPS-approved implementations requires: - -* A correctly installed OpenSSL 3 FIPS provider. -* An OpenSSL 3 [FIPS module configuration file][]. +* A correctly installed OpenSSL FIPS provider. +* An OpenSSL [FIPS module configuration file][]. * The FIPS provider to be loaded into the OpenSSL library context used by Node.js, normally by activating it in an OpenSSL configuration file when Node.js starts. @@ -7207,7 +7201,7 @@ With OpenSSL 3, FIPS support uses the provider model described in the OpenSSL configuration, [`--enable-fips`][], or [`--force-fips`][], or for subsequent fetches by `crypto.setFips(true)`. -An example OpenSSL 3 configuration file looks like this: +An example OpenSSL configuration file looks like this: ```text nodejs_conf = nodejs_init @@ -7272,8 +7266,8 @@ By default, Node.js reads the `nodejs_conf` section instead of OpenSSL's usual or build Node.js with `./configure --openssl-conf-name=` to change the default section name. -On OpenSSL 3, the configuration above enables the `fips=yes` property query at -startup. The following controls are also available: +The configuration above enables the `fips=yes` property query at startup. The +following controls are also available: * [`--enable-fips`][] and [`--force-fips`][] enable the property query and additionally require the configured provider named `fips` to initialize and @@ -7281,22 +7275,19 @@ startup. The following controls are also available: prevents FIPS mode from being disabled from script code. With `--force-fips=strict`, Node.js also rejects non-approved operations reported through the OpenSSL FIPS indicator callback. -* [`crypto.setFips()`][] changes the FIPS/property-query state. On OpenSSL 3, it - does not install, load, initialize, or validate a provider. Implementations - fetched before the call are not changed. -* [`crypto.getFips()`][] reports the FIPS/property-query state. On OpenSSL 3, a - return value of `1` does not prove that a FIPS provider is loaded or validated. +* [`crypto.setFips()`][] changes the FIPS/property-query state. It does not + install, load, initialize, or validate a provider. Implementations fetched + before the call are not changed. +* [`crypto.getFips()`][] reports the FIPS/property-query state. A return value of + `1` does not prove that a FIPS provider is loaded or validated. * With [`--enable-fips-indicator-events`][], the [`'crypto.fips.indicator'`][] diagnostics channel reports non-approved - operations permitted by an OpenSSL 3.4 or later FIPS provider configured for + operations permitted by an OpenSSL FIPS provider configured for backwards compatibility. -With OpenSSL 1.1.1, these controls use the library's FIPS mode support and -require a FIPS-capable OpenSSL build. - -Only algorithms available under the active FIPS settings can be used. With -OpenSSL 3, if no loaded provider supplies a requested cryptographic -implementation matching `fips=yes`, fetching it fails, typically with +Only algorithms available under the active FIPS settings can be used. If no +loaded provider supplies a requested cryptographic implementation matching +`fips=yes`, fetching it fails, typically with `ERR_OSSL_EVP_UNSUPPORTED`. The same error can occur for algorithms that Node.js supports when FIPS mode is disabled but that are unavailable under the active FIPS settings. @@ -7577,7 +7568,7 @@ See the [list of SSL OP Flags][] for details. -[^openssl30]: Requires OpenSSL >= 3.0 +[^noboringssl]: Not available when Node.js is built against BoringSSL [^openssl32]: Requires OpenSSL >= 3.2 @@ -7625,7 +7616,7 @@ See the [list of SSL OP Flags][] for details. [`--force-fips`]: cli.md#--force-fips [`--openssl-config`]: cli.md#--openssl-configfile [`--openssl-shared-config`]: cli.md#--openssl-shared-config -[`BN_is_prime_ex`]: https://www.openssl.org/docs/man1.1.1/man3/BN_is_prime_ex.html +[`BN_is_prime_ex`]: https://www.openssl.org/docs/man3.0/man3/BN_is_prime_ex.html [`Buffer`]: buffer.md [`DH_generate_key()`]: https://www.openssl.org/docs/man3.0/man3/DH_generate_key.html [`DiffieHellmanGroup`]: #class-diffiehellmangroup diff --git a/doc/api/tls.md b/doc/api/tls.md index c8e12eaacf62..b3fcd16dff2e 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()` @@ -2077,7 +2077,7 @@ changes: The list can contain digest algorithms (`SHA256`, `MD5` etc.), public key algorithms (`RSA-PSS`, `ECDSA` etc.), combination of both (e.g 'RSA+SHA384') or TLS v1.3 scheme names (e.g. `rsa_pss_pss_sha512`). - See [OpenSSL man pages](https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set1_sigalgs_list.html) + See [OpenSSL man pages](https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set1_sigalgs_list.html) for more info. * `ciphers` {string} Cipher suite specification, replacing the default. For more information, see [Modifying the default TLS cipher suite][]. Permitted @@ -2584,7 +2584,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 +2601,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 +2636,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 1d94af41363c..ab105dda8c3e 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -122,15 +122,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] @@ -2761,7 +2761,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 5448bfd9b78e..d3f884161458 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -575,9 +575,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 @@ -1231,12 +1230,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 From 6643044ba8bab2a7c52b458f7e2a6cb6e2cb1230 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 27 Jul 2026 01:13:01 +0200 Subject: [PATCH 06/10] test,tools: drop OpenSSL 1.x-era FIPS leftovers The openssl_fips_*.cnf fixtures use OpenSSL 1.x syntax, and their test branches can no longer run. Remove the fixtures and related version gates while keeping the provider-backed FIPS assertions. get_env_type() sniffed for a "-fips" version suffix that can no longer occur, and the crypto-check lint rule listed a helper that no longer exists. Signed-off-by: Filip Skokan Assisted-by: Codex --- test/fixtures/openssl_fips_disabled.cnf | 12 - test/fixtures/openssl_fips_enabled.cnf | 12 - test/parallel/test-crypto-fips.js | 248 ++------------------- test/parallel/test-dsa-fips-invalid-key.js | 2 +- tools/eslint-rules/crypto-check.js | 2 +- tools/test.py | 13 +- 6 files changed, 25 insertions(+), 264 deletions(-) delete mode 100644 test/fixtures/openssl_fips_disabled.cnf delete mode 100644 test/fixtures/openssl_fips_enabled.cnf 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/parallel/test-crypto-fips.js b/test/parallel/test-crypto-fips.js index ad67ec181c7e..2ff8e2325b3d 100644 --- a/test/parallel/test-crypto-fips.js +++ b/test/parallel/test-crypto-fips.js @@ -4,7 +4,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { isBoringSSL, hasOpenSSL } = require('../common/crypto'); +const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); if (isBoringSSL) common.skip('BoringSSL does not support FIPS'); @@ -13,27 +13,15 @@ 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 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 = - hasOpenSSL(3) ? - '--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 = - hasOpenSSL(3) ? - '--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; @@ -147,23 +135,21 @@ if (!sharedOpenSSL()) { 'require("crypto").getFips()', { ...process.env, 'OPENSSL_CONF': ' ' }); - if (hasOpenSSL(3)) { - // 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 @@ -175,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() && !hasOpenSSL(3)) { - // 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 (!hasOpenSSL(3)) { - 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-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/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): From b9e22cfee50a6d2bb3da79c7cc5a289adb71b906 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 27 Jul 2026 01:17:22 +0200 Subject: [PATCH 07/10] build: remove the bundled FIPS provider build --openssl-is-fips with bundled OpenSSL never worked: the openssl-fipsmodule target had no dependency edge, so fipsinstall's input was produced by nothing. Repairing it would not help, since a FIPS provider built out of tree has no validation status. Remove the machinery and restrict --openssl-is-fips to --shared-openssl. Signed-off-by: Filip Skokan Assisted-by: Codex --- BUILDING.md | 18 ++++-- configure.py | 10 +-- deps/openssl/openssl.gyp | 32 +--------- node.gyp | 95 +++++------------------------ src/node_config.cc | 2 - tools/enable_fips_include.py | 42 ------------- typings/internalBinding/config.d.ts | 1 - 7 files changed, 33 insertions(+), 167 deletions(-) delete mode 100644 tools/enable_fips_include.py diff --git a/BUILDING.md b/BUILDING.md index 531373850321..b1accbe8962a 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1042,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. -When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL. +Node.js does not build a FIPS provider. OpenSSL requires that a FIPS provider +be built from a release that carries a FIPS certificate, so a provider built +as part of the Node.js build would have no validation status. -See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to -enable FIPS support in Node.js. +`./configure --openssl-is-fips` only records that the OpenSSL being linked is +FIPS capable, and requires `--shared-openssl`. + +See [FIPS mode](doc/api/crypto.md#fips-mode) for how to configure it. ## Building Node.js with Temporal support diff --git a/configure.py b/configure.py index d5acdb8fa8e1..b47404b006af 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', @@ -2289,7 +2290,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 @@ -2344,12 +2344,12 @@ 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) 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/node.gyp b/node.gyp index 7e1e4f212cad..5d0dbfa3ae30 100644 --- a/node.gyp +++ b/node.gyp @@ -755,87 +755,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/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/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/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; From 20061700c05e048a8ad4e2a8907d998d91682828 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Wed, 5 Aug 2026 20:21:04 +0200 Subject: [PATCH 08/10] crypto: move DEP0093 to End-of-Life Signed-off-by: Filip Skokan Assisted-by: Codex --- doc/api/crypto.md | 12 ------------ doc/api/deprecations.md | 8 +++++--- lib/crypto.js | 7 ------- test/doctool/test-doc-api-json.mjs | 2 +- 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index c60affb2bf72..477271afe232 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -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)` -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)). @@ -4846,7 +4849,6 @@ 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 diff --git a/lib/crypto.js b/lib/crypto.js index b44ae9de4e5d..c6e853bb6982 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -350,13 +350,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/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. From 8c5b772b2f661bbadd7e06932c121d87c2522b04 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Wed, 26 Aug 2026 23:57:30 +0200 Subject: [PATCH 09/10] Revert "crypto,https,tls: runtime-deprecate OpenSSL engine-based APIs (DEP0183)" This reverts commit da516920fc3b091e54af21a86677574270803b81. Signed-off-by: Filip Skokan Assisted-by: Codex --- doc/api/crypto.md | 8 +------ doc/api/deprecations.md | 5 +---- doc/api/https.md | 3 --- doc/api/tls.md | 7 ------ lib/internal/crypto/util.js | 9 -------- lib/internal/tls/secure-context.js | 3 --- .../addons/openssl-client-cert-engine/test.js | 6 ----- test/addons/openssl-key-engine/test.js | 6 ----- test/parallel/test-crypto-dep0183.js | 22 ------------------- .../test-tls-clientcertengine-unsupported.js | 9 -------- test/parallel/test-tls-error-stack.js | 13 +++-------- .../test-tls-keyengine-unsupported.js | 9 -------- 12 files changed, 5 insertions(+), 95 deletions(-) delete mode 100644 test/parallel/test-crypto-dep0183.js diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 477271afe232..9b631dd8851a 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -6546,9 +6546,6 @@ added: v15.6.0 -> 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. +Support for custom engines in OpenSSL is deprecated from OpenSSL 3. `engine` could be either an id or a path to the engine's shared library. diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index dbffacf27144..f26e04b3102e 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -4111,9 +4111,6 @@ that are shorter than the default authentication tag length (i.e., shorter than -Type: Runtime +Type: Documentation-only OpenSSL 3 has deprecated support for custom engines with a recommendation to switch to its new provider model. The `clientCertEngine` option for diff --git a/doc/api/https.md b/doc/api/https.md index eba303b6600a..74b759556c43 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -427,9 +427,6 @@ a `timeout` of 5 seconds. - -* `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). -Support for custom engines in OpenSSL is deprecated from 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: Documentation-only +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` @@ -4849,7 +4854,6 @@ async function example() { [`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 74b759556c43..c4a95ee67491 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -427,6 +427,10 @@ a `timeout` of 5 seconds.