diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml index bcf70cd6a92a..6e10cf953387 100644 --- a/.github/workflows/test-shared.yml +++ b/.github/workflows/test-shared.yml @@ -260,8 +260,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 8c7407b96274..e66d19746174 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -205,7 +205,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, @@ -213,8 +213,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 @@ -222,7 +220,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. @@ -1028,14 +1026,20 @@ using the following configure option: ## Building Node.js with FIPS-compliant OpenSSL -Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via -[OpenSSL's provider model](https://docs.openssl.org/3.0/man7/crypto/#OPENSSL-PROVIDERS). -It is not necessary to rebuild Node.js to enable support for FIPS. +Node.js can use an OpenSSL FIPS provider via +[OpenSSL's provider model](https://docs.openssl.org/master/man7/crypto/#openssl-providers), +whether OpenSSL is linked statically or dynamically. It is not necessary to +rebuild Node.js to do so; the provider and the OpenSSL configuration that +activates it are supplied at runtime. + +Node.js does not build a FIPS provider. OpenSSL requires that a FIPS provider +be built from a release that carries a FIPS certificate, so a provider built +as part of the Node.js build would have no validation status. -When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL. +`./configure --openssl-is-fips` only records that the OpenSSL being linked is +FIPS capable, and requires `--shared-openssl`. -See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to -enable FIPS support in Node.js. +See [FIPS mode](doc/api/crypto.md#fips-mode) for how to configure it. ## Building Node.js with Temporal support @@ -1119,6 +1123,10 @@ A number of `configure` options are provided to support this use case. provide the ability to set the path to an external JavaScript file for the dependency to be used at runtime. +When building with `--shared-openssl`, Node.js requires OpenSSL 3.0 or later. +Support for building against OpenSSL 1.x was removed in Node.js 27.0.0, and +`configure` fails if an older version is detected. + It is the responsibility of any distribution shipping with these options to: diff --git a/benchmark/crypto/kem.js b/benchmark/crypto/kem.js index 34374dfc8494..05e640e1f5b2 100644 --- a/benchmark/crypto/kem.js +++ b/benchmark/crypto/kem.js @@ -35,12 +35,12 @@ if (hasOpenSSL(3, 2)) { keyFixtures.x25519 = readKeyPair('x25519_public', 'x25519_private'); keyFixtures.x448 = readKeyPair('x448_public', 'x448_private'); } -if (hasOpenSSL(3, 0)) { +if (!isBoringSSL) { keyFixtures.rsa = readKeyPair('rsa_public_2048', 'rsa_private_2048'); } if (Object.keys(keyFixtures).length === 0) { - console.log('no supported key types available for this OpenSSL version'); + console.log('no supported key types available for this crypto implementation'); process.exit(0); } diff --git a/benchmark/crypto/mac.js b/benchmark/crypto/mac.js index ea9d3a56e59f..a6ff89f22ea8 100644 --- a/benchmark/crypto/mac.js +++ b/benchmark/crypto/mac.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../common.js'); -const { hasOpenSSL, isBoringSSL } = require('../../test/common/crypto.js'); +const { isBoringSSL } = require('../../test/common/crypto.js'); const assert = require('node:assert'); const { createHmac, @@ -9,11 +9,10 @@ const { getMacs, } = require('node:crypto'); -if (!hasOpenSSL(3) || - isBoringSSL || +if (isBoringSSL || typeof createMac !== 'function' || typeof getMacs !== 'function') { - console.log('Skipping: generic MAC API requires OpenSSL >= 3'); + console.log('Skipping: generic MAC API requires OpenSSL EVP_MAC support'); process.exit(0); } diff --git a/configure.py b/configure.py index 5a30e76b1d84..06743a95f145 100755 --- a/configure.py +++ b/configure.py @@ -269,7 +269,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', @@ -1423,8 +1424,9 @@ def try_check_compiler(cc, lang): # # The version of asm compiler is needed for building openssl asm files. # See deps/openssl/openssl.gypi for detail. -# Commands and regular expressions to obtain its version number are taken from -# https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/crypto/sha/asm/sha512-x86_64.pl#L112-L129 +# Commands and regular expressions to obtain its version number mirror the +# bundled OpenSSL assembler scripts, including +# deps/openssl/openssl/crypto/sha/asm/sha512-x86_64.pl. # def get_version_helper(cc, regexp): try: @@ -2322,7 +2324,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 @@ -2356,15 +2357,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''') @@ -2377,17 +2378,25 @@ def without_ssl_error(option): if options.openssl_no_asm and options.shared_openssl: error('--openssl-no-asm is incompatible with --shared-openssl') + if options.openssl_is_fips and not options.shared_openssl: + error('--openssl-is-fips is only available with --shared-openssl') + if options.openssl_is_fips: o['defines'] += ['OPENSSL_FIPS'] - if options.openssl_is_fips and not options.shared_openssl: - variables['node_fipsinstall'] = b(True) - configure_library('openssl', o, with_separate_include_var=True) o['variables']['openssl_version'] = get_openssl_version(o) o['variables']['openssl_is_boringssl'] = get_openssl_is_boringssl(o) + # BoringSSL identifies itself as OpenSSL 1.1.1 and is exempt from this check. + # A version of 0 means detection failed, which is already warned about in + # get_openssl_version() and is caught at compile time by ncrypto.h. + openssl_version = o['variables']['openssl_version'] + if o['variables']['openssl_is_boringssl'] == 'false' and \ + 0 < openssl_version < 0x30000000: + error('OpenSSL 1.x is no longer supported, v3.0.0 or later is required.') + def configure_lief(o): if options.without_lief: if options.shared_lief: diff --git a/deps/ncrypto/engine.cc b/deps/ncrypto/engine.cc deleted file mode 100644 index a8e64e250491..000000000000 --- a/deps/ncrypto/engine.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "ncrypto.h" - -#if !defined(OPENSSL_NO_ENGINE) && \ - ((defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT) || \ - NCRYPTO_USE_LEGACY_OPENSSL) -#include -#endif - -namespace ncrypto { - -// ============================================================================ -// Engine - -#ifndef OPENSSL_NO_ENGINE -EnginePointer::EnginePointer(void* engine_, bool finish_on_exit_) - : engine(engine_), finish_on_exit(finish_on_exit_) {} - -EnginePointer::EnginePointer(EnginePointer&& other) noexcept - : engine(other.engine), finish_on_exit(other.finish_on_exit) { - other.release(); -} - -EnginePointer::~EnginePointer() { - reset(); -} - -EnginePointer& EnginePointer::operator=(EnginePointer&& other) noexcept { - if (this == &other) return *this; - this->~EnginePointer(); - return *new (this) EnginePointer(std::move(other)); -} - -void EnginePointer::reset(void* engine_, bool finish_on_exit_) { - if (engine != nullptr) { - ENGINE* current = static_cast(engine); - if (finish_on_exit) { - // This also does the equivalent of ENGINE_free. - ENGINE_finish(current); - } else { - ENGINE_free(current); - } - } - engine = engine_; - finish_on_exit = finish_on_exit_; -} - -void* EnginePointer::release() { - void* ret = engine; - engine = nullptr; - finish_on_exit = false; - return ret; -} - -EnginePointer EnginePointer::getEngineByName(const char* name, - CryptoErrorList* errors) { - MarkPopErrorOnReturn mark_pop_error_on_return(errors); - EnginePointer engine(ENGINE_by_id(name)); - if (!engine) { - // Engine not found, try loading dynamically. - engine = EnginePointer(ENGINE_by_id("dynamic")); - if (engine) { - ENGINE* current = static_cast(engine.engine); - if (!ENGINE_ctrl_cmd_string(current, "SO_PATH", name, 0) || - !ENGINE_ctrl_cmd_string(current, "LOAD", nullptr, 0)) { - engine.reset(); - } - } - } - return engine; -} - -bool EnginePointer::setAsDefault(uint32_t flags, CryptoErrorList* errors) { - if (engine == nullptr) return false; - ClearErrorOnReturn clear_error_on_return(errors); - return ENGINE_set_default(static_cast(engine), flags) != 0; -} - -bool EnginePointer::init(bool finish_on_exit) { - if (engine == nullptr) return false; - if (finish_on_exit) setFinishOnExit(); - return ENGINE_init(static_cast(engine)) == 1; -} - -EVPKeyPointer EnginePointer::loadPrivateKey(const char* key_name) { - if (engine == nullptr) return EVPKeyPointer(); - return EVPKeyPointer(ENGINE_load_private_key( - static_cast(engine), key_name, nullptr, nullptr)); -} - -bool EnginePointer::setClientCertEngine(SSL_CTX* ctx) { - if (engine == nullptr || ctx == nullptr) return false; - return SSL_CTX_set_client_cert_engine(ctx, static_cast(engine)) == 1; -} - -void EnginePointer::initEnginesOnce() { - static bool initialized = false; - if (!initialized) { - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - initialized = true; - } -} - -#endif // OPENSSL_NO_ENGINE - -} // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index d35d601abc70..52cf632e1982 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}; @@ -1179,9 +1163,9 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { } } } else { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return BIOPointer::PrintfAll(out, "", ip_len); -#else +#elif NCRYPTO_USE_BORINGSSL return BIOPointer::WriteAll(out, ""); #endif } @@ -1197,14 +1181,14 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { return false; } // 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 NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER int nid = OBJ_obj2nid(gen->d.otherName->type_id); switch (nid) { case NID_id_on_SmtpUTF8Mailbox: @@ -1224,7 +1208,7 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { prefix = "NAIRealm"; break; } -#endif // NCRYPTO_USE_OPENSSL3_PROVIDER +#endif // NCRYPTO_USE_OPENSSL_PROVIDER int val_type = gen->d.otherName->value->type; if (prefix == nullptr || (unicode && val_type != V_ASN1_UTF8STRING) || (!unicode && val_type != V_ASN1_IA5STRING)) { @@ -1345,7 +1329,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, const X509_EXTENSION* ext) { } sk_ACCESS_DESCRIPTION_pop_free(descs, ACCESS_DESCRIPTION_free); -#if NCRYPTO_USE_LEGACY_OPENSSL || NCRYPTO_USE_BORINGSSL +#if NCRYPTO_USE_BORINGSSL if (ok && !BIOPointer::WriteAll(out, "\n")) return false; #endif @@ -1773,9 +1757,9 @@ bool X509View::ifRsa(KeyCallback callback) const { std::optional rsa; { MarkPopErrorOnReturn mark_pop_error_on_return; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER rsa.emplace(pkey); -#else +#elif NCRYPTO_USE_BORINGSSL rsa.emplace(EVP_PKEY_get0_RSA(pkey)); #endif } @@ -1798,9 +1782,9 @@ bool X509View::ifEc(KeyCallback callback) const { std::optional ec; { MarkPopErrorOnReturn mark_pop_error_on_return; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ec.emplace(pkey); -#else +#elif NCRYPTO_USE_BORINGSSL ec.emplace(EVP_PKEY_get0_EC_KEY(pkey)); #endif } @@ -1831,9 +1815,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 } @@ -1971,7 +1955,7 @@ bool BIOPointer::WriteAll(const 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 && @@ -2048,7 +2032,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; @@ -2136,7 +2120,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) {} @@ -2144,12 +2128,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_)), @@ -2158,7 +2142,7 @@ DHPointer::DHPointer(DHPointer&& other) noexcept group_name_(other.group_name_) { other.group_name_ = nullptr; } -#else +#elif NCRYPTO_USE_BORINGSSL : dh_(other.release()) { } #endif @@ -2174,14 +2158,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(); @@ -2190,7 +2174,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 = @@ -2207,7 +2191,7 @@ EVP_PKEY* DHPointer::release() { group_name_ = nullptr; return dh_.release(); } -#else +#elif NCRYPTO_USE_BORINGSSL DH* DHPointer::release() { return dh_.release(); } @@ -2249,10 +2233,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 } @@ -2260,11 +2244,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 {}; @@ -2283,7 +2267,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)) { @@ -2293,7 +2277,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 {}; @@ -2308,7 +2292,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; @@ -2336,7 +2320,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; @@ -2350,7 +2334,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(); @@ -2398,7 +2382,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; @@ -2417,14 +2401,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); @@ -2433,14 +2417,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); @@ -2449,14 +2433,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); @@ -2465,14 +2449,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); @@ -2481,14 +2465,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); @@ -2497,14 +2481,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; @@ -2515,7 +2499,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 {}; @@ -2572,7 +2556,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 {}; @@ -2582,12 +2566,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. @@ -2599,7 +2583,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()); @@ -2644,7 +2628,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 {}; @@ -2667,7 +2651,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; @@ -2689,7 +2673,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 @@ -2704,7 +2688,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; @@ -2726,7 +2710,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 @@ -2748,7 +2732,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) { @@ -2776,7 +2760,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) { @@ -2792,11 +2776,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); } @@ -2828,9 +2807,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); @@ -2847,7 +2826,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. @@ -2874,13 +2853,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( @@ -2897,7 +2873,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, @@ -2942,10 +2918,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 @@ -2963,10 +2939,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, @@ -2994,7 +2970,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 {}; @@ -3031,7 +3007,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, @@ -3207,7 +3183,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 @@ -3284,75 +3260,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 @@ -3381,35 +3343,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 } @@ -3421,7 +3373,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( @@ -3435,16 +3387,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())) { @@ -3454,7 +3404,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 {}; @@ -3508,7 +3458,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(); @@ -3518,7 +3468,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) {} @@ -3545,12 +3495,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 } @@ -3558,13 +3508,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]; @@ -3578,14 +3527,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 } @@ -3603,7 +3544,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. @@ -3616,9 +3557,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 @@ -3643,7 +3584,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)); @@ -3655,8 +3596,6 @@ bool EVPKeyPointer::supportsContextString() const { OSSL_PARAM_locate_const(params, kSignatureInstance) != nullptr); #elif NCRYPTO_USE_BORINGSSL return algorithm->isPqc(); -#else - return false; #endif } @@ -3835,21 +3774,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; } @@ -3927,16 +3862,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; @@ -3993,7 +3928,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 } @@ -4008,7 +3943,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; @@ -4043,7 +3978,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 } @@ -4217,7 +4152,7 @@ Buffer GetPassphrase( return pass; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using OSSLEncoderCtxPointer = DeleteFnPtr; @@ -4383,7 +4318,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 @@ -4494,7 +4429,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) { @@ -4509,12 +4444,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) { @@ -4544,7 +4475,7 @@ Result EVPKeyPointer::writePrivateKey( } case PKEncodingType::PKCS8: { EVP_PKEY* export_key = get(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // OpenSSL's provider EC PKCS8 encoders temporarily change encoding flags. // Use an independent key so concurrent exports do not change the source. EVPKeyPointer key_copy; @@ -4591,7 +4522,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(), @@ -4601,12 +4532,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) { @@ -4658,7 +4585,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(), @@ -4669,12 +4596,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) { @@ -4695,7 +4618,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, @@ -4705,7 +4628,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(). @@ -4720,8 +4643,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()); @@ -4739,9 +4662,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); } @@ -4762,11 +4682,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. @@ -4780,9 +4700,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); @@ -4801,17 +4721,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 @@ -4820,9 +4733,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); @@ -4831,14 +4744,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) || @@ -4847,7 +4760,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; @@ -5000,7 +4913,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); @@ -5103,7 +5016,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; @@ -5117,7 +5030,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; @@ -5159,7 +5072,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 @@ -5182,12 +5095,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 {}; @@ -5197,7 +5110,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 {}; } @@ -5233,7 +5146,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); @@ -5242,7 +5155,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(); @@ -5252,16 +5165,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(); @@ -5272,14 +5185,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, @@ -5316,7 +5229,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()); @@ -5329,7 +5242,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()); @@ -5349,13 +5262,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. @@ -5379,7 +5292,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 @@ -5388,7 +5301,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)); @@ -5401,16 +5314,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 @@ -5517,9 +5430,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 } @@ -5533,7 +5446,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 } @@ -5628,9 +5541,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 } @@ -5725,10 +5638,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, @@ -5754,9 +5667,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 @@ -5768,9 +5681,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 @@ -5820,7 +5733,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 } @@ -6473,15 +6386,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 } @@ -6522,7 +6433,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; @@ -6549,7 +6460,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); @@ -6572,7 +6483,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; @@ -6615,9 +6526,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(); @@ -6629,15 +6540,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) { @@ -6657,7 +6565,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; @@ -6715,12 +6623,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? @@ -6732,7 +6636,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? @@ -6877,7 +6781,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 @@ -7029,24 +6933,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); @@ -7055,10 +6959,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); @@ -7069,29 +6973,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; } @@ -7117,9 +7003,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; @@ -7158,7 +7044,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_) { @@ -7189,7 +7075,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; @@ -7197,12 +7083,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(); @@ -7219,7 +7105,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; @@ -7233,7 +7119,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; } @@ -7253,36 +7139,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 } @@ -7336,7 +7193,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, @@ -7428,17 +7285,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 @@ -7446,7 +7303,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() { @@ -7512,31 +7369,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 } @@ -7566,7 +7423,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; @@ -7590,7 +7447,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; @@ -7615,7 +7472,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: @@ -7671,7 +7528,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( @@ -7680,7 +7537,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); @@ -7690,7 +7547,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) { @@ -7708,14 +7565,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; @@ -7729,12 +7586,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 } @@ -7763,7 +7620,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; @@ -7902,7 +7759,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. @@ -7936,8 +7793,6 @@ std::optional EVPMDCtxPointer::signInitWithContext( return std::nullopt; } return ctx; -#else - return std::nullopt; #endif } @@ -7955,7 +7810,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. @@ -7989,8 +7844,6 @@ std::optional EVPMDCtxPointer::verifyInitWithContext( return std::nullopt; } return ctx; -#else - return std::nullopt; #endif } @@ -8064,7 +7917,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) {} @@ -8124,7 +7977,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) {} @@ -8526,7 +8379,7 @@ std::optional 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() { @@ -8537,16 +8390,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); @@ -8555,10 +8408,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); @@ -8567,18 +8420,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()); @@ -8591,13 +8444,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()); @@ -8610,7 +8463,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()); @@ -8633,7 +8486,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; @@ -8651,7 +8504,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); @@ -8661,7 +8514,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)); @@ -8676,7 +8529,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 || @@ -8709,7 +8562,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; } @@ -8750,7 +8603,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 804a664fa0a2..ce6670e63bb5 100644 --- a/deps/ncrypto/ncrypto.gyp +++ b/deps/ncrypto/ncrypto.gyp @@ -5,22 +5,10 @@ 'ncrypto.cc', 'ncrypto.h', ], - 'ncrypto_engine_sources': [ - 'engine.cc', - 'ncrypto.h', - ], 'ncrypto_strict_defines': [ 'OPENSSL_API_COMPAT=30000', 'OPENSSL_NO_DEPRECATED', ], - 'ncrypto_legacy_openssl_defines': [ - 'OPENSSL_API_COMPAT=0x10100000L', - ], - 'ncrypto_engine_defines': [ - 'OPENSSL_API_COMPAT=30000', - 'OPENSSL_SUPPRESS_DEPRECATED', - 'NCRYPTO_ENGINE_COMPAT=1', - ], }, 'targets': [ { @@ -36,23 +24,15 @@ 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], }], ], }, 'sources': [ '<@(ncrypto_sources)' ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], - 'dependencies': [ - 'ncrypto_engine', - ], - }], - ['openssl_is_boringssl=="false" and openssl_version < 0x3000000f', { - 'sources': [ '<@(ncrypto_engine_sources)' ], }], ['node_shared_openssl=="false"', { 'dependencies': [ @@ -62,27 +42,4 @@ ] }, ], - 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'targets': [ - { - 'target_name': 'ncrypto_engine', - 'type': 'static_library', - 'include_dirs': ['.'], - 'defines': [ - 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', - '<@(ncrypto_engine_defines)', - ], - 'sources': [ '<@(ncrypto_engine_sources)' ], - 'conditions': [ - ['node_shared_openssl=="false"', { - 'dependencies': [ - '../openssl/openssl.gyp:openssl' - ] - }], - ] - }, - ], - }], - ], } diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 9a501a551b46..e45807ec1796 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -23,16 +23,16 @@ #include #include #include -#if defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT && \ - !defined(OPENSSL_NO_ENGINE) -#include -#endif // NCRYPTO_ENGINE_COMPAT && !OPENSSL_NO_ENGINE - #ifndef OPENSSL_VERSION_PREREQ #define OPENSSL_VERSION_PREREQ(maj, min) \ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20))) #endif +// BoringSSL reports itself as OpenSSL 1.1.1, so it has to be excluded here. +#if !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_VERSION_PREREQ(3, 0) +#error "OpenSSL 1.x is no longer supported, v3.0.0 or later is required." +#endif + // BoringSSL declares the EVP_*_do_all* APIs, but their implementation may // live in libdecrepit. This matches standalone ncrypto's build flag. #ifndef NCRYPTO_BSSL_LIBDECREPIT_MISSING @@ -46,48 +46,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 +77,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 +97,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 +335,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 +360,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 +393,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 +412,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 +438,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 +479,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 +575,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 +587,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 +611,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 +628,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 +709,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 +722,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 +730,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 +766,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 }; @@ -1236,9 +1212,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 @@ -1423,10 +1399,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; @@ -1434,14 +1410,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 @@ -1503,14 +1479,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 }; @@ -1838,14 +1814,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 @@ -1883,11 +1859,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 }; @@ -1957,7 +1933,7 @@ class EVPMDCtxPointer final { DeleteFnPtr ctx_; }; -#if !OPENSSL_WITH_EVP_MAC +#if NCRYPTO_USE_BORINGSSL class HMACCtxPointer final { public: HMACCtxPointer(); @@ -1984,7 +1960,7 @@ class HMACCtxPointer final { private: DeleteFnPtr ctx_; }; -#endif // !OPENSSL_WITH_EVP_MAC +#endif // NCRYPTO_USE_BORINGSSL #if OPENSSL_WITH_EVP_MAC class EVPMacPointer final { @@ -2120,7 +2096,7 @@ class HMACCtxPointer final { }; #endif // OPENSSL_WITH_EVP_MAC -#if !OPENSSL_WITH_EVP_MAC +#if NCRYPTO_USE_BORINGSSL class MacCache final { public: MacCache() = default; @@ -2128,44 +2104,6 @@ class MacCache final { }; #endif -#ifndef OPENSSL_NO_ENGINE -class EnginePointer final { - public: - EnginePointer() = default; - - explicit EnginePointer(void* engine_, bool finish_on_exit = false); - EnginePointer(EnginePointer&& other) noexcept; - EnginePointer& operator=(EnginePointer&& other) noexcept; - NCRYPTO_DISALLOW_COPY(EnginePointer) - ~EnginePointer(); - - inline operator bool() const { return engine != nullptr; } - inline void setFinishOnExit() { finish_on_exit = true; } - - void reset(void* engine_ = nullptr, bool finish_on_exit_ = false); - - bool setAsDefault(uint32_t flags, CryptoErrorList* errors = nullptr); - bool init(bool finish_on_exit = false); - EVPKeyPointer loadPrivateKey(const char* key_name); - bool setClientCertEngine(SSL_CTX* ctx); - - void* release(); - - // Retrieve an OpenSSL Engine instance by name. If the name does not - // identify a valid named engine, the returned EnginePointer will be - // empty. - static EnginePointer getEngineByName(const char* name, - CryptoErrorList* errors = nullptr); - - // Call once when initializing OpenSSL at startup for the process. - static void initEnginesOnce(); - - private: - void* engine = nullptr; - bool finish_on_exit = false; -}; -#endif // !OPENSSL_NO_ENGINE - // ============================================================================ // FIPS bool isFipsEnabled(); @@ -2210,7 +2148,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; @@ -2306,7 +2244,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/deps/ncrypto/unofficial.gni b/deps/ncrypto/unofficial.gni index dad4fbbf16f0..7cb27d22b9b8 100644 --- a/deps/ncrypto/unofficial.gni +++ b/deps/ncrypto/unofficial.gni @@ -26,11 +26,7 @@ template("ncrypto_gn_build") { source_set(target_name) { forward_variables_from(invoker, "*") public_configs = [ ":ncrypto_config" ] - defines = [ - "NCRYPTO_ENGINE_COMPAT=1", - "OPENSSL_SUPPRESS_DEPRECATED", - ] - sources = gypi_values.ncrypto_sources + gypi_values.ncrypto_engine_sources + sources = gypi_values.ncrypto_sources deps = [ "$node_openssl_path" ] } } diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 144085fd33df..d11f72a758d8 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -98,36 +98,6 @@ }, }], ] - }, { - # openssl-fipsmodule target - 'target_name': 'openssl-fipsmodule', - 'type': 'shared_library', - 'dependencies': ['openssl-cli'], - 'includes': ['./openssl_common.gypi'], - 'include_dirs+': ['openssl/apps/include'], - 'cflags': [ '-fPIC' ], - #'ldflags': [ '-o', 'fips.so' ], - #'ldflags': [ '-Wl,--version-script=providers/fips.ld',], - 'conditions': [ - [ 'openssl_no_asm==1', { - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'target_arch=="arm64" and OS=="win"', { - # VC-WIN64-ARM inherits from VC-noCE-common that has no asms. - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'gas_version and v(gas_version) >= v("2.26") or ' - 'nasm_version and v(nasm_version) >= v("2.11.8") or ' - 'llvm_version and v(llvm_version) >= v("8.0")', { - # Require AVX512IFMA supported. See - # https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html - # Currently crypto/poly1305/asm/poly1305-x86_64.pl requires AVX512IFMA. - 'includes': ['./openssl-fips_asm.gypi'], - }, { - 'includes': ['./openssl-fips_asm_avx2.gypi'], - }], - ], - 'direct_dependent_settings': { - 'include_dirs': [ 'openssl/include', 'openssl/crypto/include'] - } - }, + }, ] } diff --git a/doc/api/cli.md b/doc/api/cli.md index 7230231decd4..7cc845e472e9 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1226,9 +1226,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` @@ -2532,8 +2531,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. @@ -2545,7 +2543,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 085ccdcc9c09..769992815023 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3751,8 +3751,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][] @@ -3860,8 +3860,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][] @@ -4508,7 +4508,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) @@ -4580,7 +4580,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) @@ -4593,18 +4593,6 @@ passed to [`crypto.createPublicKey()`][]. If the `callback` function is provided this function uses libuv's threadpool. -### `crypto.fips` - - - -> Stability: 0 - Deprecated - -Deprecated property for checking and controlling [FIPS mode][]. Use -[`crypto.getFips()`][] and [`crypto.setFips()`][] instead. - ### `crypto.generateKey(type, options, callback)` - -> Stability: 0 - Deprecated - -* `engine` {string} -* `flags` {crypto.constants} **Default:** `crypto.constants.ENGINE_METHOD_ALL` - -Load and set the `engine` for some or all OpenSSL functions (selected by flags). -Use of this API is deprecated because custom engine support has been deprecated -since OpenSSL 3. - -`engine` could be either an id or a path to the engine's shared library. - -The optional `flags` argument uses `ENGINE_METHOD_ALL` by default. The `flags` -is a bit field taking one of or a mix of the following flags (defined in -`crypto.constants`): - -* `crypto.constants.ENGINE_METHOD_RSA` -* `crypto.constants.ENGINE_METHOD_DSA` -* `crypto.constants.ENGINE_METHOD_DH` -* `crypto.constants.ENGINE_METHOD_RAND` -* `crypto.constants.ENGINE_METHOD_EC` -* `crypto.constants.ENGINE_METHOD_CIPHERS` -* `crypto.constants.ENGINE_METHOD_DIGESTS` -* `crypto.constants.ENGINE_METHOD_PKEY_METHS` -* `crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS` -* `crypto.constants.ENGINE_METHOD_ALL` -* `crypto.constants.ENGINE_METHOD_NONE` - ### `crypto.setFips(bool)` -Type: Runtime +Type: End-of-Life -The [`crypto.fips`][] property is deprecated. Please use `crypto.setFips()` +The `crypto.fips` property is no longer supported. Use `crypto.setFips()` and `crypto.getFips()` instead. An automated migration is available ([source](https://github.com/nodejs/userland-migrations/tree/main/recipes/crypto-fips-to-getFips)). @@ -4108,6 +4111,9 @@ that are shorter than the default authentication tag length (i.e., shorter than -Type: Runtime +Type: End-of-Life -OpenSSL 3 has deprecated support for custom engines with a recommendation to -switch to its new provider model. The `clientCertEngine` option for -`https.request()`, [`tls.createSecureContext()`][], and [`tls.createServer()`][]; -the `privateKeyEngine` and `privateKeyIdentifier` for [`tls.createSecureContext()`][]; -and [`crypto.setEngine()`][] all depend on this functionality from OpenSSL. +The `crypto.setEngine()` API and the `crypto.constants.ENGINE_METHOD_*` +constants have been removed. The `clientCertEngine` option for +[`https.request()`][], [`tls.createSecureContext()`][], and +[`tls.createServer()`][] and the `privateKeyEngine` and `privateKeyIdentifier` +options for [`tls.createSecureContext()`][] now throw +`ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED` when used. There is no direct +replacement API in Node.js. OpenSSL's provider model replaces engines upstream. ### DEP0184: Instantiating `node:zlib` classes without `new` @@ -4884,11 +4892,9 @@ Type: Documentation-only [`crypto.createDecipheriv()`]: crypto.md#cryptocreatedecipherivalgorithm-key-iv-options [`crypto.createHash()`]: crypto.md#cryptocreatehashalgorithm-options [`crypto.createHmac()`]: crypto.md#cryptocreatehmacalgorithm-key-options -[`crypto.fips`]: crypto.md#cryptofips [`crypto.pbkdf2()`]: crypto.md#cryptopbkdf2password-salt-iterations-keylen-digest-callback [`crypto.randomBytes()`]: crypto.md#cryptorandombytessize-callback [`crypto.scrypt()`]: crypto.md#cryptoscryptpassword-salt-keylen-options-callback -[`crypto.setEngine()`]: crypto.md#cryptosetengineengine-flags [`decipher.final()`]: crypto.md#decipherfinaloutputencoding [`decipher.setAuthTag()`]: crypto.md#deciphersetauthtagbuffer-encoding [`dirent.parentPath`]: fs.md#direntparentpath diff --git a/doc/api/errors.md b/doc/api/errors.md index 1d812bd0b332..834be04dcbba 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` @@ -3945,6 +3937,17 @@ removed: v15.0.0 The native call from `process.cpuUsage` could not be processed. + + +### `ERR_CRYPTO_ENGINE_UNKNOWN` + + + +An invalid crypto engine identifier was passed to +`require('node:crypto').setEngine()`. + ### `ERR_CRYPTO_HASH_DIGEST_NO_UTF16` @@ -4840,7 +4843,6 @@ An error occurred trying to allocate memory. This should never happen. [`process.send()`]: process.md#processsendmessage-sendhandle-options-callback [`process.setUncaughtExceptionCaptureCallback()`]: process.md#processsetuncaughtexceptioncapturecallbackfn [`readable._read()`]: stream.md#readable_readsize -[`require('node:crypto').setEngine()`]: crypto.md#cryptosetengineengine-flags [`require()`]: modules.md#requireid [`server.close()`]: net.md#serverclosecallback [`server.listen()`]: net.md#serverlisten diff --git a/doc/api/https.md b/doc/api/https.md index eba303b6600a..59221c9b645f 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -427,6 +427,10 @@ a `timeout` of 5 seconds.