From a5372184195f742294dcd59badf83a991ecd4a79 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 9f4d2e031f5..750a52c50da 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -261,8 +261,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 515f278ee7a..c7dbaa1413e 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -198,7 +198,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, @@ -206,8 +206,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 @@ -215,7 +213,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. @@ -1112,6 +1110,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 4bf8e2e39ee..c93de65fa35 100755 --- a/configure.py +++ b/configure.py @@ -1422,8 +1422,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: @@ -2346,15 +2347,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''') @@ -2378,6 +2379,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 b382784e610..89812874ceb 100644 --- a/node.gypi +++ b/node.gypi @@ -403,7 +403,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 3c29df44c13..ce962a32e2d 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 8229c4125f1f1363eb159c87e1fb9c937c16097c 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. Drop legacy digest-context, raw-key, seed, signature-context, SM2, primality, and RSA2 key-detail fallbacks. Keep name-based key algorithms and capability discovery, with numeric key adapters and low-level key paths only for BoringSSL. Use the same backend split for KDFs, PKCS#1 decoding, key serialization, and provider EC/RSA key details. Gate BoringSSL-only alternatives explicitly instead of leaving them in #else branches. Signed-off-by: Filip Skokan Assisted-by: Codex --- deps/ncrypto/engine.cc | 5 +- deps/ncrypto/ncrypto.cc | 675 +++++++++++----------------- deps/ncrypto/ncrypto.gyp | 14 +- deps/ncrypto/ncrypto.h | 143 +++--- 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_keys.cc | 3 +- src/crypto/crypto_rsa.cc | 6 +- src/crypto/crypto_sig.cc | 2 +- src/crypto/crypto_tls.cc | 2 +- src/crypto/crypto_util.cc | 2 +- src/env.cc | 2 +- test/cctest/test_node_crypto.cc | 20 +- test/cctest/test_node_crypto_env.cc | 2 +- 16 files changed, 371 insertions(+), 547 deletions(-) diff --git a/deps/ncrypto/engine.cc b/deps/ncrypto/engine.cc index a8e64e25049..6b9514b8565 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 44b74e13fd2..48b505208f9 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -8,7 +8,7 @@ #include #include #include -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #endif #if NCRYPTO_USE_BORINGSSL_EVP_DO_ALL_FALLBACK @@ -22,7 +22,7 @@ #include #include #include -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include #include #include @@ -32,16 +32,6 @@ #include #endif #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 { @@ -49,7 +39,7 @@ 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. @@ -61,22 +51,18 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return EVP_CIPHER_CTX_cipher(ctx); #endif } const EVP_MD* GetDigestCtxMd(const EVP_MD_CTX* ctx) { -#if NCRYPTO_USE_OPENSSL3_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; @@ -130,7 +116,7 @@ constexpr std::array kRsaOtherPrimeParamNames = {{ 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; @@ -407,7 +393,7 @@ DataPointer DataPointer::SecureAlloc(size_t len) { // free function (OPENSSL_secure_clear_free vs. OPENSSL_clear_free) and // callers of isSecure() get a truthful answer. return DataPointer(ptr, len, CRYPTO_secure_allocated(ptr) == 1); -#else +#elif defined(OPENSSL_IS_BORINGSSL) // BoringSSL does not implement the OPENSSL_secure_zalloc API. auto ptr = OPENSSL_malloc(len); if (ptr == nullptr) return {}; @@ -511,9 +497,9 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) return FIPS_mode() == 1; #endif } @@ -528,10 +514,10 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) const bool success = FIPS_mode_set(enable ? 1 : 0) == 1; #endif if (success && isFipsEnabledRaw() != was_enabled) { @@ -546,7 +532,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"); @@ -555,7 +541,7 @@ bool testFipsEnabled() { int result = OSSL_PROVIDER_self_test(fips_provider); OSSL_PROVIDER_unload(fips_provider); return result; -#else +#elif defined(OPENSSL_IS_BORINGSSL) #ifdef OPENSSL_FIPS return FIPS_selftest(); #else // OPENSSL_FIPS @@ -728,7 +714,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; @@ -737,8 +723,6 @@ int BignumPointer::isPrime(int nchecks, return -1; } return is_probably_prime; -#else - return BN_is_prime_ex(get(), nchecks, ctx.get(), cb.get()); #endif } @@ -808,11 +792,11 @@ 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; } -#else +#elif defined(OPENSSL_IS_BORINGSSL) while (length > INT_MAX && 1 == RAND_bytes(buf, INT_MAX)) { buf += INT_MAX; length -= INT_MAX; @@ -821,9 +805,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) { @@ -858,7 +842,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}; @@ -1144,9 +1128,9 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) BIO_printf(out.get(), ""); #endif } @@ -1158,14 +1142,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: @@ -1185,7 +1169,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)) { @@ -1276,7 +1260,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 @@ -1653,9 +1637,9 @@ bool X509View::ifRsa(KeyCallback callback) const { if (cert_ == nullptr) return true; OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); if (EVPKeyPointer::isRsaVariant(pkey)) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Rsa rsa(pkey); -#else +#elif NCRYPTO_USE_BORINGSSL Rsa rsa(EVP_PKEY_get0_RSA(pkey)); #endif if (!rsa) [[unlikely]] @@ -1669,9 +1653,9 @@ bool X509View::ifEc(KeyCallback callback) const { if (cert_ == nullptr) return true; OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); if (EVPKeyPointer::isA(pkey, KeyAlgorithm::EC)) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec ec(pkey); -#else +#elif NCRYPTO_USE_BORINGSSL Ec ec(EVP_PKEY_get0_EC_KEY(pkey)); #endif if (!ec) [[unlikely]] @@ -1701,9 +1685,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return X509Pointer(SSL_get_peer_certificate(ssl.get())); #endif } @@ -1829,7 +1813,7 @@ int BIOPointer::Write(BIOPointer* bio, std::string_view message) { // DHPointer namespace { -#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 && @@ -1906,7 +1890,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; @@ -1994,7 +1978,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) {} @@ -2002,12 +1986,12 @@ DHPointer::DHPointer(BignumPointer&& p, BignumPointer&& g, const char* group_name) : p_(std::move(p)), g_(std::move(g)), group_name_(group_name) {} -#else +#elif NCRYPTO_USE_BORINGSSL 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_)), @@ -2016,7 +2000,7 @@ DHPointer::DHPointer(DHPointer&& other) noexcept group_name_(other.group_name_) { other.group_name_ = nullptr; } -#else +#elif NCRYPTO_USE_BORINGSSL : dh_(other.release()) { } #endif @@ -2032,14 +2016,14 @@ DHPointer::~DHPointer() { } void DHPointer::reset( -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_PKEY* dh -#else +#elif NCRYPTO_USE_BORINGSSL DH* dh #endif ) { dh_.reset(dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER p_.reset(); g_.reset(); pub_key_.reset(); @@ -2048,7 +2032,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 = @@ -2065,7 +2049,7 @@ EVP_PKEY* DHPointer::release() { group_name_ = nullptr; return dh_.release(); } -#else +#elif NCRYPTO_USE_BORINGSSL DH* DHPointer::release() { return dh_.release(); } @@ -2107,10 +2091,10 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return New(std::move(group), std::move(generator)); #endif } @@ -2118,11 +2102,11 @@ 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)); -#else +#elif NCRYPTO_USE_BORINGSSL DHPointer dh(DH_new()); if (!dh) return {}; @@ -2141,7 +2125,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::NewFromAlgorithm(KeyAlgorithm::DH); if (!param_ctx.initForParamgen() || !param_ctx.setDhParameters(bits, generator)) { @@ -2151,7 +2135,7 @@ DHPointer DHPointer::New(size_t bits, unsigned int generator) { auto key_params = param_ctx.paramgen(); if (!key_params) return {}; return DHPointer(std::move(key_params)); -#else +#elif NCRYPTO_USE_BORINGSSL DHPointer dh(DH_new()); if (!dh) return {}; @@ -2166,7 +2150,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; @@ -2194,7 +2178,7 @@ DHPointer::CheckResult DHPointer::check() { auto codes = CheckDhParams(p_bn, g_bn, q_bn, j_bn); if (!codes) return DHPointer::CheckResult::CHECK_FAILED; return static_cast(*codes); -#else +#elif NCRYPTO_USE_BORINGSSL int codes = 0; if (DH_check(dh_.get(), &codes) != 1) return DHPointer::CheckResult::CHECK_FAILED; @@ -2208,7 +2192,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(); @@ -2256,7 +2240,7 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey( return DHPointer::CheckPublicKeyResult::INVALID; } return CheckPublicKeyResult::NONE; -#else +#elif NCRYPTO_USE_BORINGSSL int codes = 0; if (DH_check_pub_key(dh_.get(), pub_key.get(), &codes) != 1) { return DHPointer::CheckPublicKeyResult::CHECK_FAILED; @@ -2275,14 +2259,14 @@ 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; DeleteFnPtr g; if (!GetDhParams(dh_.get(), &p, &g)) return {}; return BignumPointer::Encode(p.get()); -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* p; DH_get0_pqg(dh_.get(), &p, nullptr, nullptr); return BignumPointer::Encode(p); @@ -2291,14 +2275,14 @@ 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; DeleteFnPtr g; if (!GetDhParams(dh_.get(), &p, &g)) return 0; return BignumPointer::GetBitCount(p.get()); -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* p; DH_get0_pqg(dh_.get(), &p, nullptr, nullptr); return BignumPointer::GetBitCount(p); @@ -2307,14 +2291,14 @@ 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; DeleteFnPtr g; if (!GetDhParams(dh_.get(), &p, &g)) return {}; return BignumPointer::Encode(g.get()); -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* g; DH_get0_pqg(dh_.get(), nullptr, nullptr, &g); return BignumPointer::Encode(g); @@ -2323,14 +2307,14 @@ 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 {}; DeleteFnPtr pub_key; if (!GetDhKeys(dh_.get(), &pub_key, nullptr)) return {}; return BignumPointer::Encode(pub_key.get()); -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* pub_key; DH_get0_key(dh_.get(), &pub_key, nullptr); return BignumPointer::Encode(pub_key); @@ -2339,14 +2323,14 @@ 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 {}; DeleteFnPtr pvt_key; if (!GetDhKeys(dh_.get(), nullptr, &pvt_key)) return {}; return BignumPointer::Encode(pvt_key.get()); -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* pvt_key; DH_get0_key(dh_.get(), nullptr, &pvt_key); return BignumPointer::Encode(pvt_key); @@ -2355,14 +2339,14 @@ 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; DeleteFnPtr pvt_key; if (!GetDhKeys(dh_.get(), nullptr, &pvt_key)) return false; return pvt_key != nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL const BIGNUM* pvt_key = nullptr; DH_get0_key(dh_.get(), nullptr, &pvt_key); return pvt_key != nullptr; @@ -2373,7 +2357,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 {}; @@ -2430,7 +2414,7 @@ DataPointer DHPointer::generateKeys() { if (EVP_PKEY_keygen(ctx.get(), &generated) != 1) return {}; dh_.reset(generated); return getPublicKey(); -#else +#elif NCRYPTO_USE_BORINGSSL // Key generation failed if (!DH_generate_key(dh_.get())) return {}; @@ -2440,12 +2424,12 @@ 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()); return bits > 0 ? (static_cast(bits) + 7) / 8 : 0; -#else +#elif NCRYPTO_USE_BORINGSSL int ret = DH_size(dh_.get()); // DH_size can return a -1 on error but we just want to return a 0 // in that case so we don't wrap around when returning the size_t. @@ -2457,7 +2441,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()); @@ -2502,7 +2486,7 @@ DataPointer DHPointer::computeSecret(const BignumPointer& peer) const { return {}; } return dp.resize(out_size); -#else +#elif NCRYPTO_USE_BORINGSSL auto dp = DataPointer::Alloc(size()); if (!dp) return {}; @@ -2525,7 +2509,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; @@ -2547,7 +2531,7 @@ bool DHPointer::setPublicKey(BignumPointer&& key) { if (!pkey) return false; dh_.reset(pkey.release()); return true; -#else +#elif NCRYPTO_USE_BORINGSSL if (DH_set0_key(dh_.get(), key.get(), nullptr) == 1) { // If DH_set0_key returns successfully, then dh_ takes ownership of the // BIGNUM, so we must release it here. Unfortunately coverity does not @@ -2562,7 +2546,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; @@ -2584,7 +2568,7 @@ bool DHPointer::setPrivateKey(BignumPointer&& key) { if (!pkey) return false; dh_.reset(pkey.release()); return true; -#else +#elif NCRYPTO_USE_BORINGSSL if (DH_set0_key(dh_.get(), nullptr, key.get()) == 1) { // If DH_set0_key returns successfully, then dh_ takes ownership of the // BIGNUM, so we must release it here. Unfortunately coverity does not @@ -2606,7 +2590,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) { @@ -2634,7 +2618,7 @@ DataPointer DHPointer::stateless(const EVPKeyPointer& ourKey, // ============================================================================ // KDF -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER KDF::KDF(EVP_KDF* kdf) : kdf_(kdf) {} KDF KDF::Fetch(const char* algorithm, OSSL_LIB_CTX* libctx) { @@ -2650,11 +2634,6 @@ bool KDF::derive(const Buffer& out, #endif 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); } @@ -2686,9 +2665,9 @@ DataPointer hkdf(const Digest& md, actual_salt = {default_salt, static_cast(md.size())}; } - // Keep extraction as a one-shot HMAC. The legacy path requires it because - // EVP_PKEY_derive rejects the zero-length keys Web Crypto allows. Both - // backends expand a pseudorandom key of exactly one digest block. + // Keep extraction as a one-shot HMAC because BoringSSL's EVP_PKEY_derive + // rejects the zero-length keys Web Crypto allows. Both backends expand a + // pseudorandom key of exactly one digest block. unsigned char pseudorandom_key[EVP_MAX_MD_SIZE]; unsigned pseudorandom_key_len = sizeof(pseudorandom_key); @@ -2705,7 +2684,7 @@ DataPointer hkdf(const Digest& md, auto buf = DataPointer::Alloc(length); if (!buf) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Expand through EVP_KDF directly. The EVP_PKEY_HKDF interface reaches the // same provider implementation, but only after allocating a second context // and translating every parameter across the legacy bridge. @@ -2732,13 +2711,10 @@ DataPointer hkdf(const Digest& md, if (!kdf.derive({buf.get(), length}, params.data())) { return {}; } -#else +#elif NCRYPTO_USE_BORINGSSL auto ctx = EVPKeyCtxPointer::NewFromName("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) || !EVP_PKEY_CTX_hkdf_mode(ctx.get(), EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) || !EVP_PKEY_CTX_set1_hkdf_key( @@ -2755,7 +2731,7 @@ DataPointer hkdf(const Digest& md, return buf; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { bool ScryptDerive(const Buffer& pass, const Buffer& salt, @@ -2800,10 +2776,10 @@ bool ScryptDerive(const Buffer& pass, #endif bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // A null output validates the parameters without deriving a key. return ScryptDerive({nullptr, 0}, {nullptr, 0}, N, r, p, maxmem, nullptr, 0); -#else +#elif NCRYPTO_USE_BORINGSSL return EVP_PBE_scrypt(nullptr, 0, nullptr, 0, N, r, p, maxmem, nullptr, 0) == 1; #endif @@ -2821,10 +2797,10 @@ DataPointer scrypt(const Buffer& pass, } auto dp = DataPointer::Alloc(length); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (dp && ScryptDerive( pass, salt, N, r, p, maxmem, dp.get(), length)) { -#else +#elif NCRYPTO_USE_BORINGSSL if (dp && EVP_PBE_scrypt(pass.data, pass.len, salt.data, @@ -2852,7 +2828,7 @@ DataPointer pbkdf2(const Digest& md, } auto dp = DataPointer::Alloc(length); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dp) return {}; auto kdf = KDF::Fetch(OSSL_KDF_NAME_PBKDF2); if (!kdf) return {}; @@ -2889,7 +2865,7 @@ DataPointer pbkdf2(const Digest& md, if (kdf.derive({dp.get(), length}, params)) { return dp; } -#else +#elif NCRYPTO_USE_BORINGSSL const EVP_MD* md_ptr = md; if (dp && PKCS5_PBKDF2_HMAC(pass.data, pass.len, @@ -3065,7 +3041,7 @@ const KeyAlgorithm KeyAlgorithm::SLH_DSA_SHAKE_256S("SLH-DSA-SHAKE-256s", Family // clang-format on namespace { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER constexpr char kSignatureContextString[] = "context-string"; constexpr char kSignatureInstance[] = "instance"; #endif @@ -3142,75 +3118,61 @@ size_t KeyAlgorithm::seedSize() const { } namespace { -#if !NCRYPTO_USE_OPENSSL3_PROVIDER -struct LegacyKeyAlgorithm { +#if NCRYPTO_USE_BORINGSSL +struct BoringSSLKeyAlgorithm { const char* name; int id; -#if NCRYPTO_USE_BORINGSSL const EVP_PKEY_ALG* (*raw_key_algorithm)() = nullptr; -#endif }; -// These backends require native key IDs. BoringSSL also uses EVP_PKEY_ALG -// descriptors for raw keys; keep both adapters in the same table. +// BoringSSL requires native key IDs and EVP_PKEY_ALG descriptors for raw keys; +// keep both adapters in the same table. // clang-format off // NOLINTBEGIN(whitespace/line_length) -const LegacyKeyAlgorithm kLegacyKeyAlgorithms[] = { +const BoringSSLKeyAlgorithm kBoringSSLKeyAlgorithms[] = { {KeyAlgorithm::RSA.name(), EVP_PKEY_RSA}, {KeyAlgorithm::RSA_PSS.name(), EVP_PKEY_RSA_PSS}, {KeyAlgorithm::DSA.name(), EVP_PKEY_DSA}, {KeyAlgorithm::DH.name(), EVP_PKEY_DH}, {KeyAlgorithm::EC.name(), EVP_PKEY_EC}, -#if NCRYPTO_USE_BORINGSSL {KeyAlgorithm::ED25519.name(), EVP_PKEY_ED25519, EVP_pkey_ed25519}, {KeyAlgorithm::X25519.name(), EVP_PKEY_X25519, EVP_pkey_x25519}, -#else - {KeyAlgorithm::ED25519.name(), EVP_PKEY_ED25519}, - {KeyAlgorithm::X25519.name(), EVP_PKEY_X25519}, -#endif {"HKDF", EVP_PKEY_HKDF}, {KeyAlgorithm::ED448.name(), EVP_PKEY_ED448}, {KeyAlgorithm::X448.name(), EVP_PKEY_X448}, -#ifndef OPENSSL_NO_SM2 - {KeyAlgorithm::SM2.name(), EVP_PKEY_SM2}, -#endif -#if NCRYPTO_USE_BORINGSSL {KeyAlgorithm::ML_DSA_44.name(), EVP_PKEY_ML_DSA_44, EVP_pkey_ml_dsa_44}, {KeyAlgorithm::ML_DSA_65.name(), EVP_PKEY_ML_DSA_65, EVP_pkey_ml_dsa_65}, {KeyAlgorithm::ML_DSA_87.name(), EVP_PKEY_ML_DSA_87, EVP_pkey_ml_dsa_87}, {KeyAlgorithm::ML_KEM_768.name(), EVP_PKEY_ML_KEM_768, EVP_pkey_ml_kem_768}, {KeyAlgorithm::ML_KEM_1024.name(), EVP_PKEY_ML_KEM_1024, EVP_pkey_ml_kem_1024}, -#endif }; // NOLINTEND(whitespace/line_length) // clang-format on -const LegacyKeyAlgorithm* FindLegacyKeyAlgorithm(const char* name) { +const BoringSSLKeyAlgorithm* FindBoringSSLKeyAlgorithm(const char* name) { if (name == nullptr) return nullptr; - for (const auto& algorithm : kLegacyKeyAlgorithms) { + for (const auto& algorithm : kBoringSSLKeyAlgorithms) { if (CaseInsensitiveNameEqual()(name, algorithm.name)) return &algorithm; } return nullptr; } -int GetLegacyKeyId(const char* name) { - const auto* algorithm = FindLegacyKeyAlgorithm(name); +int GetBoringSSLKeyId(const char* name) { + const auto* algorithm = FindBoringSSLKeyAlgorithm(name); return algorithm == nullptr ? NID_undef : algorithm->id; } -#if NCRYPTO_USE_BORINGSSL const EVP_PKEY_ALG* GetBoringSSLKeyAlgorithm(const KeyAlgorithm& algorithm) { - const auto* entry = FindLegacyKeyAlgorithm(algorithm.name()); + const auto* entry = FindBoringSSLKeyAlgorithm(algorithm.name()); return entry != nullptr && entry->raw_key_algorithm != nullptr ? entry->raw_key_algorithm() : nullptr; } #endif -#endif } // namespace void ConfigurePqcEncoding() { -#if NCRYPTO_USE_OPENSSL3_PROVIDER && OPENSSL_VERSION_PREREQ(3, 5) +#if NCRYPTO_USE_OPENSSL_PROVIDER && OPENSSL_VERSION_PREREQ(3, 5) // Configure all loaded providers to prefer seed-only format for ML-KEM and // ML-DSA private keys in PKCS#8 export, falling back to priv-only when a // seed is not available. The provider encoder reads these parameters at @@ -3239,35 +3201,25 @@ EVPKeyPointer EVPKeyPointer::New() { EVPKeyPointer EVPKeyPointer::NewRawPublic( const KeyAlgorithm& algorithm, const Buffer& data) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyPointer(EVP_PKEY_new_raw_public_key_ex( nullptr, algorithm.name(), nullptr, data.data, data.len)); #elif NCRYPTO_USE_BORINGSSL const auto* alg = GetBoringSSLKeyAlgorithm(algorithm); if (alg == nullptr) return {}; return EVPKeyPointer(EVP_PKEY_from_raw_public_key(alg, data.data, data.len)); -#else - const int id = GetLegacyKeyId(algorithm.name()); - if (id == NID_undef) return {}; - return EVPKeyPointer( - EVP_PKEY_new_raw_public_key(id, nullptr, data.data, data.len)); #endif } EVPKeyPointer EVPKeyPointer::NewRawPrivate( const KeyAlgorithm& algorithm, const Buffer& data) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyPointer(EVP_PKEY_new_raw_private_key_ex( nullptr, algorithm.name(), nullptr, data.data, data.len)); #elif NCRYPTO_USE_BORINGSSL const auto* alg = GetBoringSSLKeyAlgorithm(algorithm); if (alg == nullptr) return {}; return EVPKeyPointer(EVP_PKEY_from_raw_private_key(alg, data.data, data.len)); -#else - const int id = GetLegacyKeyId(algorithm.name()); - if (id == NID_undef) return {}; - return EVPKeyPointer( - EVP_PKEY_new_raw_private_key(id, nullptr, data.data, data.len)); #endif } @@ -3279,7 +3231,7 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed( if (seed_alg == nullptr) return {}; return EVPKeyPointer( EVP_PKEY_from_private_seed(seed_alg, data.data, data.len)); -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#else // ML-DSA and ML-KEM both use the provider parameter "seed". OSSL_PARAM params[] = { OSSL_PARAM_construct_octet_string( @@ -3293,16 +3245,14 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed( return {}; } return EVPKeyPointer(pkey); -#else - return {}; #endif } EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) { if (!dh) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyPointer(dh.release()); -#else +#elif NCRYPTO_USE_BORINGSSL auto key = New(); if (!key) return {}; if (EVP_PKEY_assign_DH(key.get(), dh.get())) { @@ -3312,7 +3262,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 {}; @@ -3366,7 +3316,7 @@ EVPKeyPointer EVPKeyPointer::NewRSA(const Rsa& rsa) { if (!params) return {}; return NewPKeyFromData(KeyAlgorithm::RSA, selection, params.get()); } -#else +#elif NCRYPTO_USE_BORINGSSL EVPKeyPointer EVPKeyPointer::NewRSA(RSAPointer&& rsa) { if (!rsa) return {}; auto key = New(); @@ -3376,7 +3326,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) {} @@ -3403,12 +3353,12 @@ EVP_PKEY* EVPKeyPointer::release() { bool EVPKeyPointer::isA(const EVP_PKEY* key, const char* name) { if (key == nullptr || name == nullptr) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // EVP_PKEY_is_a() can match an untyped key to an unknown legacy name. return EVP_PKEY_get0_type_name(key) != nullptr && EVP_PKEY_is_a(key, name) == 1; -#else - const int id = GetLegacyKeyId(name); +#elif NCRYPTO_USE_BORINGSSL + const int id = GetBoringSSLKeyId(name); return id != NID_undef && EVP_PKEY_id(key) == id; #endif } @@ -3416,13 +3366,12 @@ bool EVPKeyPointer::isA(const EVP_PKEY* key, const char* name) { // Returns true unless the key is known not to be SM2, so that a key whose curve // cannot be determined opts out of the prehashed fallback rather than into it. bool EVPKeyPointer::mayBeSM2() const { -#ifdef OPENSSL_NO_SM2 +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_NO_SM2) return false; #else if (isA(KeyAlgorithm::SM2)) return true; if (!isA(KeyAlgorithm::EC)) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER // An ECKeyPointer would also need the public point, which a provider-backed // key need not expose. char group_name[64]; @@ -3436,14 +3385,6 @@ bool EVPKeyPointer::mayBeSM2() const { } return OBJ_sn2nid(group_name) == NID_sm2 || EC_curve_nist2nid(group_name) == NID_sm2; -#else - ECKeyPointer ec(*this); - if (!ec) return true; - - const EC_GROUP* group = ec.getGroup(); - if (group == nullptr) return true; - return EC_GROUP_get_curve_name(group) == NID_sm2; -#endif #endif } @@ -3461,7 +3402,7 @@ bool EVPKeyPointer::isA(const KeyAlgorithm& algorithm) const { const KeyAlgorithm* EVPKeyPointer::getAlgorithm() const { if (!pkey_) return nullptr; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Provider primary names identify algorithms. Legacy ASN.1 methods can // share names (for example, SM2 uses EC), so resolve those through isA(). // The fallback also handles providers with a noncanonical primary alias. @@ -3474,9 +3415,9 @@ const KeyAlgorithm* EVPKeyPointer::getAlgorithm() const { for (const auto* algorithm : kKeyAlgorithms) { if (isA(*algorithm)) return algorithm; } -#else +#elif NCRYPTO_USE_BORINGSSL const int id = EVP_PKEY_id(get()); - for (const auto& algorithm : kLegacyKeyAlgorithms) { + for (const auto& algorithm : kBoringSSLKeyAlgorithms) { if (id == algorithm.id) return KeyAlgorithm::FromName(algorithm.name); } #endif @@ -3501,7 +3442,7 @@ bool EVPKeyPointer::supportsRawPrivate() const { bool EVPKeyPointer::supportsContextString() const { const auto* algorithm = getAlgorithm(); if (algorithm == nullptr || !algorithm->isOneShot()) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER MarkPopErrorOnReturn mark_pop_error_on_return; DeleteFnPtr signature( EVP_SIGNATURE_fetch(nullptr, EVP_PKEY_get0_type_name(get()), nullptr)); @@ -3513,8 +3454,6 @@ bool EVPKeyPointer::supportsContextString() const { OSSL_PARAM_locate_const(params, kSignatureInstance) != nullptr); #elif NCRYPTO_USE_BORINGSSL return algorithm->isPqc(); -#else - return false; #endif } @@ -3693,21 +3632,17 @@ DataPointer EVPKeyPointer::rawPublicKey() const { } namespace { -DataPointer GetRawSeed([[maybe_unused]] EVP_PKEY* key, size_t seed_len) { +DataPointer GetRawSeed(EVP_PKEY* key, size_t seed_len) { auto data = DataPointer::Alloc(seed_len); if (!data) return {}; -#if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_OPENSSL3_PROVIDER const Buffer buf = data; size_t len = data.size(); -#endif #if NCRYPTO_USE_BORINGSSL if (EVP_PKEY_get_private_seed(key, buf.data, &len) != 1) return {}; -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#else if (EVP_PKEY_get_octet_string_param(key, "seed", buf.data, buf.len, &len) != 1) return {}; -#else - return {}; #endif return data; } @@ -3785,16 +3720,16 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return EVP_PKEY_assign_EC_KEY(pkey_.get(), eckey.get()); #endif } 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; @@ -3851,7 +3786,7 @@ bool EVPKeyPointer::set(const ECKeyPointer& eckey) { if (!pkey) return false; reset(pkey.release()); return true; -#else +#elif NCRYPTO_USE_BORINGSSL return EVP_PKEY_set1_EC_KEY(pkey_.get(), eckey); #endif } @@ -3866,7 +3801,7 @@ EVPKeyPointer::operator const EC_KEY*() const { namespace { EVP_PKEY* DecodeRsaPublicKey(const unsigned char** data, size_t length) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Borrow the EVP_PKEY constructor and its data from a context that stays // alive until after the restricted decoder context is destroyed. EVP_PKEY* raw = nullptr; @@ -3901,7 +3836,7 @@ EVP_PKEY* DecodeRsaPublicKey(const unsigned char** data, size_t length) { const int result = OSSL_DECODER_from_data(ctx.get(), data, &length); EVPKeyPointer key(raw); return result == 1 ? key.release() : nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL return d2i_PublicKey(NID_rsaEncryption, nullptr, data, length); #endif } @@ -4075,7 +4010,7 @@ Buffer GetPassphrase( return pass; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using OSSLEncoderCtxPointer = DeleteFnPtr; @@ -4241,7 +4176,7 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryLoadPrivateKeyFromStore( const StorePrivateKeyConfig& config) { -#if !NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_BORINGSSL return ParseKeyResult(PKParseError::FAILED); #else // The error queue is left populated on failure so the caller can surface a @@ -4352,7 +4287,7 @@ Result EVPKeyPointer::writePrivateKey( // PKCS1 is only permitted for RSA keys. if (!isA(KeyAlgorithm::RSA)) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher.get() : nullptr; if (cipher != nullptr && passphrase.len == 0) { @@ -4367,12 +4302,8 @@ Result EVPKeyPointer::writePrivateKey( cipher, passphrase); } -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const RSA* rsa = EVP_PKEY_get0_RSA(get()); -#else +#elif NCRYPTO_USE_BORINGSSL RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif if (rsa == nullptr) return Result(false); switch (config.format) { @@ -4434,7 +4365,7 @@ Result EVPKeyPointer::writePrivateKey( // SEC1 is only permitted for EC keys if (!isA(KeyAlgorithm::EC)) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher.get() : nullptr; err = !WriteEncodedPKey(bio.get(), @@ -4444,12 +4375,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 +#elif NCRYPTO_USE_BORINGSSL EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); -#endif if (ec == nullptr) return Result(false); switch (config.format) { @@ -4501,7 +4428,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 (!isA(KeyAlgorithm::RSA)) return Result(false); if (!WriteEncodedPKey(bio.get(), get(), @@ -4512,12 +4439,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 +#elif NCRYPTO_USE_BORINGSSL RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif if (rsa == nullptr) return Result(false); if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { @@ -4538,7 +4461,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, @@ -4548,7 +4471,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(). @@ -4563,8 +4486,8 @@ Result EVPKeyPointer::writePublicKey( return Result(false, mark_pop_error_on_return.peekError()); } -#else - // Non-OpenSSL >= 3 builds do not all declare PEM_write_bio_X509_PUBKEY(). +#elif NCRYPTO_USE_BORINGSSL + // 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()); @@ -4582,9 +4505,6 @@ Result EVPKeyPointer::writePublicKey( } bool EVPKeyPointer::isRsaVariant(const EVP_PKEY* key) { -#if !NCRYPTO_USE_OPENSSL3_PROVIDER && !NCRYPTO_USE_BORINGSSL - if (key != nullptr && EVP_PKEY_id(key) == EVP_PKEY_RSA2) return true; -#endif return isA(key, KeyAlgorithm::RSA) || isA(key, KeyAlgorithm::RSA_PSS); } @@ -4605,11 +4525,11 @@ std::optional EVPKeyPointer::getBytesOfRS() const { int bits; if (isA(KeyAlgorithm::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()); -#else +#elif NCRYPTO_USE_BORINGSSL const DSA* dsa_key = EVP_PKEY_get0_DSA(get()); bool has_bits = false; // Both r and s are computed mod q, so their width is limited by that of q. @@ -4623,9 +4543,9 @@ std::optional EVPKeyPointer::getBytesOfRS() const { if (!has_bits) return std::nullopt; #endif } else if (isA(KeyAlgorithm::EC)) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bits = EVP_PKEY_bits(get()); -#else +#elif NCRYPTO_USE_BORINGSSL const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(get()); if (ec_key == nullptr) return std::nullopt; const EC_GROUP* group = ECKeyPointer::GetGroup(ec_key); @@ -4644,17 +4564,10 @@ std::optional EVPKeyPointer::getBytesOfRS() const { EVPKeyPointer::operator Rsa() const { if (!isA(KeyAlgorithm::RSA) && !isA(KeyAlgorithm::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())); - } +#elif NCRYPTO_USE_BORINGSSL + OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get()); if (rsa == nullptr) return {}; return Rsa(rsa); #endif @@ -4663,9 +4576,9 @@ EVPKeyPointer::operator Rsa() const { EVPKeyPointer::operator Dsa() const { if (!isA(KeyAlgorithm::DSA)) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return Dsa(get()); -#else +#elif NCRYPTO_USE_BORINGSSL OSSL3_CONST DSA* dsa = EVP_PKEY_get0_DSA(get()); if (dsa == nullptr) return {}; return Dsa(dsa); @@ -4674,14 +4587,14 @@ 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) && isA(KeyAlgorithm::DSA)) { -#else +#elif defined(OPENSSL_IS_BORINGSSL) if (FIPS_mode() && isA(KeyAlgorithm::DSA)) { #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) || @@ -4690,7 +4603,7 @@ bool EVPKeyPointer::validateDsaParameters() const { } const BIGNUM* p_value = p.get(); const BIGNUM* q_value = q.get(); -#else +#elif NCRYPTO_USE_BORINGSSL const DSA* dsa = EVP_PKEY_get0_DSA(pkey_.get()); if (dsa == nullptr) return false; const BIGNUM* p; @@ -4843,7 +4756,7 @@ EVPKeyPointer SSLPointer::getPeerTempKey() const { EVP_PKEY* raw_key = nullptr; #ifndef OPENSSL_IS_BORINGSSL if (!SSL_get_peer_tmp_key(get(), &raw_key)) return {}; -#else +#elif defined(OPENSSL_IS_BORINGSSL) if (!SSL_get_server_tmp_key(get(), &raw_key)) return {}; #endif return EVPKeyPointer(raw_key); @@ -4946,7 +4859,7 @@ bool SSLCtxPointer::setCipherSuites(const char* ciphers) { #ifndef OPENSSL_IS_BORINGSSL if (!ctx_) return false; return SSL_CTX_set_ciphersuites(ctx_.get(), ciphers); -#else +#elif defined(OPENSSL_IS_BORINGSSL) // BoringSSL does not allow API config of TLS 1.3 cipher suites. // We treat this as a non-op. return true; @@ -4960,7 +4873,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; @@ -5002,7 +4915,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 @@ -5025,12 +4938,12 @@ 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 {}; return lookup(it->second, generation); -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(name); static_cast(generation); return {}; @@ -5040,7 +4953,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 {}; } @@ -5076,7 +4989,7 @@ DigestCache::Result DigestCache::insert(const char* name, aliases_.insert_or_assign(name, id); return {digests_[index].get(), id}; -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(name); static_cast(digest); static_cast(generation); @@ -5085,7 +4998,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(); @@ -5095,16 +5008,16 @@ 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 +#elif NCRYPTO_USE_BORINGSSL static const AliasMap empty; return empty; #endif } 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(); @@ -5115,14 +5028,14 @@ const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { if (it == aliases_.end()) return nullptr; if (it->second >= ciphers_.size()) return nullptr; return ciphers_[it->second].get(); -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(name); static_cast(generation); return nullptr; #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* CipherCache::insert( const char* name, DeleteFnPtr&& cipher, @@ -5159,7 +5072,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()); @@ -5172,7 +5085,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()); @@ -5192,13 +5105,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. @@ -5222,7 +5135,7 @@ const Cipher Cipher::FromName(const char* name, CipherCache* cache) { } return Cipher(std::move(fetched)); -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(cache); return Cipher(); #endif @@ -5231,7 +5144,7 @@ const Cipher Cipher::FromName(const char* name, CipherCache* cache) { const Cipher Cipher::FromNameForKeyEncoding(const char* name) { // Key serializers have their own cipher restrictions. Preserve their policy // instead of applying the filters used by the general cipher operations. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER MarkPopErrorOnReturn mark_pop_error_on_return; DeleteFnPtr fetched( EVP_CIPHER_fetch(nullptr, name, nullptr)); @@ -5244,16 +5157,16 @@ const Cipher Cipher::FromNameForKeyEncoding(const char* name) { 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 +#elif NCRYPTO_USE_BORINGSSL static_cast(cache); #endif @@ -5360,9 +5273,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return false; #endif } @@ -5376,7 +5289,7 @@ bool Cipher::isSivMode() const { if (!cipher_) return false; #if OPENSSL_WITH_AES_SIV return getMode() == EVP_CIPH_SIV_MODE; -#else +#elif NCRYPTO_USE_BORINGSSL return false; #endif } @@ -5471,9 +5384,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL return {}; #endif } @@ -5568,10 +5481,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, @@ -5597,9 +5510,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL static_cast(mode); return false; #endif @@ -5611,9 +5524,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL static_cast(standard); return false; #endif @@ -5663,7 +5576,7 @@ bool CipherCtxPointer::isSivMode() const { if (!ctx_) return false; #if OPENSSL_WITH_AES_SIV return getMode() == EVP_CIPH_SIV_MODE; -#else +#elif NCRYPTO_USE_BORINGSSL return false; #endif } @@ -6316,15 +6229,13 @@ EVPKeyCtxPointer EVPKeyCtxPointer::New(const EVPKeyPointer& key) { EVPKeyCtxPointer EVPKeyCtxPointer::NewFromName(const char* name) { if (name == nullptr) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyCtxPointer(EVP_PKEY_CTX_new_from_name(nullptr, name, nullptr)); -#else - const int id = GetLegacyKeyId(name); +#elif NCRYPTO_USE_BORINGSSL + const int id = GetBoringSSLKeyId(name); if (id == NID_undef) return {}; -#ifdef OPENSSL_IS_BORINGSSL // DSA keys are not supported with BoringSSL. if (id == EVP_PKEY_DSA) return {}; -#endif return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(id, nullptr)); #endif } @@ -6365,7 +6276,7 @@ bool EVPKeyCtxPointer::setDhParameters(int prime_size, uint32_t generator) { if (!ctx_) return false; return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx_.get(), prime_size) == 1 && EVP_PKEY_CTX_set_dh_paramgen_generator(ctx_.get(), generator) == 1; -#else +#elif defined(OPENSSL_IS_BORINGSSL) // TODO(jasnell): Boringssl appears not to support this operation. // Is there an alternative approach that Boringssl does support? return false; @@ -6392,7 +6303,7 @@ bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) { bool EVPKeyCtxPointer::setEcParameters(const char* group_name, int encoding) { if (!ctx_ || group_name == nullptr) return false; const int curve = Ec::GetCurveIdFromName(group_name); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Keep the historical aliases while allowing names known only to providers. if (curve != NID_undef) group_name = OBJ_nid2sn(curve); @@ -6415,7 +6326,7 @@ bool EVPKeyCtxPointer::setEcParameters(const char* group_name, int encoding) { OSSL_PARAM_END, }; return EVP_PKEY_CTX_set_params(ctx_.get(), params) == 1; -#else +#elif NCRYPTO_USE_BORINGSSL return curve != NID_undef && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx_.get(), curve) == 1 && EVP_PKEY_CTX_set_ec_param_enc(ctx_.get(), encoding) == 1; @@ -6458,9 +6369,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx_.get(), e.get()) == 1) { // The ctx_ takes ownership of e on success. e.release(); @@ -6472,15 +6383,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) { @@ -6500,7 +6408,7 @@ bool EVPKeyCtxPointer::setRsaImplicitRejection() { // of how it is set. The call to set the value // will not affect what is used since a different context is // used in the call if the option is supported -#else +#elif defined(OPENSSL_IS_BORINGSSL) // TODO(jasnell): Boringssl appears not to support this operation. // Is there an alternative approach that Boringssl does support? return true; @@ -6558,12 +6466,8 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) // Boringssl appears not to support this operation. // TODO(jasnell): Is there an alternative approach that Boringssl does // support? @@ -6575,7 +6479,7 @@ bool EVPKeyCtxPointer::privateCheck() const { if (!ctx_) return false; #ifndef OPENSSL_IS_BORINGSSL return EVP_PKEY_check(ctx_.get()) == 1; -#else +#elif defined(OPENSSL_IS_BORINGSSL) // Boringssl appears not to support this operation. // TODO(jasnell): Is there an alternative approach that Boringssl does // support? @@ -6720,7 +6624,7 @@ Rsa::OtherPrimeInfoPointer::OtherPrimeInfoPointer(BignumPointer&& r, BignumPointer&& t) : r(r.release()), d(d.release()), t(t.release()) {} -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { // Normalizes a provider digest name such as "SHA2-256" to the long name the // rest of the key details use ("sha256"). The returned storage has static @@ -6872,24 +6776,24 @@ Rsa::Rsa(const EVP_PKEY* pkey, Selection selection) : Rsa() { rsa_ = true; } -#else +#elif NCRYPTO_USE_BORINGSSL Rsa::Rsa() : rsa_(nullptr) {} Rsa::Rsa(OSSL3_CONST RSA* ptr) : rsa_(ptr) {} #endif Rsa Rsa::PublicOnly(const EVPKeyPointer& key) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return Rsa(key.get(), Selection::Public); -#else +#elif NCRYPTO_USE_BORINGSSL return key; #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 +#elif NCRYPTO_USE_BORINGSSL if (rsa_ == nullptr) return {}; PublicKey key; RSA_get0_key(rsa_, &key.n, &key.e, &key.d); @@ -6898,10 +6802,10 @@ 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 +#elif NCRYPTO_USE_BORINGSSL if (rsa_ == nullptr) return {}; PrivateKey key; RSA_get0_factors(rsa_, &key.p, &key.q); @@ -6912,29 +6816,11 @@ const Rsa::PrivateKey Rsa::getPrivateKey() const { const Rsa::OtherPrimeInfos Rsa::getOtherPrimeInfos() const { OtherPrimeInfos infos; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER infos.reserve(other_prime_infos_.size()); for (const auto& info : other_prime_infos_) { infos.push_back({info.r.get(), info.d.get(), info.t.get()}); } -#elif NCRYPTO_USE_LEGACY_OPENSSL - if (rsa_ == nullptr) return infos; - const int count = RSA_get_multi_prime_extra_count(rsa_); - if (count <= 0) return infos; - - std::vector factors(count); - std::vector exponents(count); - std::vector coefficients(count); - if (RSA_get0_multi_prime_factors(rsa_, factors.data()) != 1 || - RSA_get0_multi_prime_crt_params( - rsa_, exponents.data(), coefficients.data()) != 1) { - return {}; - } - - infos.reserve(count); - for (int i = 0; i < count; i++) { - infos.push_back({factors[i], exponents[i], coefficients[i]}); - } #endif return infos; } @@ -6960,9 +6846,9 @@ bool Rsa::checkPrimeProduct() const { } const std::optional Rsa::getPssParams() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pss_params_; -#else +#elif NCRYPTO_USE_BORINGSSL if (rsa_ == nullptr) return std::nullopt; const RSA_PSS_PARAMS* params = RSA_get0_pss_params(rsa_); if (params == nullptr) return std::nullopt; @@ -7001,7 +6887,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_) { @@ -7032,7 +6918,7 @@ BIOPointer Rsa::derPublicKey() const { } parameters.release(); if (i2d_X509_PUBKEY_bio(bio.get(), pubkey.get()) != 1) return {}; -#else +#elif NCRYPTO_USE_BORINGSSL if (rsa_ == nullptr || i2d_RSA_PUBKEY_bio(bio.get(), rsa_) != 1) return {}; #endif return bio; @@ -7040,12 +6926,12 @@ 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; return true; -#else +#elif NCRYPTO_USE_BORINGSSL if (RSA_set0_key(const_cast(rsa_), n.get(), e.get(), nullptr) == 1) { n.release(); e.release(); @@ -7062,7 +6948,7 @@ bool Rsa::setPrivateKey(BignumPointer&& d, BignumPointer&& dq, BignumPointer&& qi, OtherPrimeInfoPointers&& other_prime_infos) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!d || !q || !p || !dp || !dq || !qi) return false; for (const auto& info : other_prime_infos) { if (!info.r || !info.d || !info.t) return false; @@ -7076,7 +6962,7 @@ bool Rsa::setPrivateKey(BignumPointer&& d, other_prime_infos_ = std::move(other_prime_infos); rsa_ = n_ != nullptr && e_ != nullptr; return rsa_; -#else +#elif NCRYPTO_USE_BORINGSSL if (!RSA_set0_key(const_cast(rsa_), nullptr, nullptr, d.get())) { return false; } @@ -7096,36 +6982,7 @@ bool Rsa::setPrivateKey(BignumPointer&& d, dq.release(); qi.release(); -#if NCRYPTO_USE_LEGACY_OPENSSL - if (!other_prime_infos.empty()) { - std::vector factors; - std::vector exponents; - std::vector coefficients; - factors.reserve(other_prime_infos.size()); - exponents.reserve(other_prime_infos.size()); - coefficients.reserve(other_prime_infos.size()); - for (const auto& info : other_prime_infos) { - if (!info.r || !info.d || !info.t) return false; - factors.push_back(info.r.get()); - exponents.push_back(info.d.get()); - coefficients.push_back(info.t.get()); - } - if (RSA_set0_multi_prime_params(const_cast(rsa_), - factors.data(), - exponents.data(), - coefficients.data(), - static_cast(factors.size())) != 1) { - return false; - } - for (auto& info : other_prime_infos) { - info.r.release(); - info.d.release(); - info.t.release(); - } - } -#else if (!other_prime_infos.empty()) return false; -#endif return true; #endif } @@ -7179,7 +7036,7 @@ struct CipherCallbackContext { void operator()(const char* name) { cb(name); } }; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER template void array_push_back(const TypeName* evp_ref, const char* from, @@ -7271,17 +7128,17 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) { } #else EVP_CIPHER_do_all_sorted( -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER array_push_back, -#else +#elif NCRYPTO_USE_BORINGSSL array_push_back, #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 @@ -7289,7 +7146,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() { @@ -7355,31 +7212,31 @@ Ec::Ec(const EVP_PKEY* pkey) : Ec() { } pub_.reset(point.release()); } -#else +#elif NCRYPTO_USE_BORINGSSL Ec::Ec() : ec_(nullptr) {} 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 +#elif NCRYPTO_USE_BORINGSSL return ECKeyPointer::GetGroup(ec_); #endif } const EC_POINT* Ec::getPublicKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pub_.get(); -#else +#elif NCRYPTO_USE_BORINGSSL return ECKeyPointer::GetPublicKey(ec_); #endif } point_conversion_form_t Ec::getPointConversionForm() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return form_; -#else +#elif NCRYPTO_USE_BORINGSSL return EC_KEY_get_conv_form(ec_); #endif } @@ -7409,7 +7266,7 @@ BIOPointer Ec::ExportPrivatePkcs8(const EVPKeyPointer& key) { DataPointer Ec::TryExportPublic(const EVPKeyPointer& key, point_conversion_form_t form) { if (!key || form != POINT_CONVERSION_UNCOMPRESSED) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER { MarkPopErrorOnReturn pop_errors; size_t length = 0; @@ -7433,7 +7290,7 @@ DataPointer Ec::TryExportPublic(const EVPKeyPointer& key, DataPointer Ec::ExportPrivate(const EVPKeyPointer& key) { if (!key) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER { MarkPopErrorOnReturn pop_errors; BignumPointer priv; @@ -7458,7 +7315,7 @@ bool Ec::GetKeyComponents(const EVPKeyPointer& key, BignumPointer* priv, int* degree) { if (!key) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int nid = GetCurveId(key); switch (nid) { case NID_X9_62_prime256v1: @@ -7514,7 +7371,7 @@ bool Ec::GetKeyComponents(const EVPKeyPointer& key, int Ec::GetCurveId(const EVPKeyPointer& key) { if (!key) return NID_undef; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER char name[80]; size_t length = 0; if (EVP_PKEY_get_utf8_string_param( @@ -7523,7 +7380,7 @@ int Ec::GetCurveId(const EVPKeyPointer& key) { return NID_undef; } return GetCurveIdFromName(name); -#else +#elif NCRYPTO_USE_BORINGSSL const EC_KEY* ec = key; if (ec == nullptr) return NID_undef; const EC_GROUP* group = EC_KEY_get0_group(ec); @@ -7533,7 +7390,7 @@ int Ec::GetCurveId(const EVPKeyPointer& key) { std::optional Ec::GetCurveName(const EVPKeyPointer& key) { if (!key) return std::nullopt; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER size_t length = 0; if (EVP_PKEY_get_utf8_string_param( key.get(), OSSL_PKEY_PARAM_GROUP_NAME, nullptr, 0, &length) != 1) { @@ -7551,14 +7408,14 @@ std::optional Ec::GetCurveName(const EVPKeyPointer& key) { // Preserve the public short names for the curves OpenSSL already knows. const int nid = GetCurveIdFromName(name.c_str()); return nid == NID_undef ? name : std::string(OBJ_nid2sn(nid)); -#else +#elif NCRYPTO_USE_BORINGSSL const int nid = GetCurveId(key); if (nid == NID_undef) return std::nullopt; return std::string(OBJ_nid2sn(nid)); #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { bool IsAvailableEcGroup(const char* name) { MarkPopErrorOnReturn mark; @@ -7572,12 +7429,12 @@ bool IsAvailableEcGroup(const char* name) { bool Ec::CheckCurveName(const char* name) { if (name == nullptr) return false; if (GetCurveIdFromName(name) != NID_undef) return true; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Keep invalid names a synchronous argument error. Generation contexts can // defer rejecting a group until parameter generation. Use the same parameter // generation path as key generation without requiring parameter import. return IsAvailableEcGroup(name); -#else +#elif NCRYPTO_USE_BORINGSSL return false; #endif } @@ -7606,7 +7463,7 @@ bool Ec::GetCurves(Ec::GetCurveCallback callback) { } for (const auto& curve : curves) { const char* name = OBJ_nid2sn(curve.nid); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!IsAvailableEcGroup(name)) continue; #endif if (!callback(name)) return false; @@ -7745,7 +7602,7 @@ std::optional EVPMDCtxPointer::signInitWithContext( return std::nullopt; } return ctx; -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#else EVP_PKEY_CTX* ctx = nullptr; // Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode. @@ -7779,8 +7636,6 @@ std::optional EVPMDCtxPointer::signInitWithContext( return std::nullopt; } return ctx; -#else - return std::nullopt; #endif } @@ -7798,7 +7653,7 @@ std::optional EVPMDCtxPointer::verifyInitWithContext( return std::nullopt; } return ctx; -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#else EVP_PKEY_CTX* ctx = nullptr; // Ed25519 requires the INSTANCE param to switch into Ed25519ctx mode. @@ -7832,8 +7687,6 @@ std::optional EVPMDCtxPointer::verifyInitWithContext( return std::nullopt; } return ctx; -#else - return std::nullopt; #endif } @@ -7907,7 +7760,7 @@ bool extractP1363(const Buffer& buf, // ============================================================================ -#if !OPENSSL_WITH_EVP_MAC +#if NCRYPTO_USE_BORINGSSL HMACCtxPointer::HMACCtxPointer() : ctx_(nullptr) {} HMACCtxPointer::HMACCtxPointer(HMAC_CTX* ctx) : ctx_(ctx) {} @@ -7967,7 +7820,7 @@ bool HMACCtxPointer::digestInto(Buffer* buf) { HMACCtxPointer HMACCtxPointer::New() { return HMACCtxPointer(HMAC_CTX_new()); } -#endif // !OPENSSL_WITH_EVP_MAC +#endif // NCRYPTO_USE_BORINGSSL #if OPENSSL_WITH_EVP_MAC EVPMacPointer::EVPMacPointer(EVP_MAC* mac) : mac_(mac) {} @@ -8342,7 +8195,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() { @@ -8353,16 +8206,16 @@ Dsa::Dsa(const EVP_PKEY* pkey) : Dsa() { } dsa_ = true; } -#else +#elif NCRYPTO_USE_BORINGSSL Dsa::Dsa() : dsa_(nullptr) {} 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 +#elif NCRYPTO_USE_BORINGSSL if (dsa_ == nullptr) return nullptr; const BIGNUM* p; DSA_get0_pqg(dsa_, &p, nullptr, nullptr); @@ -8371,10 +8224,10 @@ 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 +#elif NCRYPTO_USE_BORINGSSL if (dsa_ == nullptr) return nullptr; const BIGNUM* q; DSA_get0_pqg(dsa_, nullptr, &q, nullptr); @@ -8383,18 +8236,18 @@ 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 +#elif NCRYPTO_USE_BORINGSSL if (dsa_ == nullptr) return 0; #endif return BignumPointer::GetBitCount(getP()); } size_t Dsa::getDivisorLength() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return 0; -#else +#elif NCRYPTO_USE_BORINGSSL if (dsa_ == nullptr) return 0; #endif return BignumPointer::GetBitCount(getQ()); @@ -8407,13 +8260,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()); @@ -8426,7 +8279,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()); @@ -8449,7 +8302,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; @@ -8467,7 +8320,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); @@ -8477,7 +8330,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)); @@ -8492,7 +8345,7 @@ const Digest Digest::Fetch(const char* name) { // ============================================================================ // KEM Implementation #if OPENSSL_WITH_KEM -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool KEM::SetOperationParameter(EVP_PKEY_CTX* ctx, const EVPKeyPointer& key) { const OSSL_PARAM* settable = EVP_PKEY_CTX_settable_params(ctx); if (settable == nullptr || @@ -8525,7 +8378,7 @@ std::optional KEM::Encapsulate( return std::nullopt; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!SetOperationParameter(ctx.get(), public_key)) { return std::nullopt; } @@ -8566,7 +8419,7 @@ DataPointer KEM::Decapsulate(const EVPKeyPointer& private_key, return {}; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!SetOperationParameter(ctx.get(), private_key)) { return {}; } diff --git a/deps/ncrypto/ncrypto.gyp b/deps/ncrypto/ncrypto.gyp index 804a664fa0a..e0c8e2b6e4b 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 30dccfc0c79..78df111fa95 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -33,6 +33,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 @@ -46,48 +51,28 @@ #endif // Backend split: -// - OpenSSL >= 3 uses provider APIs and hides deprecated low-level objects. -// - BoringSSL has its own API-compatible branch. -// - OpenSSL < 3 remains the legacy fallback branch. -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0) -#define NCRYPTO_USE_OPENSSL3_PROVIDER 1 -#else -#define NCRYPTO_USE_OPENSSL3_PROVIDER 0 -#endif - +// - OpenSSL uses provider APIs and hides deprecated low-level objects. +// - BoringSSL has its own API-compatible branch and keeps using the legacy +// low-level key types. #ifdef OPENSSL_IS_BORINGSSL #define NCRYPTO_USE_BORINGSSL 1 +#define NCRYPTO_USE_OPENSSL_PROVIDER 0 #else #define NCRYPTO_USE_BORINGSSL 0 +#define NCRYPTO_USE_OPENSSL_PROVIDER 1 #endif -#if !NCRYPTO_USE_OPENSSL3_PROVIDER && !NCRYPTO_USE_BORINGSSL -#define NCRYPTO_USE_LEGACY_OPENSSL 1 -#else -#define NCRYPTO_USE_LEGACY_OPENSSL 0 -#endif - -#if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_LEGACY_OPENSSL -#define NCRYPTO_USE_LEGACY_KEY_TYPES 1 -#else -#define NCRYPTO_USE_LEGACY_KEY_TYPES 0 -#endif +#define NCRYPTO_USE_LEGACY_KEY_TYPES NCRYPTO_USE_BORINGSSL -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #include #endif -// The FIPS-related functions are only available -// when the OpenSSL itself was compiled with FIPS support. -#if defined(OPENSSL_FIPS) && !OPENSSL_VERSION_PREREQ(3, 0) -#include -#endif // OPENSSL_FIPS - -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_OCB 1 -#else +#elif defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_OCB 0 #endif @@ -97,21 +82,17 @@ #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 +#elif defined(OPENSSL_IS_BORINGSSL) #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 +#elif defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_SIV 0 #endif @@ -121,9 +102,9 @@ #define OPENSSL_WITH_AES_GCM_SIV 0 #endif -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OSSL3_CONST const -#else +#elif defined(OPENSSL_IS_BORINGSSL) #define OSSL3_CONST #endif @@ -359,7 +340,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; @@ -384,7 +365,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 @@ -417,14 +398,14 @@ 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 {}; const size_t index = unsigned_id - first_id_; if (index >= digests_.size()) return {}; return {digests_[index].get(), id}; -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(id); static_cast(generation); return {}; @@ -436,7 +417,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 @@ -462,14 +443,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; @@ -503,7 +484,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; @@ -599,7 +580,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 @@ -611,18 +592,18 @@ 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 +#elif NCRYPTO_USE_BORINGSSL 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_; } -#else +#elif NCRYPTO_USE_BORINGSSL inline operator bool() const { return dsa_ != nullptr; } #endif #if NCRYPTO_USE_LEGACY_KEY_TYPES @@ -635,11 +616,11 @@ 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_; -#else +#elif NCRYPTO_USE_BORINGSSL OSSL3_CONST DSA* dsa_; #endif }; @@ -652,18 +633,18 @@ class Rsa final { Rsa(); enum class Selection { Public, Private }; static Rsa PublicOnly(const EVPKeyPointer& key); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Rsa(const EVP_PKEY* pkey, Selection selection = Selection::Private); -#else +#elif NCRYPTO_USE_BORINGSSL 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_; } -#else +#elif NCRYPTO_USE_BORINGSSL inline operator bool() const { return rsa_ != nullptr; } #endif #if NCRYPTO_USE_LEGACY_KEY_TYPES @@ -733,7 +714,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_; @@ -746,7 +727,7 @@ class Rsa final { DeleteFnPtr qi_; OtherPrimeInfoPointers other_prime_infos_; std::optional pss_params_; -#else +#elif NCRYPTO_USE_BORINGSSL OSSL3_CONST RSA* rsa_; #endif }; @@ -754,9 +735,9 @@ 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 +#elif NCRYPTO_USE_BORINGSSL Ec(OSSL3_CONST EC_KEY* key); #endif NCRYPTO_DISALLOW_COPY_AND_MOVE(Ec) @@ -790,11 +771,11 @@ 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; -#else +#elif NCRYPTO_USE_BORINGSSL OSSL3_CONST EC_KEY* ec_ = nullptr; #endif }; @@ -1209,9 +1190,9 @@ class EVPKeyPointer final { static EVPKeyPointer NewRawSeed(const KeyAlgorithm& algorithm, const Buffer& data); static EVPKeyPointer NewDH(DHPointer&& dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER static EVPKeyPointer NewRSA(const Rsa& rsa); -#else +#elif NCRYPTO_USE_BORINGSSL static EVPKeyPointer NewRSA(RSAPointer&& rsa); #endif @@ -1396,10 +1377,10 @@ 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 +#elif NCRYPTO_USE_BORINGSSL explicit DHPointer(DH* dh); #endif DHPointer(DHPointer&& other) noexcept; @@ -1407,14 +1388,14 @@ 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(); } inline operator bool() const { return dh_ != nullptr || (p_ && g_); } -#else +#elif NCRYPTO_USE_BORINGSSL inline bool operator==(std::nullptr_t) noexcept { return dh_ == nullptr; } inline operator bool() const { return dh_ != nullptr; } #endif @@ -1476,14 +1457,14 @@ class DHPointer final { const EVPKeyPointer& theirKey); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr dh_; BignumPointer p_; BignumPointer g_; BignumPointer pub_key_; BignumPointer pvt_key_; const char* group_name_ = nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL DeleteFnPtr dh_; #endif }; @@ -1804,14 +1785,14 @@ 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; } inline operator bool() const { return group_ != nullptr; } -#else +#elif NCRYPTO_USE_BORINGSSL inline bool operator==(std::nullptr_t) noexcept { return key_ == nullptr; } inline operator bool() const { return key_ != nullptr; } #endif @@ -1849,11 +1830,11 @@ class ECKeyPointer final { #endif private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr group_; DeleteFnPtr pub_; DeleteFnPtr priv_; -#else +#elif NCRYPTO_USE_BORINGSSL DeleteFnPtr key_; #endif }; @@ -1923,7 +1904,7 @@ class EVPMDCtxPointer final { DeleteFnPtr ctx_; }; -#if !OPENSSL_WITH_EVP_MAC +#if NCRYPTO_USE_BORINGSSL class HMACCtxPointer final { public: HMACCtxPointer(); @@ -1950,7 +1931,7 @@ class HMACCtxPointer final { private: DeleteFnPtr ctx_; }; -#endif // !OPENSSL_WITH_EVP_MAC +#endif // NCRYPTO_USE_BORINGSSL #if OPENSSL_WITH_EVP_MAC class EVPMacPointer final { @@ -2086,7 +2067,7 @@ class HMACCtxPointer final { }; #endif // OPENSSL_WITH_EVP_MAC -#if !OPENSSL_WITH_EVP_MAC +#if NCRYPTO_USE_BORINGSSL class MacCache final { public: MacCache() = default; @@ -2176,7 +2157,7 @@ Buffer ExportChallenge(const char* input, size_t length); // ============================================================================ // KDF -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER class KDF final { public: KDF() = default; @@ -2272,7 +2253,7 @@ class KEM final { const Buffer& ciphertext); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER static bool SetOperationParameter(EVP_PKEY_CTX* ctx, const EVPKeyPointer& key); #endif diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 823d87e7f20..72a86e82672 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1635,7 +1635,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 @@ -1947,7 +1947,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.isA(KeyAlgorithm::DH)) dh.reset(params.release()); #else @@ -1971,7 +1971,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 @@ -1980,7 +1980,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 } @@ -2370,7 +2370,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); @@ -2378,7 +2378,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) { @@ -2402,7 +2402,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, @@ -2499,7 +2499,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 73aff5b628a..86634007984 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 28abba798da..8bfde65327f 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -195,7 +195,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 24d49a6d377..6c3e7efc672 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -76,7 +76,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()) { @@ -107,7 +107,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()) { @@ -235,7 +235,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) { @@ -248,7 +248,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); @@ -284,7 +284,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); @@ -311,7 +311,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) { @@ -352,7 +352,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); @@ -367,7 +367,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)); @@ -531,7 +531,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 = @@ -607,7 +607,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_keys.cc b/src/crypto/crypto_keys.cc index 580f9ac009d..d7aef2b5d08 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -334,8 +334,7 @@ bool GetAsymmetricKeyDetail(Environment* env, } const auto& pkey = key.GetAsymmetricKey(); const auto* algorithm = pkey.getAlgorithm(); - // Preserve RSA2 support on legacy backends without exposing its numeric ID. - if (algorithm != nullptr ? algorithm->isRsa() : pkey.isRsaVariant()) { + if (algorithm != nullptr && algorithm->isRsa()) { return GetRsaKeyDetail(env, key, target); } if (algorithm == &KeyAlgorithm::DSA) return GetDsaKeyDetail(env, key, target); diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index e3c594bfbc4..817929b8955 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -44,7 +44,7 @@ namespace { constexpr uint32_t kMaxRsaOtherPrimeInfos = 8; 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; @@ -397,7 +397,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { return {}; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::Rsa rsa_view; #else RSAPointer rsa(RSA_new()); @@ -511,7 +511,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 1e003e9e51b..f884ee4bdd8 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -7,7 +7,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 diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index fbc5fc8c39c..e1c147f56bc 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -952,7 +952,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 a99b4f10af2..b980a578721 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -899,7 +899,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 24cd7b62e4f..25e98d6b9d2 100644 --- a/src/env.cc +++ b/src/env.cc @@ -981,7 +981,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.cc b/test/cctest/test_node_crypto.cc index 6e1e687df0d..632ac1f8a40 100644 --- a/test/cctest/test_node_crypto.cc +++ b/test/cctest/test_node_crypto.cc @@ -15,7 +15,7 @@ #include #include -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #include @@ -74,7 +74,7 @@ TEST(NodeCrypto, KeyAlgorithmNames) { EXPECT_FALSE(empty.isA(static_cast(nullptr))); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER TEST(NodeCrypto, ProviderPkcs1PublicKeyImport) { ncrypto::ClearErrorOnReturn clear_errors; auto ctx = EVPKeyCtxPointer::NewFromAlgorithm(KeyAlgorithm::RSA); @@ -404,11 +404,11 @@ TEST(NodeCrypto, EcKeyComponents) { 0); auto raw_public = ncrypto::Ec::TryExportPublic(key, POINT_CONVERSION_UNCOMPRESSED); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ASSERT_TRUE(raw_public); ASSERT_EQ(raw_public.size(), point.size()); EXPECT_EQ(memcmp(raw_public.get(), point.get(), point.size()), 0); -#else +#elif NCRYPTO_USE_BORINGSSL EXPECT_FALSE(raw_public); #endif EXPECT_FALSE( @@ -463,7 +463,7 @@ TEST(NodeCrypto, ResolveKeyAlgorithm) { key.reset(); EXPECT_EQ(key.getAlgorithm(), nullptr); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Legacy keys must resolve even without provider-backed key material. key = EVPKeyPointer::New(); ASSERT_EQ(EVP_PKEY_set_type(key.get(), NID_rsaEncryption), 1); @@ -487,7 +487,7 @@ TEST(NodeCrypto, PublicKeyTypeNames) { EXPECT_STREQ(key.getKeyTypeName(), "ed25519"); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER TEST(NodeCrypto, LegacyKeyAlgorithmResolution) { ncrypto::ClearErrorOnReturn clear_errors; auto key = EVPKeyPointer::New(); @@ -533,7 +533,7 @@ TEST(NodeCrypto, EcGroupNames) { } } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { // Deliberately longer than the fixed-size group buffer formerly used by // ncrypto. @@ -723,7 +723,7 @@ TEST(NodeCrypto, NamedRawKey) { EXPECT_TRUE(key.supportsRawPublic()); EXPECT_TRUE(key.supportsRawPrivate()); EXPECT_EQ(key.getAlgorithm()->seedSize(), 0); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // Provider aliases are recognized without comparing the primary type name. EXPECT_TRUE(key.isA("1.3.101.112")); auto ctx = ncrypto::EVPKeyCtxPointer::NewFromName("1.3.101.112"); @@ -778,7 +778,7 @@ TEST(NodeCrypto, ProviderPqcKeyWithoutLegacyId) { algorithm->seedSize()}; auto key = EVPKeyPointer::NewRawSeed(*algorithm, input); ASSERT_TRUE(key); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EXPECT_EQ(EVP_PKEY_id(key.get()), -1); #endif EXPECT_TRUE(key.isA(*algorithm)); @@ -855,7 +855,7 @@ TEST(NodeCrypto, UnavailableBoringSSLKeyAlgorithms) { } #endif -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER TEST(NodeCrypto, PrivateKeyEncodingOwnsFetchedCipher) { ncrypto::ClearErrorOnReturn clear_errors; EVPKeyPointer::PrivateKeyEncodingConfig assigned; diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index fddf584d7d4..1d31dc98329 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 a592c7b84bf9c9dbc2f71bca3ef13138591bb18a 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, including the shared PKCS12 parser and TLS PFX error handling. Gate BoringSSL-only alternatives explicitly instead of leaving them in #else branches, including the MAC/KMAC and OCB fallbacks. Fix the BoringSSL guard on QUIC's unsupported-backend diagnostic. Keep the provider activation and deferred DRBG initialization in startup, without the obsolete OpenSSL 1.x fallback. 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_aes.h | 2 +- src/crypto/crypto_cipher.cc | 4 ++-- src/crypto/crypto_context.cc | 26 +++++++++++++------------- src/crypto/crypto_context.h | 6 +++--- src/crypto/crypto_dh.cc | 16 +++------------- src/crypto/crypto_hash.cc | 12 ++++++------ src/crypto/crypto_kem.h | 6 +++--- src/crypto/crypto_keys.cc | 4 ++-- src/crypto/crypto_kmac.h | 2 +- src/crypto/crypto_mac.cc | 12 ++++++------ src/crypto/crypto_mac.h | 2 +- src/crypto/crypto_pkcs12.cc | 4 ++-- src/crypto/crypto_rsa.cc | 12 +++++------- src/crypto/crypto_tls.cc | 14 +++++++------- src/crypto/crypto_tls.h | 2 +- src/crypto/crypto_util.cc | 16 +++------------- src/node.cc | 16 ++++------------ src/node_constants.cc | 4 ++-- src/node_constants.h | 2 +- src/node_crypto.cc | 2 +- src/node_metadata.cc | 2 +- src/node_options.cc | 6 +++--- src/node_options.h | 2 +- src/quic/tlscontext.h | 2 +- 26 files changed, 77 insertions(+), 110 deletions(-) diff --git a/src/crypto/README.md b/src/crypto/README.md index 1655fc5ea0f..63f14030697 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -93,8 +93,8 @@ use their methods to keep that adaptation inside ncrypto. 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 ea869a8eef1..070c05582ee 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -150,11 +150,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_aes.h b/src/crypto/crypto_aes.h index 6b18b1e29e2..bea409da94a 100644 --- a/src/crypto/crypto_aes.h +++ b/src/crypto/crypto_aes.h @@ -43,7 +43,7 @@ constexpr unsigned kNoAuthTagLength = static_cast(-1); V(OCB_128, AES_Cipher, ncrypto::Cipher::AES_128_OCB()) \ V(OCB_192, AES_Cipher, ncrypto::Cipher::AES_192_OCB()) \ V(OCB_256, AES_Cipher, ncrypto::Cipher::AES_256_OCB()) -#else +#elif defined(OPENSSL_IS_BORINGSSL) #define VARIANTS_OCB(V) #endif diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 348d96e6043..f28ecdae965 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 72a86e82672..488483f0c87 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -1607,7 +1607,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 @@ -1626,9 +1626,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_))) { @@ -1638,7 +1638,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { #if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(sc->ctx_.get(), TicketCompatibilityCallback); -#else +#elif NCRYPTO_USE_BORINGSSL SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback); #endif } @@ -1950,7 +1950,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { #if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer params(PEM_read_bio_Parameters(bio.get(), nullptr)); if (params && params.isA(KeyAlgorithm::DH)) dh.reset(params.release()); -#else +#elif NCRYPTO_USE_BORINGSSL dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr)); #endif } @@ -1974,7 +1974,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { #if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer dh_pkey(dh.release()); if (!SSL_CTX_set0_tmp_dh_pkey(sc->ctx_.get(), dh_pkey.get())) { -#else +#elif NCRYPTO_USE_BORINGSSL if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) { #endif return THROW_ERR_CRYPTO_OPERATION_FAILED( @@ -2188,12 +2188,12 @@ void SecureContext::Close(const FunctionCallbackInfo& args) { namespace { // The historical error shape for the TLS `pfx` option: the OpenSSL reason -// string, except for OpenSSL 3's bare "unsupported" error, which on its own +// string, except for OpenSSL's bare "unsupported" error, which on its own // says nothing useful. // TODO(@jasnell): Should this use ThrowCryptoError? // NOLINTNEXTLINE(runtime/int) -- matches ERR_get_error() void ThrowPFXError(Environment* env, unsigned long err) { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION( env, "Unsupported PKCS12 PFX data"); @@ -2372,7 +2372,7 @@ void SecureContext::EnableTicketKeyCallback( #if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(wrap->ctx_.get(), TicketKeyCallback); -#else +#elif NCRYPTO_USE_BORINGSSL SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback); #endif } @@ -2391,7 +2391,7 @@ bool InitTicketHmac(EVP_MAC_CTX* hctx, }; return EVP_MAC_init(hctx, key, key_len, params) == 1; } -#else +#elif NCRYPTO_USE_BORINGSSL bool InitTicketHmac(HMAC_CTX* hctx, const unsigned char* key, size_t key_len) { return HMAC_Init_ex(hctx, key, key_len, Digest::SHA256, nullptr) == 1; } @@ -2404,7 +2404,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl, EVP_CIPHER_CTX* ectx, #if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, -#else +#elif NCRYPTO_USE_BORINGSSL HMAC_CTX* hctx, #endif int enc) { @@ -2501,7 +2501,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl, EVP_CIPHER_CTX* ectx, #if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, -#else +#elif NCRYPTO_USE_BORINGSSL HMAC_CTX* hctx, #endif int enc) { diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 86634007984..3de8e0703e5 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); @@ -160,7 +160,7 @@ class SecureContext final : public BaseObject { EVP_CIPHER_CTX* ectx, #if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, -#else +#elif NCRYPTO_USE_BORINGSSL HMAC_CTX* hctx, #endif int enc); @@ -171,7 +171,7 @@ class SecureContext final : public BaseObject { EVP_CIPHER_CTX* ectx, #if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, -#else +#elif NCRYPTO_USE_BORINGSSL HMAC_CTX* hctx, #endif int enc); diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 8bfde65327f..a65cc2e12e5 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -81,20 +81,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 @@ -123,12 +117,8 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) PutBnError(BN_R_BITS_TOO_SMALL); #endif // OPENSSL_IS_BORINGSSL return ThrowCryptoError(env, ERR_get_error(), "Invalid prime length"); diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 6c3e7efc672..bd4a3737d80 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -226,7 +226,7 @@ void SaveSupportedProviderHashAlgorithms(EVP_MD* md, void* arg) { EVP_MD_names_do_all(md, SaveSupportedProviderHashName, &context); } -#else +#elif NCRYPTO_USE_BORINGSSL void SaveSupportedHashAlgorithms(const EVP_MD* md, const char* from, const char* to, @@ -253,7 +253,7 @@ const std::vector& GetSupportedHashAlgorithms(Environment* env) { // later lookups instead of throwing them away immediately. EVP_MD_do_all_sorted(SaveSupportedHashAlgorithmsAndCacheMD, env); EVP_MD_do_all_provided(nullptr, SaveSupportedProviderHashAlgorithms, env); -#else +#elif NCRYPTO_USE_BORINGSSL EVP_MD_do_all_sorted(SaveSupportedHashAlgorithms, env); #endif } @@ -345,7 +345,7 @@ const EVP_MD* GetDigestImplementation( return digest_owner->get(); } return nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL Utf8Value utf8(env->isolate(), algorithm); return ncrypto::getDigestByName(*utf8); #endif @@ -354,7 +354,7 @@ const EVP_MD* GetDigestImplementation( void MarkInvalidXofLength() { #if NCRYPTO_USE_OPENSSL_PROVIDER ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH); -#else +#elif NCRYPTO_USE_BORINGSSL EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH); #endif } @@ -369,7 +369,7 @@ void MarkInvalidXofLength() { bool IsShakeDigest(const EVP_MD* md) { #if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_MD_is_a(md, "SHAKE128") || EVP_MD_is_a(md, "SHAKE256"); -#else +#elif NCRYPTO_USE_BORINGSSL const char* name = OBJ_nid2sn(EVP_MD_type(md)); return name != nullptr && (strcmp(name, "SHAKE128") == 0 || strcmp(name, "SHAKE256") == 0); @@ -540,7 +540,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo& args) { } if (env->isolate()->HasPendingException()) return; } -#else +#elif NCRYPTO_USE_BORINGSSL Utf8Value utf8(env->isolate(), args[0]); return OneShotDigestWithMD( env, args, ncrypto::getDigestByName(*utf8), nullptr); diff --git a/src/crypto/crypto_kem.h b/src/crypto/crypto_kem.h index dc60001e2d1..bdc99499204 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 d7aef2b5d08..b2a789cc602 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -1325,9 +1325,9 @@ 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 +#elif defined(OPENSSL_IS_BORINGSSL) int ok = EVP_PKEY_cmp(pkey, pkey2); #endif if (ok == -2) { diff --git a/src/crypto/crypto_kmac.h b/src/crypto/crypto_kmac.h index 4f8fe27d2ff..7698a0dfaa1 100644 --- a/src/crypto/crypto_kmac.h +++ b/src/crypto/crypto_kmac.h @@ -64,7 +64,7 @@ void Initialize(Environment* env, v8::Local target); void RegisterExternalReferences(ExternalReferenceRegistry* registry); } // namespace Kmac -#else +#elif defined(OPENSSL_IS_BORINGSSL) // If there is no KMAC support, provide empty namespace functions. namespace Kmac { void Initialize(Environment* env, v8::Local target) {} diff --git a/src/crypto/crypto_mac.cc b/src/crypto/crypto_mac.cc index 7f43e760ccf..ba34211275f 100644 --- a/src/crypto/crypto_mac.cc +++ b/src/crypto/crypto_mac.cc @@ -522,7 +522,7 @@ Mac::Mac(Environment* env, has_output_length_(has_output_length) { MakeWeak(); } -#else +#elif defined(OPENSSL_IS_BORINGSSL) Mac::Mac(Environment* env, Local wrap) : BaseObject(env, wrap) { MakeWeak(); } @@ -531,7 +531,7 @@ Mac::Mac(Environment* env, Local wrap) : BaseObject(env, wrap) { void Mac::MemoryInfo(MemoryTracker* tracker) const { #if OPENSSL_WITH_EVP_MAC tracker->TrackFieldWithSize("context", context_ ? kSizeOf_EVP_MAC_CTX : 0); -#else +#elif defined(OPENSSL_IS_BORINGSSL) static_cast(tracker); #endif } @@ -570,7 +570,7 @@ void Mac::New(const FunctionCallbackInfo& args) { std::move(initialized.context), initialized.output_size, initialized.has_output_length); -#else +#elif defined(OPENSSL_IS_BORINGSSL) THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args), "MAC is not supported"); #endif @@ -585,7 +585,7 @@ void Mac::MacUpdate(const FunctionCallbackInfo& args) { size_t length) { args.GetReturnValue().Set(mac->MacUpdate(data, length)); }); -#else +#elif defined(OPENSSL_IS_BORINGSSL) THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args), "MAC is not supported"); #endif @@ -613,7 +613,7 @@ void Mac::MacFinal(const FunctionCallbackInfo& args) { .ToLocal(&result)) { args.GetReturnValue().Set(result); } -#else +#elif defined(OPENSSL_IS_BORINGSSL) THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args), "MAC is not supported"); #endif @@ -627,7 +627,7 @@ void Mac::GetMacs(const FunctionCallbackInfo& args) { if (ToV8Value(context, GetSupportedMacAlgorithms(env)).ToLocal(&result)) { args.GetReturnValue().Set(result); } -#else +#elif defined(OPENSSL_IS_BORINGSSL) args.GetReturnValue().Set(Array::New(args.GetIsolate(), 0)); #endif } diff --git a/src/crypto/crypto_mac.h b/src/crypto/crypto_mac.h index 3223b148710..4da9dcef2dc 100644 --- a/src/crypto/crypto_mac.h +++ b/src/crypto/crypto_mac.h @@ -39,7 +39,7 @@ class Mac final : public BaseObject { ncrypto::EVPMacCtxPointer context_; size_t output_size_ = 0; bool has_output_length_ = false; -#else +#elif defined(OPENSSL_IS_BORINGSSL) Mac(Environment* env, v8::Local wrap); #endif }; diff --git a/src/crypto/crypto_pkcs12.cc b/src/crypto/crypto_pkcs12.cc index 8b0af44d9d7..b4e909b2629 100644 --- a/src/crypto/crypto_pkcs12.cc +++ b/src/crypto/crypto_pkcs12.cc @@ -60,8 +60,8 @@ PKCS12ParseResult ParsePKCS12Bundle(const BIOPointer& bio, const char* pass) { return PKCS12ParseResult(PKCS12ParseError::NOT_RECOGNIZED, err); } #endif -#if OPENSSL_VERSION_MAJOR >= 3 - // OpenSSL 3 reports algorithms that moved to the legacy provider as a +#ifndef OPENSSL_IS_BORINGSSL + // OpenSSL reports algorithms that moved to the legacy provider as a // bare "unsupported" error. if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { return PKCS12ParseResult(PKCS12ParseError::UNSUPPORTED_ALGORITHM, err); diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index 817929b8955..7bf4ef5597a 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -50,7 +50,7 @@ bool IsRsaPssDigestEncodable(const Digest& digest) { const ASN1_OBJECT* object = OBJ_nid2obj(nid); return object != nullptr && OBJ_length(object) > 0; -#else +#elif NCRYPTO_USE_BORINGSSL static_cast(digest); return true; #endif @@ -82,10 +82,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; @@ -399,7 +397,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { #if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::Rsa rsa_view; -#else +#elif NCRYPTO_USE_BORINGSSL RSAPointer rsa(RSA_new()); if (!rsa) { THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Unable to create RSA pointer"); @@ -513,7 +511,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { #if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = EVPKeyPointer::NewRSA(rsa_view); -#else +#elif NCRYPTO_USE_BORINGSSL auto pkey = EVPKeyPointer::NewRSA(std::move(rsa)); #endif if (!pkey) { diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index e1c147f56bc..97f56e6e613 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -111,7 +111,7 @@ int VerifyCertChain(X509_STORE_CTX* ctx, void*) { // 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 @@ -573,9 +573,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); @@ -707,8 +707,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);"); @@ -954,7 +954,7 @@ void TLSWrap::ClearOut() { const char* ls = ERR_lib_error_string(ssl_err); #if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL const char* fs = ERR_func_error_string(ssl_err); #endif const char* rs = ERR_reason_error_string(ssl_err); diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index ab602401887..f3e0dfff9bc 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -155,7 +155,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 b980a578721..8dd7a14e205 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 @@ -451,7 +451,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, @@ -505,15 +505,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"); @@ -521,7 +512,6 @@ void InitCryptoOnce() { fprintf(stderr, "Unable to load legacy provider.\n"); } } -#endif OPENSSL_init_ssl(0, settings); InstallFipsIndicatorCallback(); @@ -901,7 +891,7 @@ Maybe Decorate(Environment* env, const char* ls = ERR_lib_error_string(err); #if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; -#else +#elif NCRYPTO_USE_BORINGSSL const char* fs = ERR_func_error_string(err); #endif const char* rs = ERR_reason_error_string(err); diff --git a/src/node.cc b/src/node.cc index 2993fda0e9c..01c09349828 100644 --- a/src/node.cc +++ b/src/node.cc @@ -49,11 +49,11 @@ #if HAVE_OPENSSL #include "ncrypto.h" -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include #endif #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 @@ -1223,7 +1223,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( @@ -1239,6 +1238,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. @@ -1295,11 +1295,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; @@ -1315,12 +1311,8 @@ InitializeOncePerProcessInternal(const std::vector& args, // configuration without a DRBG still aborts at startup instead of // hanging at the first crypto call. Otherwise the DRBG is instantiated // on first use. -#if OPENSSL_VERSION_MAJOR >= 3 const bool check_csprng = ncrypto::isFipsEnabled() || !OSSL_PROVIDER_available(nullptr, "default"); -#else - const bool check_csprng = true; -#endif if (check_csprng) { CHECK(ncrypto::CSPRNG(nullptr, 0)); } diff --git a/src/node_constants.cc b/src/node_constants.cc index bd3b66414d1..cce1903f1c8 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 97429c0e5e9..115de09587d 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_crypto.cc b/src/node_crypto.cc index 99cb556ecd9..9b096ac8437 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -77,7 +77,7 @@ namespace crypto { #if OPENSSL_WITH_EVP_MAC #define KMAC_NAMESPACE_LIST(V) V(Kmac) -#else +#elif defined(OPENSSL_IS_BORINGSSL) #define KMAC_NAMESPACE_LIST(V) #endif // OPENSSL_WITH_EVP_MAC diff --git a/src/node_metadata.cc b/src/node_metadata.cc index b91b1b48814..68daae837fc 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 692ac3b6240..92f52340f0b 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1650,9 +1650,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", @@ -1660,7 +1660,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 9f31af1cb1b..c3c4e1949c6 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -437,7 +437,7 @@ class PerProcessOptions : public Options { DEFINE_BOOL_FIELD(force_fips_crypto) = false; std::string force_fips_crypto_policy = "provider"; #endif // HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) DEFINE_BOOL_FIELD(openssl_legacy_provider) = false; DEFINE_BOOL_FIELD(openssl_shared_config) = false; #endif diff --git a/src/quic/tlscontext.h b/src/quic/tlscontext.h index 8209eda12db..ecadc1fa78d 100644 --- a/src/quic/tlscontext.h +++ b/src/quic/tlscontext.h @@ -21,7 +21,7 @@ namespace node::quic { class Session; class TLSContext; -#if OPENSSL_IS_BORING +#ifdef OPENSSL_IS_BORINGSSL static_assert(false, "This implementation of tlscontext relies on OpenSSL APIS " "that are not available in BoringSSL. An alternative impl " From 8c7cca118c5d6c85e0809ef3003ecfcad9512623 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, including PKCS12 parsing, named DH groups, private-key serialization, RSA-PSS parameters, consolidated provider caches, FIPS availability, and empty KMAC output. 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-curves.js | 12 +--- test/parallel/test-crypto-dh-errors.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 +- ...est-crypto-key-encoding-provider-cipher.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/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/parallel/test-crypto-pkcs12.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 +-- .../test-crypto-provider-cache-snapshot.js | 6 +- test/parallel/test-crypto-provider-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-crypto-rsa-multiprime-jwk.js | 4 +- .../test-crypto-rsa-pss-parameters.js | 6 +- 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 | 17 +---- 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-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-kmac-empty-output.js | 6 +- .../test-webcrypto-sign-verify-kmac.js | 6 +- test/parallel/test-webcrypto-sign-verify.js | 2 +- test/parallel/test-webcrypto-supports-fips.js | 4 +- 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 | 8 +-- test/wpt/status/WebCryptoAPI.cjs | 2 +- 103 files changed, 341 insertions(+), 609 deletions(-) delete mode 100644 test/parallel/test-crypto-ecb.js diff --git a/benchmark/crypto/kem.js b/benchmark/crypto/kem.js index 34374dfc849..05e640e1f5b 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 ea9d3a56e59..a6ff89f22ea 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 785a103bb6c..36f8de59ccd 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 7e7a958b900..08cab0d4687 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 1d31dc98329..4c349ac1a0a 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 49678e0de43..80a22c89aa1 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 8d58397783e..5e87c3f7c56 100644 --- a/test/fixtures/webcrypto/supports-modern-algorithms.mjs +++ b/test/fixtures/webcrypto/supports-modern-algorithms.mjs @@ -14,8 +14,8 @@ const shake256 = crypto.getHashes().includes('shake256'); const cshake128 = crypto.getHashes().includes('cshake128'); const cshake256 = crypto.getHashes().includes('cshake256'); const sha3 = crypto.getHashes().includes('sha3-256'); -const ocb = hasOpenSSL(3) && crypto.getCiphers().includes('aes-128-ocb'); -const kmac = hasOpenSSL(3) && crypto.getMacs().includes('kmac128'); +const ocb = !isBoringSSL && crypto.getCiphers().includes('aes-128-ocb'); +const kmac = !isBoringSSL && crypto.getMacs().includes('kmac128'); const hybridKems = !fips && pqc && (!boringSSL || (sha3 && shake256)); diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index 375c46c11ab..fa290d23c96 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 08973bd17ee..ad8818c3cd9 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 a60dc73d67b..f4c754d118f 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 f321bb0105f..a6565aba077 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -819,7 +819,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 d2c216924ea..ab429ecb1d3 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 48d68c93fb6..e875f706110 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-curves.js b/test/parallel/test-crypto-dh-curves.js index 22b05fb8960..e9e93cb63b7 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 d9f7065655c..d697a72a09f 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-odd-key.js b/test/parallel/test-crypto-dh-odd-key.js index c96227770e3..32d83fe0d4f 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 9c0270304f2..d1e134aa4a1 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 7b9a9d50d89..5ef9450b86a 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 65c373d35d2..00000000000 --- 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 199ad68fa36..50a44f91051 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 5e003d7015b..b1024fc5235 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 faf45c766c5..8e707690355 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 7051c2fae07..88be6098725 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(), { @@ -142,9 +142,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); @@ -233,7 +230,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 1e19b3e972d..116daa5f311 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 ee9bd27bba6..06cb3c93b14 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-encoding-provider-cipher.js b/test/parallel/test-crypto-key-encoding-provider-cipher.js index 3ded8ed0a62..3f2c3dafd97 100644 --- a/test/parallel/test-crypto-key-encoding-provider-cipher.js +++ b/test/parallel/test-crypto-key-encoding-provider-cipher.js @@ -4,8 +4,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasFIPS, hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (isBoringSSL || !hasOpenSSL(3)) +const { hasFIPS, isBoringSSL } = require('../common/crypto'); +if (isBoringSSL) common.skip('OpenSSL providers are required'); const assert = require('assert'); diff --git a/test/parallel/test-crypto-key-objects.js b/test/parallel/test-crypto-key-objects.js index 97810af5d9c..759f2af4399 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 0fec81a9c64..659d1836ba5 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 d5636f350dc..8c8032cb5fb 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 52c82ea5725..9527383692a 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 5d0254491cd..884b4eca7db 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 cd7e59be97f..b876596df61 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 5c0878fc634..f79b92eeae2 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 ba86fcdb94e..545190bbc48 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 84ea9d2f7a9..82f8705a280 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 7a372ded9fc..19f83bc3882 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 90d32cd73bc..2c37ef18798 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 ccf98bcd376..9f2fc9b55c8 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 afe95dbee40..6fd81184480 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 a68c7c07c93..37cb2629419 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-errors.js b/test/parallel/test-crypto-mac-errors.js index 8bc8cebfcf5..7326ee88e95 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 1721e9d1c1a..84fa4299667 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 19544ccf4ec..7e965f78618 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 deb2a8a3d32..267eea0e1ad 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 0e9525fcaf6..8bf5d305a2f 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 0354aad8b0b..eb4b0291464 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 dce34409400..7ad837c64b2 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 7cd1206f4f0..b583ae80ef8 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-pkcs12.js b/test/parallel/test-crypto-pkcs12.js index 0ec9a2f544d..1e65bf20a45 100644 --- a/test/parallel/test-crypto-pkcs12.js +++ b/test/parallel/test-crypto-pkcs12.js @@ -5,7 +5,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const crypto = require('crypto'); const fixtures = require('../common/fixtures'); -const { hasOpenSSL3, hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const fips3 = hasFIPS(3); @@ -140,7 +140,7 @@ if (!fips3) { assert.ok(additionalCertificates[0] instanceof crypto.X509Certificate); } -if (hasOpenSSL3) { +if (!isBoringSSL) { // Legacy algorithms (RC2-40-CBC) throw a recognizable, actionable error // rather than a bare OpenSSL string. Mirrors the behavior added for the // TLS path in https://github.com/nodejs/node/pull/54485. 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 cd8f8c926f5..1fb0fa19f08 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 d08a479f421..7ae706af400 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 eff309468c3..090aa65f9dc 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 6f43e3a0bfb..0831aee23e4 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 a38fcba6775..1e6c2d7626f 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-cache-snapshot.js b/test/parallel/test-crypto-provider-cache-snapshot.js index 522dedfc436..c6a06887512 100644 --- a/test/parallel/test-crypto-provider-cache-snapshot.js +++ b/test/parallel/test-crypto-provider-cache-snapshot.js @@ -5,13 +5,13 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('node:assert'); -const { hasOpenSSL, isBoringSSL } = 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) || isBoringSSL) - common.skip('this test requires OpenSSL 3.x'); +if (isBoringSSL) + common.skip('OpenSSL provider support is required'); const entry = fixtures.path('snapshot', 'crypto-provider-cache.js'); const buildEnv = { diff --git a/test/parallel/test-crypto-provider-cache.js b/test/parallel/test-crypto-provider-cache.js index bbfee76b615..2d57b63e523 100644 --- a/test/parallel/test-crypto-provider-cache.js +++ b/test/parallel/test-crypto-provider-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 provider support'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL) + common.skip('this test requires OpenSSL provider support'); const assert = require('node:assert'); const crypto = require('node:crypto'); diff --git a/test/parallel/test-crypto-provider-hash-options.js b/test/parallel/test-crypto-provider-hash-options.js index ecccc02f01e..997b179413a 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 5e688303910..8953e2afa51 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 21cc5f3ebce..297a6c24a3d 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 6e47d2a1865..e050796e856 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 @@ -40,34 +38,25 @@ const dsaPkcs8KeyPem = fixtures.readKey('dsa_private_pkcs8.pem'); const ec = new TextEncoder(); -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); @@ -168,10 +157,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({ @@ -541,21 +528,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-rsa-multiprime-jwk.js b/test/parallel/test-crypto-rsa-multiprime-jwk.js index be434c76e82..10b25a90f03 100644 --- a/test/parallel/test-crypto-rsa-multiprime-jwk.js +++ b/test/parallel/test-crypto-rsa-multiprime-jwk.js @@ -6,13 +6,13 @@ if (!common.hasCrypto) const assert = require('assert'); const fixtures = require('../common/fixtures'); -const { hasFIPS } = require('../common/crypto'); +const { hasFIPS, isBoringSSL } = require('../common/crypto'); const { createPrivateKey, } = require('crypto'); const { subtle } = globalThis.crypto; -if (process.features.openssl_is_boringssl) +if (isBoringSSL) common.skip('multi-prime RSA is not available with BoringSSL'); if (hasFIPS()) common.skip('multi-prime RSA is not available in FIPS mode'); diff --git a/test/parallel/test-crypto-rsa-pss-parameters.js b/test/parallel/test-crypto-rsa-pss-parameters.js index cda01e7a16d..8cc802beec8 100644 --- a/test/parallel/test-crypto-rsa-pss-parameters.js +++ b/test/parallel/test-crypto-rsa-pss-parameters.js @@ -2,9 +2,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) - common.skip('requires OpenSSL 3 provider support'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL) + common.skip('requires OpenSSL provider support'); const assert = require('assert'); const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-crypto-sec-level.js b/test/parallel/test-crypto-sec-level.js index ff32b29bb2b..d4459bc5b75 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 3c79d1bb8a6..71d1175aba1 100644 --- a/test/parallel/test-crypto-secure-heap.js +++ b/test/parallel/test-crypto-secure-heap.js @@ -19,7 +19,6 @@ if (common.hasV8Sandbox) { const { isBoringSSL, - hasOpenSSL, hasFIPS, } = require('../common/crypto'); @@ -33,7 +32,6 @@ const fixtures = require('../common/fixtures'); const { secureHeapUsed, createDiffieHellman, - getFips, } = require('crypto'); if (process.argv[2] === 'child') { @@ -47,8 +45,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 4b874a7e43f..cb02c4ffd33 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 9584e48f2cb..8abaf4b8a73 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 c8f44372f97..4b3834aeeec 100644 --- a/test/parallel/test-crypto-x509.js +++ b/test/parallel/test-crypto-x509.js @@ -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( @@ -414,7 +403,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 3e431c788c6..257c405324c 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 0d7366dd343..2ad900cbf35 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 c4edc5b33db..cd82fb0cbb7 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 ec1b8dda8ca..c9096c570fc 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 f97657051ca..08913fb047f 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 f5aeec01796..910fec097b6 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 420625b01f5..9cb122448ed 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 1b80571e70e..ee1a77c2aa2 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 973e9fad32e..5cbc6cdef5b 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 f08be448dd1..c15ab7e28ee 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 33e74af13ed..b69ddd126e5 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 6f54bbd9766..cad14df5529 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 08c2d39c684..a90fbc60c9b 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 8f60ef0520c..fa26419fe5b 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 77f9c093502..2f3339196f4 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 932ad7f0f21..27017bb9baf 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 57fb3599112..f54e79dcb13 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 4d1a8165277..6c3d144f8ab 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 53db81496b2..7df489b48df 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); @@ -56,7 +56,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 4ef6cbd8d9b..1a1ff8da94b 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) { @@ -178,7 +178,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( @@ -203,7 +203,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) { @@ -374,7 +374,7 @@ function assertSameSet(actual, expected, msg) { })()); // AES-OCB raw-secret import. - if (hasOpenSSL(3)) { + if (!isBoringSSL) { tests.push((async () => { const imported = subtle.importKey( 'raw-secret', @@ -393,7 +393,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()); @@ -469,7 +469,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'], @@ -481,7 +481,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 4fb372fd3a8..ae8a6bf686c 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, hasFIPS, isBoringSSL } = require('../common/crypto'); +const { hasFIPS, 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 318ca8d2500..2148e20d838 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)) { +if (!isBoringSSL) { (async () => { const derivedKeyAlgorithm = { name: 'KMAC128', length: 0 }; const usages = ['sign']; diff --git a/test/parallel/test-webcrypto-encrypt-decrypt-aes.js b/test/parallel/test-webcrypto-encrypt-decrypt-aes.js index bdf1a1d6666..0789f71cdd7 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 0f3341db64b..1a7c4c946d2 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)); @@ -217,5 +217,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 63fdde05f1e..6c372241996 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 999e70df6a6..b51363b79ce 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 { hasOpenSSL } = require('../common/crypto'); +const { 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 b1fc8f41b2a..62df1be1956 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-kmac-empty-output.js b/test/parallel/test-webcrypto-kmac-empty-output.js index fe88f7ab769..a1783ec64d4 100644 --- a/test/parallel/test-webcrypto-kmac-empty-output.js +++ b/test/parallel/test-webcrypto-kmac-empty-output.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'); if (hasFIPS()) common.skip('empty KMAC output is not supported in FIPS mode'); diff --git a/test/parallel/test-webcrypto-sign-verify-kmac.js b/test/parallel/test-webcrypto-sign-verify-kmac.js index 5829ab3685c..312431b4f06 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 { hasOpenSSL } = require('../common/crypto'); +const { 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 295f1378238..70148ee28ae 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-supports-fips.js b/test/parallel/test-webcrypto-supports-fips.js index e08551c65f3..470c776933e 100644 --- a/test/parallel/test-webcrypto-supports-fips.js +++ b/test/parallel/test-webcrypto-supports-fips.js @@ -3,8 +3,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL, isBoringSSL } = require('../common/crypto'); -if (!hasOpenSSL(3) || isBoringSSL) common.skip('requires OpenSSL 3'); +const { isBoringSSL } = require('../common/crypto'); +if (isBoringSSL) common.skip('requires an OpenSSL provider'); const assert = require('node:assert'); const crypto = require('node:crypto'); diff --git a/test/parallel/test-webcrypto-wrap-unwrap.js b/test/parallel/test-webcrypto-wrap-unwrap.js index 1f8d45f02c2..46ba12c2d12 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: { @@ -484,7 +484,7 @@ async function testNonByteLengthWrapUnwrap({ implicitAlgorithm: hmacAlgorithm, }); - if (hasOpenSSL(3) && getFips() !== 1) { + if (!isBoringSSL && getFips() !== 1) { for (const name of ['KMAC128', 'KMAC256']) { const keyData = new Uint8Array(32).fill(0xff); const kmacKey = await subtle.importKey( diff --git a/test/parallel/test-x509-escaping.js b/test/parallel/test-x509-escaping.js index 47901140cac..e33d1372663 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 e428df491a3..f61fd5bf3ea 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 8a2e71745a3..b5a1995ffef 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 iterations = 2000; if (hasFIPS(3)) { @@ -46,11 +46,11 @@ if (hasFIPS(3)) { } let createDH; -if (hasOpenSSL(3)) { - // OpenSSL 3 recognizes named groups without validating their primes. +if (!isBoringSSL) { + // OpenSSL recognizes named groups without validating their primes. createDH = () => crypto.getDiffieHellman('modp14'); } else { - // Other backends validate each peer's parameters, so keep them small. + // BoringSSL validates each peer's parameters, so keep them small. const length = crypto.getFips() === 1 ? 1024 : 256; const prime = crypto.createDiffieHellman(length).getPrime(); createDH = () => crypto.createDiffieHellman(prime); diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index ff618016f3d..37f8bb3935a 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 9ba09bd7af2d8687f047a738c7c3c3f46b16bea3 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. Document BoringSSL as the only backend with numeric key adapters. 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 ++--- src/crypto/README.md | 5 +-- 7 files changed, 64 insertions(+), 78 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index f3cc2ee7e1a..a753b289514 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1015,9 +1015,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` @@ -2468,8 +2467,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. @@ -2481,7 +2479,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 cafb38391b7..298c6a1a041 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3743,8 +3743,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][] @@ -3848,8 +3848,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][] @@ -4492,7 +4492,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) @@ -4564,7 +4564,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) @@ -5191,11 +5191,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()` @@ -5213,10 +5212,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 @@ -6637,11 +6635,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 @@ -6660,8 +6657,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])` @@ -7128,7 +7124,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: @@ -7164,8 +7160,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 @@ -7187,7 +7183,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: @@ -7224,13 +7220,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. @@ -7239,7 +7233,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 @@ -7304,8 +7298,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 @@ -7313,22 +7307,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. @@ -7609,7 +7600,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 @@ -7656,7 +7647,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 7df2ab93860..5dfcf5069a8 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 609ebf00379..5f0f676cb48 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] @@ -2768,7 +2768,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 07d4ac4a64e..f0b933d19f2 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -512,7 +512,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 1f97de57033..540f36bf4cb 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -577,9 +577,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 @@ -1236,12 +1235,11 @@ usually only useful for developers debugging Node.js itself. . .It Fl -openssl-config Ns = Ns Ar file Load an OpenSSL configuration file on startup. The file can activate an -OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See -FIPS mode. +OpenSSL FIPS provider. See FIPS mode. This option takes precedence over the \fBOPENSSL_CONF\fR environment variable. . .It Fl -openssl-legacy-provider -Enable OpenSSL 3.0 legacy provider. For more information please see +Enable OpenSSL's legacy provider. For more information please see OSSL_PROVIDER-legacy. . .It Fl -openssl-shared-config diff --git a/src/crypto/README.md b/src/crypto/README.md index 63f14030697..3d561f712e0 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -158,10 +158,9 @@ callers can retain descriptor pointers across asynchronous jobs. For example, `ML-DSA-44`. For an existing key, use `key.isA(KeyAlgorithm::RSA_PSS)` or another descriptor. -On OpenSSL 3 and later this uses `EVP_PKEY_is_a()` to recognize provider aliases. +On OpenSSL this uses `EVP_PKEY_is_a()` to recognize provider aliases. Numeric key IDs are unsuitable for provider-only keys: OpenSSL can return `-1` -for their ID. Numeric adapters for BoringSSL and legacy OpenSSL stay private to -ncrypto. +for their ID. Numeric adapters for BoringSSL stay private to ncrypto. When a function needs algorithm metadata, use `key.getAlgorithm()`. It returns a pointer to a static descriptor, or `nullptr` for an empty key or an unrecognized From 88b76fb6927ce0f57d3388317c8e86b8323bad2f 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 253c6906e3f..00000000000 --- 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 79733c657a9..00000000000 --- 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 ad67ec181c7..2ff8e2325b3 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 3df51bfbed3..43ac7e22ced 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 10862c1b160..bd79303829b 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 90df2cfb2fa..c4e0d239a58 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1464,7 +1464,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", @@ -1628,14 +1628,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 849f29f6e30b51f1a6870b1d4225a90542f5d632 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 c7dbaa1413e..618390d17db 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1019,14 +1019,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 c93de65fa35..d879c02ff14 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', @@ -2313,7 +2314,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 @@ -2368,12 +2368,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 144085fd33d..d11f72a758d 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 7ad2d95ef9e..8a537337202 100644 --- a/node.gyp +++ b/node.gyp @@ -768,87 +768,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 7245d9130d0..2de1ee244dd 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 cb24c7d83b6..00000000000 --- 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 5651b391b88..e85f1a815a8 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 f83d2a7172018a8fa5941af6c25f5a5e0dad17fc 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 298c6a1a041..c95a11d47cf 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -4577,18 +4577,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 3e720cd3bdf..4261097b52b 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -352,13 +352,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 ff063e018d0..83a0367bde0 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 3d5127197f14f5ca67fdfb845bf0af88f3022cf5 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 c95a11d47cf..a35ac905ec1 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -6578,9 +6578,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 90a11b4fbc9..fe35f2b2e56 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 eba303b6600..74b759556c4 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 11292b60b5d..e02a22404c2 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -911,9 +911,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. @@ -930,13 +929,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` @@ -4811,7 +4803,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 74b759556c4..c4a95ee6749 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -427,6 +427,10 @@ a `timeout` of 5 seconds.