diff --git a/BUILDING.md b/BUILDING.md index e477d46863f4..b1accbe8962a 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -206,7 +206,7 @@ on your Linux distribution. #### OpenSSL asm support -OpenSSL-1.1.1 requires the following assembler version for use of asm +OpenSSL requires the following assembler version for use of asm support on x86\_64 and ia32. For use of AVX-512, @@ -214,8 +214,6 @@ For use of AVX-512, * gas (GNU assembler) version 2.26 or higher * nasm version 2.11.8 or higher in Windows -AVX-512 is disabled for Skylake-X by OpenSSL-1.1.1. - For use of AVX2, * gas (GNU assembler) version 2.23 or higher @@ -223,7 +221,7 @@ For use of AVX2, * llvm version 3.3 or higher * nasm version 2.10 or higher in Windows -Please refer to for details. +Please refer to for details. If compiling without one of the above, use `configure` with the `--openssl-no-asm` flag. Otherwise, `configure` will fail. @@ -1044,14 +1042,20 @@ using the following configure option: ## Building Node.js with FIPS-compliant OpenSSL -Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via -[OpenSSL's provider model](https://docs.openssl.org/3.0/man7/crypto/#OPENSSL-PROVIDERS). -It is not necessary to rebuild Node.js to enable support for FIPS. +Node.js can use an OpenSSL FIPS provider via +[OpenSSL's provider model](https://docs.openssl.org/master/man7/crypto/#openssl-providers), +whether OpenSSL is linked statically or dynamically. It is not necessary to +rebuild Node.js to do so; the provider and the OpenSSL configuration that +activates it are supplied at runtime. + +Node.js does not build a FIPS provider. OpenSSL requires that a FIPS provider +be built from a release that carries a FIPS certificate, so a provider built +as part of the Node.js build would have no validation status. -When using OpenSSL 1.1.1, Node.js must be built against a FIPS-capable OpenSSL. +`./configure --openssl-is-fips` only records that the OpenSSL being linked is +FIPS capable, and requires `--shared-openssl`. -See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to -enable FIPS support in Node.js. +See [FIPS mode](doc/api/crypto.md#fips-mode) for how to configure it. ## Building Node.js with Temporal support @@ -1135,6 +1139,10 @@ A number of `configure` options are provided to support this use case. provide the ability to set the path to an external JavaScript file for the dependency to be used at runtime. +When building with `--shared-openssl`, Node.js requires OpenSSL 3.0 or later. +Support for building against OpenSSL 1.x was removed in Node.js 27.0.0, and +`configure` fails if an older version is detected. + It is the responsibility of any distribution shipping with these options to: diff --git a/configure.py b/configure.py index b11c4e3284d0..c967aa8345a8 100755 --- a/configure.py +++ b/configure.py @@ -268,7 +268,8 @@ action='store_true', dest='openssl_is_fips', default=None, - help='specifies that the OpenSSL library is FIPS compatible') + help='specifies that the shared OpenSSL library is FIPS capable ' + '(requires --shared-openssl)') parser.add_argument('--openssl-use-def-ca-store', action='store_true', @@ -2244,7 +2245,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 @@ -2299,17 +2299,25 @@ def without_ssl_error(option): if options.openssl_no_asm and options.shared_openssl: error('--openssl-no-asm is incompatible with --shared-openssl') + if options.openssl_is_fips and not options.shared_openssl: + error('--openssl-is-fips is only available with --shared-openssl') + if options.openssl_is_fips: o['defines'] += ['OPENSSL_FIPS'] - if options.openssl_is_fips and not options.shared_openssl: - variables['node_fipsinstall'] = b(True) - configure_library('openssl', o) o['variables']['openssl_version'] = get_openssl_version(o) o['variables']['openssl_is_boringssl'] = get_openssl_is_boringssl(o) + # BoringSSL identifies itself as OpenSSL 1.1.1 and is exempt from this check. + # A version of 0 means detection failed, which is already warned about in + # get_openssl_version() and is caught at compile time by ncrypto.h. + openssl_version = o['variables']['openssl_version'] + if o['variables']['openssl_is_boringssl'] == 'false' and \ + 0 < openssl_version < 0x30000000: + error('OpenSSL 1.x is no longer supported, v3.0.0 or later is required.') + def configure_lief(o): if options.without_lief: if options.shared_lief: diff --git a/deps/ncrypto/engine.cc b/deps/ncrypto/engine.cc deleted file mode 100644 index a8e64e250491..000000000000 --- a/deps/ncrypto/engine.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "ncrypto.h" - -#if !defined(OPENSSL_NO_ENGINE) && \ - ((defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT) || \ - NCRYPTO_USE_LEGACY_OPENSSL) -#include -#endif - -namespace ncrypto { - -// ============================================================================ -// Engine - -#ifndef OPENSSL_NO_ENGINE -EnginePointer::EnginePointer(void* engine_, bool finish_on_exit_) - : engine(engine_), finish_on_exit(finish_on_exit_) {} - -EnginePointer::EnginePointer(EnginePointer&& other) noexcept - : engine(other.engine), finish_on_exit(other.finish_on_exit) { - other.release(); -} - -EnginePointer::~EnginePointer() { - reset(); -} - -EnginePointer& EnginePointer::operator=(EnginePointer&& other) noexcept { - if (this == &other) return *this; - this->~EnginePointer(); - return *new (this) EnginePointer(std::move(other)); -} - -void EnginePointer::reset(void* engine_, bool finish_on_exit_) { - if (engine != nullptr) { - ENGINE* current = static_cast(engine); - if (finish_on_exit) { - // This also does the equivalent of ENGINE_free. - ENGINE_finish(current); - } else { - ENGINE_free(current); - } - } - engine = engine_; - finish_on_exit = finish_on_exit_; -} - -void* EnginePointer::release() { - void* ret = engine; - engine = nullptr; - finish_on_exit = false; - return ret; -} - -EnginePointer EnginePointer::getEngineByName(const char* name, - CryptoErrorList* errors) { - MarkPopErrorOnReturn mark_pop_error_on_return(errors); - EnginePointer engine(ENGINE_by_id(name)); - if (!engine) { - // Engine not found, try loading dynamically. - engine = EnginePointer(ENGINE_by_id("dynamic")); - if (engine) { - ENGINE* current = static_cast(engine.engine); - if (!ENGINE_ctrl_cmd_string(current, "SO_PATH", name, 0) || - !ENGINE_ctrl_cmd_string(current, "LOAD", nullptr, 0)) { - engine.reset(); - } - } - } - return engine; -} - -bool EnginePointer::setAsDefault(uint32_t flags, CryptoErrorList* errors) { - if (engine == nullptr) return false; - ClearErrorOnReturn clear_error_on_return(errors); - return ENGINE_set_default(static_cast(engine), flags) != 0; -} - -bool EnginePointer::init(bool finish_on_exit) { - if (engine == nullptr) return false; - if (finish_on_exit) setFinishOnExit(); - return ENGINE_init(static_cast(engine)) == 1; -} - -EVPKeyPointer EnginePointer::loadPrivateKey(const char* key_name) { - if (engine == nullptr) return EVPKeyPointer(); - return EVPKeyPointer(ENGINE_load_private_key( - static_cast(engine), key_name, nullptr, nullptr)); -} - -bool EnginePointer::setClientCertEngine(SSL_CTX* ctx) { - if (engine == nullptr || ctx == nullptr) return false; - return SSL_CTX_set_client_cert_engine(ctx, static_cast(engine)) == 1; -} - -void EnginePointer::initEnginesOnce() { - static bool initialized = false; - if (!initialized) { - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - initialized = true; - } -} - -#endif // OPENSSL_NO_ENGINE - -} // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index d334d17c300b..1268adde4f82 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -18,7 +18,7 @@ #include #include #include -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include #include #include @@ -62,24 +62,13 @@ constexpr static PQCMapping pqc_mappings[] = { #endif -// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e. -#if OPENSSL_VERSION_NUMBER < 0x1010105fL -#define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \ - EVP_PKEY_CTX_ctrl((ctx), \ - EVP_PKEY_DSA, \ - EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, \ - (qbits), \ - nullptr) -#endif - namespace ncrypto { namespace { using BignumCtxPointer = DeleteFnPtr; using BignumGenCallbackPointer = DeleteFnPtr; using NetscapeSPKIPointer = DeleteFnPtr; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using X509PubKeyPointer = DeleteFnPtr; // OSSL_STORE_close() returns int, so it needs a void-returning adapter to be // usable as a DeleteFnPtr deleter. @@ -91,7 +80,7 @@ using UIMethodPointer = DeleteFnPtr; #endif const EVP_CIPHER* GetCipherCtxCipher(const EVP_CIPHER_CTX* ctx) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_CIPHER_CTX_get0_cipher(ctx); #else return EVP_CIPHER_CTX_cipher(ctx); @@ -99,14 +88,14 @@ const EVP_CIPHER* GetCipherCtxCipher(const EVP_CIPHER_CTX* ctx) { } const EVP_MD* GetDigestCtxMd(const EVP_MD_CTX* ctx) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER || NCRYPTO_USE_BORINGSSL +#if NCRYPTO_USE_OPENSSL_PROVIDER || NCRYPTO_USE_BORINGSSL return EVP_MD_CTX_get0_md(ctx); #else return EVP_MD_CTX_md(ctx); #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using ASN1StringPointer = DeleteFnPtr; using OSSLParamBldPointer = DeleteFnPtr; using RsaPssParamsPointer = DeleteFnPtr; @@ -135,7 +124,7 @@ using OpenSSLBufferPointer = static constexpr int kX509NameFlagsRFC2253WithinUtf8JSON = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB & ~ASN1_STRFLGS_ESC_CTRL; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER template bool GetPKeyBnParam(const EVP_PKEY* pkey, const char* name, Pointer* out) { BIGNUM* bn = nullptr; @@ -514,7 +503,7 @@ namespace { std::atomic fips_state_generation{0}; bool isFipsEnabledRaw() { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL return EVP_default_properties_is_fips_enabled(nullptr) == 1; #else return FIPS_mode() == 1; @@ -531,7 +520,7 @@ bool setFipsEnabled(bool enable, CryptoErrorList* errors) { const bool was_enabled = isFipsEnabled(); if (was_enabled == enable) return true; ClearErrorOnReturn clearErrorOnReturn(errors); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL const bool success = EVP_default_properties_enable_fips(nullptr, enable ? 1 : 0) == 1; #else @@ -549,7 +538,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"); @@ -731,7 +720,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; @@ -811,7 +800,7 @@ bool CSPRNG(void* buffer, size_t length) { auto buf = reinterpret_cast(buffer); do { if (1 == RAND_status()) { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (1 == RAND_bytes_ex(nullptr, buf, length, 0)) { return true; } @@ -824,7 +813,7 @@ bool CSPRNG(void* buffer, size_t length) { return true; #endif } -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL const auto code = ERR_peek_last_error(); // A misconfigured OpenSSL 3 installation may report 1 from RAND_poll() // and RAND_status() but fail in RAND_bytes() if it cannot look up @@ -861,7 +850,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}; @@ -1147,7 +1136,7 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { BIO_printf(out.get(), (j == 0) ? "%X" : ":%X", pair); } } else { -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL BIO_printf(out.get(), "", ip_len); #else BIO_printf(out.get(), ""); @@ -1166,9 +1155,9 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { // awkward, especially when passed to translatePeerCertificate. bool unicode = true; const char* prefix = nullptr; - // OpenSSL 1.1.1 does not support othername in GENERAL_NAME_print and may + // BoringSSL does not support othername in GENERAL_NAME_print and may // not define these NIDs. -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int nid = OBJ_obj2nid(gen->d.otherName->type_id); switch (nid) { case NID_id_on_SmtpUTF8Mailbox: @@ -1188,7 +1177,7 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) { prefix = "NAIRealm"; break; } -#endif // OPENSSL_VERSION_MAJOR >= 3 +#endif // !OPENSSL_IS_BORINGSSL int val_type = gen->d.otherName->value->type; if (prefix == nullptr || (unicode && val_type != V_ASN1_UTF8STRING) || (!unicode && val_type != V_ASN1_IA5STRING)) { @@ -1279,7 +1268,7 @@ bool SafeX509InfoAccessPrint(const BIOPointer& out, const X509_EXTENSION* ext) { } sk_ACCESS_DESCRIPTION_pop_free(descs, ACCESS_DESCRIPTION_free); -#if OPENSSL_VERSION_MAJOR < 3 +#ifdef OPENSSL_IS_BORINGSSL BIO_write(out.get(), "\n", 1); #endif @@ -1657,7 +1646,7 @@ bool X509View::ifRsa(KeyCallback callback) const { OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); auto id = EVP_PKEY_id(pkey); if (id == EVP_PKEY_RSA || id == EVP_PKEY_RSA2 || id == EVP_PKEY_RSA_PSS) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Rsa rsa(pkey); #else Rsa rsa(EVP_PKEY_get0_RSA(pkey)); @@ -1674,7 +1663,7 @@ bool X509View::ifEc(KeyCallback callback) const { OSSL3_CONST EVP_PKEY* pkey = X509_get0_pubkey(cert_); auto id = EVP_PKEY_id(pkey); if (id == EVP_PKEY_EC) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec ec(pkey); #else Ec ec(EVP_PKEY_get0_EC_KEY(pkey)); @@ -1706,7 +1695,7 @@ X509Pointer X509Pointer::IssuerFrom(const SSL_CTX* ctx, const X509View& cert) { } X509Pointer X509Pointer::PeerFrom(const SSLPointer& ssl) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return X509Pointer(SSL_get1_peer_certificate(ssl.get())); #else return X509Pointer(SSL_get_peer_certificate(ssl.get())); @@ -1841,7 +1830,7 @@ bool EqualNoCase(const std::string_view a, const std::string_view b) { }); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* GetOpenSSLDhGroupName(const std::string_view name, DHPointer::FindGroupOption option) { if (option != DHPointer::FindGroupOption::NO_SMALL_PRIMES && @@ -2006,7 +1995,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) {} @@ -2019,7 +2008,7 @@ DHPointer::DHPointer(DH* dh) : dh_(dh) {} #endif DHPointer::DHPointer(DHPointer&& other) noexcept -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER : dh_(other.dh_.release()), p_(std::move(other.p_)), g_(std::move(other.g_)), @@ -2044,14 +2033,14 @@ DHPointer::~DHPointer() { } void DHPointer::reset( -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_PKEY* dh #else DH* dh #endif ) { dh_.reset(dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER p_.reset(); g_.reset(); pub_key_.reset(); @@ -2060,7 +2049,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 = @@ -2119,7 +2108,7 @@ DHPointer DHPointer::FromGroup(const std::string_view name, auto generator = GetStandardGenerator(); if (!generator) return {}; // Unable to create the generator. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* group_name = GetOpenSSLDhGroupName(name, option); return DHPointer(std::move(group), std::move(generator), group_name); #else @@ -2130,7 +2119,7 @@ DHPointer DHPointer::FromGroup(const std::string_view name, DHPointer DHPointer::New(BignumPointer&& p, BignumPointer&& g) { if (!p || !g) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = NewDhPKey(p.get(), g.get()); if (!pkey) return {}; return DHPointer(std::move(pkey)); @@ -2153,7 +2142,7 @@ DHPointer DHPointer::New(BignumPointer&& p, BignumPointer&& g) { } DHPointer DHPointer::New(size_t bits, unsigned int generator) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto param_ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_DH); if (!param_ctx.initForParamgen() || !param_ctx.setDhParameters(bits, generator)) { @@ -2178,7 +2167,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; @@ -2220,7 +2209,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(); @@ -2287,7 +2276,7 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey( DataPointer DHPointer::getPrime() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return p_.encode(); DeleteFnPtr p; @@ -2303,7 +2292,7 @@ DataPointer DHPointer::getPrime() const { size_t DHPointer::getPrimeBits() const { if (!*this) return 0; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return BignumPointer::GetBitCount(p_.get()); DeleteFnPtr p; @@ -2319,7 +2308,7 @@ size_t DHPointer::getPrimeBits() const { DataPointer DHPointer::getGenerator() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (g_) return g_.encode(); DeleteFnPtr p; @@ -2335,7 +2324,7 @@ DataPointer DHPointer::getGenerator() const { DataPointer DHPointer::getPublicKey() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pub_key_) return pub_key_.encode(); if (!dh_) return {}; @@ -2351,7 +2340,7 @@ DataPointer DHPointer::getPublicKey() const { DataPointer DHPointer::getPrivateKey() const { if (!*this) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pvt_key_) return pvt_key_.encode(); if (!dh_) return {}; @@ -2367,7 +2356,7 @@ DataPointer DHPointer::getPrivateKey() const { bool DHPointer::hasPrivateKey() const { if (!*this) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (pvt_key_) return true; if (!dh_) return false; @@ -2385,7 +2374,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 {}; @@ -2452,7 +2441,7 @@ DataPointer DHPointer::generateKeys() { size_t DHPointer::size() const { if (!*this) return 0; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (p_) return BignumPointer::GetByteCount(p_.get()); const int bits = EVP_PKEY_get_bits(dh_.get()); @@ -2469,7 +2458,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()); @@ -2537,7 +2526,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; @@ -2574,7 +2563,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; @@ -3035,7 +3024,7 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed( EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) { if (!dh) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVPKeyPointer(dh.release()); #else auto key = New(); @@ -3047,7 +3036,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 {}; @@ -3098,7 +3087,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) {} @@ -3236,7 +3225,7 @@ BIOPointer EVPKeyPointer::derPublicKey() const { bool EVPKeyPointer::assign(const ECKeyPointer& eckey) { if (!pkey_ || !eckey) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return set(eckey); #else return EVP_PKEY_assign_EC_KEY(pkey_.get(), eckey.get()); @@ -3245,7 +3234,7 @@ bool EVPKeyPointer::assign(const ECKeyPointer& eckey) { bool EVPKeyPointer::set(const ECKeyPointer& eckey) { if (!pkey_ || !eckey) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int nid = EC_GROUP_get_curve_name(eckey.group_.get()); const char* group_name = OBJ_nid2sn(nid); if (group_name == nullptr) return false; @@ -3513,7 +3502,7 @@ Buffer GetPassphrase( return pass; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER using OSSLEncoderCtxPointer = DeleteFnPtr; @@ -3679,7 +3668,7 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryLoadPrivateKeyFromStore( const StorePrivateKeyConfig& config) { -#if !NCRYPTO_USE_OPENSSL3_PROVIDER +#if !NCRYPTO_USE_OPENSSL_PROVIDER return ParseKeyResult(PKParseError::FAILED); #else // The error queue is left populated on failure so the caller can surface a @@ -3790,7 +3779,7 @@ Result EVPKeyPointer::writePrivateKey( // PKCS1 is only permitted for RSA keys. if (id() != EVP_PKEY_RSA) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher : nullptr; if (cipher != nullptr && passphrase.len == 0) { @@ -3805,12 +3794,8 @@ Result EVPKeyPointer::writePrivateKey( cipher, passphrase); } -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const RSA* rsa = EVP_PKEY_get0_RSA(get()); #else RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif if (rsa == nullptr) return Result(false); switch (config.format) { @@ -3872,7 +3857,7 @@ Result EVPKeyPointer::writePrivateKey( // SEC1 is only permitted for EC keys if (id() != EVP_PKEY_EC) return Result(false); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* cipher = config.format == PKFormatType::PEM ? config.cipher : nullptr; err = !WriteEncodedPKey(bio.get(), @@ -3882,12 +3867,8 @@ Result EVPKeyPointer::writePrivateKey( "type-specific", cipher, passphrase); -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); #else EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); -#endif if (ec == nullptr) return Result(false); switch (config.format) { @@ -3939,7 +3920,7 @@ Result EVPKeyPointer::writePublicKey( if (config.type == ncrypto::EVPKeyPointer::PKEncodingType::PKCS1) { // PKCS#1 is only valid for RSA keys. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (id() != EVP_PKEY_RSA) return Result(false); if (!WriteEncodedPKey(bio.get(), get(), @@ -3950,12 +3931,8 @@ Result EVPKeyPointer::writePublicKey( mark_pop_error_on_return.peekError()); } return bio; -#else -#if OPENSSL_VERSION_MAJOR >= 3 - const RSA* rsa = EVP_PKEY_get0_RSA(get()); #else RSA* rsa = EVP_PKEY_get0_RSA(get()); -#endif if (rsa == nullptr) return Result(false); if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { @@ -3976,7 +3953,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, @@ -3986,7 +3963,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(). @@ -4072,7 +4049,7 @@ std::optional EVPKeyPointer::getBytesOfRS() const { int bits, id = base_id(); if (id == EVP_PKEY_DSA) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr q; if (!GetPKeyBnParam(get(), OSSL_PKEY_PARAM_FFC_Q, &q)) return std::nullopt; bits = BignumPointer::GetBitCount(q.get()); @@ -4090,7 +4067,7 @@ std::optional EVPKeyPointer::getBytesOfRS() const { if (!has_bits) return std::nullopt; #endif } else if (id == EVP_PKEY_EC) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Ec ec(get()); if (!ec) return std::nullopt; const EC_GROUP* group = ec.getGroup(); @@ -4116,17 +4093,10 @@ EVPKeyPointer::operator Rsa() const { int type = id(); if (type != EVP_PKEY_RSA && type != EVP_PKEY_RSA_PSS) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return Rsa(get()); #else - // TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL - // versions older than 1.1.1e via FIPS / dynamic linking. - OSSL3_CONST RSA* rsa; - if (OPENSSL_VERSION_NUMBER >= 0x1010105fL) { - rsa = EVP_PKEY_get0_RSA(get()); - } else { - rsa = static_cast(EVP_PKEY_get0(get())); - } + OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get()); if (rsa == nullptr) return {}; return Rsa(rsa); #endif @@ -4136,7 +4106,7 @@ EVPKeyPointer::operator Dsa() const { int type = id(); if (type != EVP_PKEY_DSA) return {}; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return Dsa(get()); #else OSSL3_CONST DSA* dsa = EVP_PKEY_get0_DSA(get()); @@ -4147,13 +4117,13 @@ EVPKeyPointer::operator Dsa() const { bool EVPKeyPointer::validateDsaParameters() const { if (!pkey_) return false; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (EVP_default_properties_is_fips_enabled(nullptr) && EVP_PKEY_DSA == id()) { #else if (FIPS_mode() && EVP_PKEY_DSA == id()) { #endif // Validate DSA2 parameters from FIPS 186-4. -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr p; DeleteFnPtr q; if (!GetPKeyBnParam(pkey_.get(), OSSL_PKEY_PARAM_FFC_P, &p) || @@ -4432,7 +4402,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; @@ -4474,7 +4444,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 @@ -4497,7 +4467,7 @@ bool CaseInsensitiveNameEqual::operator()(std::string_view lhs, DigestCache::Result DigestCache::lookup(const char* name, uint64_t generation) const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation) return {}; const auto it = aliases_.find(name); if (it == aliases_.end()) return {}; @@ -4512,7 +4482,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 {}; } @@ -4557,7 +4527,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(); @@ -4567,7 +4537,7 @@ void DigestCache::reset(uint64_t generation) { } const DigestCache::AliasMap& DigestCache::aliases() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return aliases_; #else static const AliasMap empty; @@ -4576,7 +4546,7 @@ const DigestCache::AliasMap& DigestCache::aliases() const { } const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation) { aliases_.clear(); ciphers_.clear(); @@ -4594,7 +4564,7 @@ const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) { #endif } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_CIPHER* CipherCache::insert( const char* name, DeleteFnPtr&& cipher, @@ -4631,7 +4601,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()); @@ -4644,7 +4614,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()); @@ -4664,13 +4634,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. @@ -4703,13 +4673,13 @@ const Cipher Cipher::FromName(const char* name, CipherCache* cache) { const Cipher Cipher::FromNid(int nid, CipherCache* cache) { const EVP_CIPHER* cipher = EVP_get_cipherbynid(nid); if (cipher != nullptr) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!IsSupportedLegacyCipher(cipher)) return Cipher(); #endif return Cipher(cipher); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* name = OBJ_nid2sn(nid); if (name != nullptr) return FromName(name, cache); #else @@ -4819,7 +4789,7 @@ bool Cipher::isCcmMode() const { bool Cipher::isCtsMode() const { if (!cipher_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return (EVP_CIPHER_get_flags(cipher_) & EVP_CIPH_FLAG_CTS) != 0; #else return false; @@ -4930,7 +4900,7 @@ const char* Cipher::getName() const { const char* name = OBJ_nid2sn(nid); if (name != nullptr) return name; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_CIPHER_get0_name(cipher_); #else return {}; @@ -5027,10 +4997,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, @@ -5056,7 +5026,7 @@ bool SetCipherCtxStringParam(EVP_CIPHER_CTX* ctx, #endif bool CipherCtxPointer::setCtsMode(const char* mode) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return SetCipherCtxStringParam(ctx_.get(), OSSL_CIPHER_PARAM_CTS_MODE, mode); #else static_cast(mode); @@ -5070,7 +5040,7 @@ bool CipherCtxPointer::setPadding(bool padding) { } bool CipherCtxPointer::setXtsStandard(const char* standard) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return SetCipherCtxStringParam(ctx_.get(), kCipherParamXtsStandard, standard); #else static_cast(standard); @@ -5812,7 +5782,7 @@ bool EVPKeyCtxPointer::setDsaParameters(uint32_t bits, bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) { if (!ctx_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* group_name = OBJ_nid2sn(curve); if (group_name == nullptr) return false; @@ -5877,7 +5847,7 @@ bool EVPKeyCtxPointer::setRsaKeygenBits(int bits) { bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) { if (!ctx_) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx_.get(), e.get()) == 1; #else if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx_.get(), e.get()) == 1) { @@ -5977,11 +5947,7 @@ EVPKeyPointer EVPKeyCtxPointer::paramgen() const { bool EVPKeyCtxPointer::publicCheck() const { if (!ctx_) return false; #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 return EVP_PKEY_public_check_quick(ctx_.get()) == 1; -#else - return EVP_PKEY_public_check(ctx_.get()) == 1; -#endif #else // OPENSSL_IS_BORINGSSL // Boringssl appears not to support this operation. // TODO(jasnell): Is there an alternative approach that Boringssl does @@ -6134,7 +6100,7 @@ DataPointer CipherImpl(const EVPKeyPointer& key, } } // namespace -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER namespace { int DigestAlgorithmIdentifierToNid(const unsigned char* data, size_t size) { size_t sequence_header; @@ -6376,7 +6342,7 @@ Rsa::Rsa(OSSL3_CONST RSA* ptr) : rsa_(ptr) {} #endif const Rsa::PublicKey Rsa::getPublicKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!rsa_) return {}; return PublicKey{n_.get(), e_.get(), d_.get()}; #else @@ -6388,7 +6354,7 @@ const Rsa::PublicKey Rsa::getPublicKey() const { } const Rsa::PrivateKey Rsa::getPrivateKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!rsa_) return {}; return PrivateKey{p_.get(), q_.get(), dp_.get(), dq_.get(), qi_.get()}; #else @@ -6401,7 +6367,7 @@ const Rsa::PrivateKey Rsa::getPrivateKey() const { } const std::optional Rsa::getPssParams() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pss_params_; #else if (rsa_ == nullptr) return std::nullopt; @@ -6442,7 +6408,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_) { @@ -6481,7 +6447,7 @@ BIOPointer Rsa::derPublicKey() const { bool Rsa::setPublicKey(BignumPointer&& n, BignumPointer&& e) { if (!n || !e) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER n_.reset(n.release()); e_.reset(e.release()); rsa_ = true; @@ -6502,7 +6468,7 @@ bool Rsa::setPrivateKey(BignumPointer&& d, BignumPointer&& dp, BignumPointer&& dq, BignumPointer&& qi) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!d || !q || !p || !dp || !dq || !qi) return false; d_.reset(d.release()); q_.reset(q.release()); @@ -6584,7 +6550,7 @@ struct CipherCallbackContext { void operator()(const char* name) { cb(name); } }; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER template , #endif &context); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_CIPHER_do_all_provided(nullptr, array_push_back_provider, &context); #endif #endif @@ -6694,7 +6660,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() { @@ -6766,7 +6732,7 @@ Ec::Ec(OSSL3_CONST EC_KEY* key) : ec_(key) {} #endif const EC_GROUP* Ec::getGroup() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return ec_.get(); #else return ECKeyPointer::GetGroup(ec_); @@ -6774,7 +6740,7 @@ const EC_GROUP* Ec::getGroup() const { } const EC_POINT* Ec::getPublicKey() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return pub_.get(); #else return ECKeyPointer::GetPublicKey(ec_); @@ -6782,7 +6748,7 @@ const EC_POINT* Ec::getPublicKey() const { } point_conversion_form_t Ec::getPointConversionForm() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return form_; #else return EC_KEY_get_conv_form(ec_); @@ -7451,7 +7417,7 @@ std::pair X509Name::Iterator::operator*() const { // ============================================================================ -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Dsa::Dsa() : dsa_(false) {} Dsa::Dsa(const EVP_PKEY* pkey) : Dsa() { @@ -7468,7 +7434,7 @@ Dsa::Dsa(OSSL3_CONST DSA* dsa) : dsa_(dsa) {} #endif const BIGNUM* Dsa::getP() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return nullptr; return p_.get(); #else @@ -7480,7 +7446,7 @@ const BIGNUM* Dsa::getP() const { } const BIGNUM* Dsa::getQ() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return nullptr; return q_.get(); #else @@ -7492,7 +7458,7 @@ const BIGNUM* Dsa::getQ() const { } size_t Dsa::getModulusLength() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return 0; #else if (dsa_ == nullptr) return 0; @@ -7501,7 +7467,7 @@ size_t Dsa::getModulusLength() const { } size_t Dsa::getDivisorLength() const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (!dsa_) return 0; #else if (dsa_ == nullptr) return 0; @@ -7516,13 +7482,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()); @@ -7535,7 +7501,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()); @@ -7558,7 +7524,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; @@ -7576,7 +7542,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); @@ -7586,7 +7552,7 @@ const Digest Digest::FromName(const char* name) { } const Digest Digest::Fetch(const char* name) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER MarkPopErrorOnReturn mark_pop_error_on_return; DeleteFnPtr fetched( EVP_MD_fetch(nullptr, name, nullptr)); diff --git a/deps/ncrypto/ncrypto.gyp b/deps/ncrypto/ncrypto.gyp index 804a664fa0a2..ce6670e63bb5 100644 --- a/deps/ncrypto/ncrypto.gyp +++ b/deps/ncrypto/ncrypto.gyp @@ -5,22 +5,10 @@ 'ncrypto.cc', 'ncrypto.h', ], - 'ncrypto_engine_sources': [ - 'engine.cc', - 'ncrypto.h', - ], 'ncrypto_strict_defines': [ 'OPENSSL_API_COMPAT=30000', 'OPENSSL_NO_DEPRECATED', ], - 'ncrypto_legacy_openssl_defines': [ - 'OPENSSL_API_COMPAT=0x10100000L', - ], - 'ncrypto_engine_defines': [ - 'OPENSSL_API_COMPAT=30000', - 'OPENSSL_SUPPRESS_DEPRECATED', - 'NCRYPTO_ENGINE_COMPAT=1', - ], }, 'targets': [ { @@ -36,23 +24,15 @@ 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], }], ], }, 'sources': [ '<@(ncrypto_sources)' ], 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'defines!': [ '<@(ncrypto_legacy_openssl_defines)' ], + ['openssl_is_boringssl=="false"', { 'defines': [ '<@(ncrypto_strict_defines)' ], - 'dependencies': [ - 'ncrypto_engine', - ], - }], - ['openssl_is_boringssl=="false" and openssl_version < 0x3000000f', { - 'sources': [ '<@(ncrypto_engine_sources)' ], }], ['node_shared_openssl=="false"', { 'dependencies': [ @@ -62,27 +42,4 @@ ] }, ], - 'conditions': [ - ['openssl_is_boringssl=="false" and openssl_version >= 0x3000000f', { - 'targets': [ - { - 'target_name': 'ncrypto_engine', - 'type': 'static_library', - 'include_dirs': ['.'], - 'defines': [ - 'NCRYPTO_BSSL_LIBDECREPIT_MISSING=<(ncrypto_bssl_libdecrepit_missing)', - '<@(ncrypto_engine_defines)', - ], - 'sources': [ '<@(ncrypto_engine_sources)' ], - 'conditions': [ - ['node_shared_openssl=="false"', { - 'dependencies': [ - '../openssl/openssl.gyp:openssl' - ] - }], - ] - }, - ], - }], - ], } diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 8c09ac5f165d..100d7ae43106 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -22,16 +22,16 @@ #include #include #include -#if defined(NCRYPTO_ENGINE_COMPAT) && NCRYPTO_ENGINE_COMPAT && \ - !defined(OPENSSL_NO_ENGINE) -#include -#endif // NCRYPTO_ENGINE_COMPAT && !OPENSSL_NO_ENGINE - #ifndef OPENSSL_VERSION_PREREQ #define OPENSSL_VERSION_PREREQ(maj, min) \ (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | ((min) << 20))) #endif +// BoringSSL reports itself as OpenSSL 1.1.1, so it has to be excluded here. +#if !defined(OPENSSL_IS_BORINGSSL) && !OPENSSL_VERSION_PREREQ(3, 0) +#error "OpenSSL 1.x is no longer supported, v3.0.0 or later is required." +#endif + // BoringSSL declares the EVP_*_do_all* APIs, but their implementation may // live in libdecrepit. This matches standalone ncrypto's build flag. #ifndef NCRYPTO_BSSL_LIBDECREPIT_MISSING @@ -45,46 +45,26 @@ #endif // Backend split: -// - OpenSSL >= 3 uses provider APIs and hides deprecated low-level objects. -// - BoringSSL has its own API-compatible branch. -// - OpenSSL < 3 remains the legacy fallback branch. -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_PREREQ(3, 0) -#define NCRYPTO_USE_OPENSSL3_PROVIDER 1 -#else -#define NCRYPTO_USE_OPENSSL3_PROVIDER 0 -#endif - +// - OpenSSL uses provider APIs and hides deprecated low-level objects. +// - BoringSSL has its own API-compatible branch and keeps using the legacy +// low-level key types. #ifdef OPENSSL_IS_BORINGSSL #define NCRYPTO_USE_BORINGSSL 1 +#define NCRYPTO_USE_OPENSSL_PROVIDER 0 #else #define NCRYPTO_USE_BORINGSSL 0 +#define NCRYPTO_USE_OPENSSL_PROVIDER 1 #endif -#if !NCRYPTO_USE_OPENSSL3_PROVIDER && !NCRYPTO_USE_BORINGSSL -#define NCRYPTO_USE_LEGACY_OPENSSL 1 -#else -#define NCRYPTO_USE_LEGACY_OPENSSL 0 -#endif +#define NCRYPTO_USE_LEGACY_KEY_TYPES NCRYPTO_USE_BORINGSSL -#if NCRYPTO_USE_BORINGSSL || NCRYPTO_USE_LEGACY_OPENSSL -#define NCRYPTO_USE_LEGACY_KEY_TYPES 1 -#else -#define NCRYPTO_USE_LEGACY_KEY_TYPES 0 -#endif - -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #include #endif -// The FIPS-related functions are only available -// when the OpenSSL itself was compiled with FIPS support. -#if defined(OPENSSL_FIPS) && !OPENSSL_VERSION_PREREQ(3, 0) -#include -#endif // OPENSSL_FIPS - -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_AES_OCB 1 #else #define OPENSSL_WITH_AES_OCB 0 @@ -96,13 +76,9 @@ #define OPENSSL_WITH_ARGON2 0 #endif -#if OPENSSL_VERSION_PREREQ(3, 0) || defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_KEM 1 -#else -#define OPENSSL_WITH_KEM 0 -#endif -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OPENSSL_WITH_EVP_MAC 1 #else #define OPENSSL_WITH_EVP_MAC 0 @@ -167,7 +143,7 @@ #define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024 #endif -#if OPENSSL_VERSION_PREREQ(3, 0) +#if !defined(OPENSSL_IS_BORINGSSL) #define OSSL3_CONST const #else #define OSSL3_CONST @@ -403,7 +379,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; @@ -428,7 +404,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 @@ -461,7 +437,7 @@ class DigestCache final { Result lookup(const char* name, uint64_t generation) const; inline Result lookup(int32_t id, uint64_t generation) const { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (generation_ != generation || id == -1) return {}; const uint32_t unsigned_id = static_cast(id); if (unsigned_id < first_id_) return {}; @@ -480,7 +456,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 @@ -506,14 +482,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; @@ -547,7 +523,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; @@ -642,7 +618,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 @@ -654,14 +630,14 @@ class Cipher final { class Dsa final { public: Dsa(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Dsa(const EVP_PKEY* pkey); #else Dsa(OSSL3_CONST DSA* dsa); #endif NCRYPTO_DISALLOW_COPY_AND_MOVE(Dsa) -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline operator bool() const { return dsa_; } @@ -678,7 +654,7 @@ class Dsa final { size_t getDivisorLength() const; private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool dsa_ = false; DeleteFnPtr p_; DeleteFnPtr q_; @@ -693,14 +669,14 @@ class Dsa final { class Rsa final { public: Rsa(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Rsa(const EVP_PKEY* pkey); #else Rsa(OSSL3_CONST RSA* rsa); #endif NCRYPTO_DISALLOW_COPY_AND_MOVE(Rsa) -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline operator bool() const { return rsa_; } @@ -753,7 +729,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_; @@ -773,7 +749,7 @@ class Rsa final { class Ec final { public: Ec(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit Ec(const EVP_PKEY* pkey); #else Ec(OSSL3_CONST EC_KEY* key); @@ -796,7 +772,7 @@ class Ec final { static bool GetCurves(GetCurveCallback callback); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr ec_; DeleteFnPtr pub_; point_conversion_form_t form_ = POINT_CONVERSION_UNCOMPRESSED; @@ -1144,7 +1120,7 @@ class EVPKeyPointer final { const Buffer& data); #endif static EVPKeyPointer NewDH(DHPointer&& dh); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER static EVPKeyPointer NewRSA(const Rsa& rsa); #else static EVPKeyPointer NewRSA(RSAPointer&& rsa); @@ -1309,7 +1285,7 @@ class DHPointer final { static DHPointer New(size_t bits, unsigned int generator); DHPointer() = default; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER explicit DHPointer(EVPKeyPointer&& key, const char* group_name = nullptr); DHPointer(BignumPointer&& p, BignumPointer&& g, const char* group_name); #else @@ -1320,7 +1296,7 @@ class DHPointer final { NCRYPTO_DISALLOW_COPY(DHPointer) ~DHPointer(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline bool operator==(std::nullptr_t) noexcept { return !operator bool(); } @@ -1389,7 +1365,7 @@ class DHPointer final { const EVPKeyPointer& theirKey); private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr dh_; BignumPointer p_; BignumPointer g_; @@ -1717,7 +1693,7 @@ class ECKeyPointer final { NCRYPTO_DISALLOW_COPY(ECKeyPointer) ~ECKeyPointer(); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER inline bool operator==(std::nullptr_t) noexcept { return group_ == nullptr; } @@ -1761,7 +1737,7 @@ class ECKeyPointer final { #endif private: -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER DeleteFnPtr group_; DeleteFnPtr pub_; DeleteFnPtr priv_; @@ -1941,44 +1917,6 @@ class HMACCtxPointer final { }; #endif // OPENSSL_WITH_EVP_MAC -#ifndef OPENSSL_NO_ENGINE -class EnginePointer final { - public: - EnginePointer() = default; - - explicit EnginePointer(void* engine_, bool finish_on_exit = false); - EnginePointer(EnginePointer&& other) noexcept; - EnginePointer& operator=(EnginePointer&& other) noexcept; - NCRYPTO_DISALLOW_COPY(EnginePointer) - ~EnginePointer(); - - inline operator bool() const { return engine != nullptr; } - inline void setFinishOnExit() { finish_on_exit = true; } - - void reset(void* engine_ = nullptr, bool finish_on_exit_ = false); - - bool setAsDefault(uint32_t flags, CryptoErrorList* errors = nullptr); - bool init(bool finish_on_exit = false); - EVPKeyPointer loadPrivateKey(const char* key_name); - bool setClientCertEngine(SSL_CTX* ctx); - - void* release(); - - // Retrieve an OpenSSL Engine instance by name. If the name does not - // identify a valid named engine, the returned EnginePointer will be - // empty. - static EnginePointer getEngineByName(const char* name, - CryptoErrorList* errors = nullptr); - - // Call once when initializing OpenSSL at startup for the process. - static void initEnginesOnce(); - - private: - void* engine = nullptr; - bool finish_on_exit = false; -}; -#endif // !OPENSSL_NO_ENGINE - // ============================================================================ // FIPS bool isFipsEnabled(); diff --git a/deps/ncrypto/unofficial.gni b/deps/ncrypto/unofficial.gni index dad4fbbf16f0..7cb27d22b9b8 100644 --- a/deps/ncrypto/unofficial.gni +++ b/deps/ncrypto/unofficial.gni @@ -26,11 +26,7 @@ template("ncrypto_gn_build") { source_set(target_name) { forward_variables_from(invoker, "*") public_configs = [ ":ncrypto_config" ] - defines = [ - "NCRYPTO_ENGINE_COMPAT=1", - "OPENSSL_SUPPRESS_DEPRECATED", - ] - sources = gypi_values.ncrypto_sources + gypi_values.ncrypto_engine_sources + sources = gypi_values.ncrypto_sources deps = [ "$node_openssl_path" ] } } diff --git a/deps/openssl/openssl.gyp b/deps/openssl/openssl.gyp index 144085fd33df..d11f72a758d8 100644 --- a/deps/openssl/openssl.gyp +++ b/deps/openssl/openssl.gyp @@ -98,36 +98,6 @@ }, }], ] - }, { - # openssl-fipsmodule target - 'target_name': 'openssl-fipsmodule', - 'type': 'shared_library', - 'dependencies': ['openssl-cli'], - 'includes': ['./openssl_common.gypi'], - 'include_dirs+': ['openssl/apps/include'], - 'cflags': [ '-fPIC' ], - #'ldflags': [ '-o', 'fips.so' ], - #'ldflags': [ '-Wl,--version-script=providers/fips.ld',], - 'conditions': [ - [ 'openssl_no_asm==1', { - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'target_arch=="arm64" and OS=="win"', { - # VC-WIN64-ARM inherits from VC-noCE-common that has no asms. - 'includes': ['./openssl-fips_no_asm.gypi'], - }, 'gas_version and v(gas_version) >= v("2.26") or ' - 'nasm_version and v(nasm_version) >= v("2.11.8") or ' - 'llvm_version and v(llvm_version) >= v("8.0")', { - # Require AVX512IFMA supported. See - # https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html - # Currently crypto/poly1305/asm/poly1305-x86_64.pl requires AVX512IFMA. - 'includes': ['./openssl-fips_asm.gypi'], - }, { - 'includes': ['./openssl-fips_asm_avx2.gypi'], - }], - ], - 'direct_dependent_settings': { - 'include_dirs': [ 'openssl/include', 'openssl/crypto/include'] - } - }, + }, ] } diff --git a/doc/api/cli.md b/doc/api/cli.md index 6ba509d25692..9337c5370247 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -884,9 +884,8 @@ priority than `--dns-result-order`. added: v6.0.0 --> -Enable [FIPS mode][] at startup. With OpenSSL 3, a configured provider named -`fips` must be available and initialize successfully. With OpenSSL 1.1.1, -Node.js must be built against a FIPS-capable OpenSSL. +Enable [FIPS mode][] at startup. A configured provider named `fips` must be +available and initialize successfully. ### `--enable-source-maps` @@ -2288,8 +2287,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. @@ -2301,7 +2299,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 8d80bdc299aa..badfbc08ce38 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3661,8 +3661,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][] @@ -3766,8 +3766,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][] @@ -4349,7 +4349,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) @@ -4421,7 +4421,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) @@ -4434,18 +4434,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)). @@ -4105,8 +4108,8 @@ that are shorter than the default authentication tag length (i.e., shorter than -Type: Runtime +Type: End-of-Life -OpenSSL 3 has deprecated support for custom engines with a recommendation to -switch to its new provider model. The `clientCertEngine` option for -`https.request()`, [`tls.createSecureContext()`][], and [`tls.createServer()`][]; -the `privateKeyEngine` and `privateKeyIdentifier` for [`tls.createSecureContext()`][]; -and [`crypto.setEngine()`][] all depend on this functionality from OpenSSL. +The `crypto.setEngine()` API and the `crypto.constants.ENGINE_METHOD_*` +constants have been removed. The `clientCertEngine` option for +[`https.request()`][], [`tls.createSecureContext()`][], and +[`tls.createServer()`][] and the `privateKeyEngine` and `privateKeyIdentifier` +options for [`tls.createSecureContext()`][] now throw +`ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED` when used. There is no direct +replacement API in Node.js. OpenSSL's provider model replaces engines upstream. ### DEP0184: Instantiating `node:zlib` classes without `new` @@ -4842,11 +4847,9 @@ async function example() { [`crypto.createDecipheriv()`]: crypto.md#cryptocreatedecipherivalgorithm-key-iv-options [`crypto.createHash()`]: crypto.md#cryptocreatehashalgorithm-options [`crypto.createHmac()`]: crypto.md#cryptocreatehmacalgorithm-key-options -[`crypto.fips`]: crypto.md#cryptofips [`crypto.pbkdf2()`]: crypto.md#cryptopbkdf2password-salt-iterations-keylen-digest-callback [`crypto.randomBytes()`]: crypto.md#cryptorandombytessize-callback [`crypto.scrypt()`]: crypto.md#cryptoscryptpassword-salt-keylen-options-callback -[`crypto.setEngine()`]: crypto.md#cryptosetengineengine-flags [`decipher.final()`]: crypto.md#decipherfinaloutputencoding [`decipher.setAuthTag()`]: crypto.md#deciphersetauthtagbuffer-encoding [`dirent.parentPath`]: fs.md#direntparentpath diff --git a/doc/api/errors.md b/doc/api/errors.md index 97eca0951cc8..cf47ec322a89 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -885,9 +885,8 @@ Argon2 is not supported by the current version of OpenSSL being used. ### `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED` -An OpenSSL engine was requested (for example, through the `clientCertEngine` or -`privateKeyEngine` TLS options) that is not supported by the version of OpenSSL -being used, likely due to the compile-time flag `OPENSSL_NO_ENGINE`. +An OpenSSL engine-based TLS or HTTPS option was used after support for custom +engines reached End-of-Life in Node.js. @@ -904,13 +903,6 @@ An invalid value for the `key` argument has been passed to the `crypto.ECDH()` class `computeSecret()` method. It means that the public key lies outside of the elliptic curve. - - -### `ERR_CRYPTO_ENGINE_UNKNOWN` - -An invalid crypto engine identifier was passed to -[`require('node:crypto').setEngine()`][]. - ### `ERR_CRYPTO_FIPS_FORCED` @@ -4719,7 +4711,6 @@ An error occurred trying to allocate memory. This should never happen. [`process.send()`]: process.md#processsendmessage-sendhandle-options-callback [`process.setUncaughtExceptionCaptureCallback()`]: process.md#processsetuncaughtexceptioncapturecallbackfn [`readable._read()`]: stream.md#readable_readsize -[`require('node:crypto').setEngine()`]: crypto.md#cryptosetengineengine-flags [`require()`]: modules.md#requireid [`server.close()`]: net.md#serverclosecallback [`server.listen()`]: net.md#serverlisten diff --git a/doc/api/https.md b/doc/api/https.md index eba303b6600a..c4a95ee67491 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -428,8 +428,9 @@ a `timeout` of 5 seconds. added: v0.3.6 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine` option is runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v22.4.0 - v20.16.0 @@ -471,10 +472,9 @@ changes: Makes a request to a secure web server. The following additional `options` from [`tls.connect()`][] are also accepted: -`ca`, `cert`, `ciphers`, `clientCertEngine` (deprecated), `crl`, `dhparam`, `ecdhCurve`, -`honorCipherOrder`, `key`, `passphrase`, `pfx`, `rejectUnauthorized`, -`secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`, -`highWaterMark`. +`ca`, `cert`, `ciphers`, `crl`, `dhparam`, `ecdhCurve`, `honorCipherOrder`, +`key`, `passphrase`, `pfx`, `rejectUnauthorized`, `secureOptions`, +`secureProtocol`, `servername`, `sessionIdContext`, `highWaterMark`. `options` can be an object, a string, or a [`URL`][] object. If `options` is a string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][] diff --git a/doc/api/permissions.md b/doc/api/permissions.md index 0b46f42d982a..8dbab80c0b52 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -346,8 +346,6 @@ There are constraints you need to know before using this system: to read files before environment initialization. As a result, such flags are not subject to the rules of the Permission Model. The same applies for V8 flags that can be set via runtime through `v8.setFlagsFromString`. -* OpenSSL engines cannot be requested at runtime when the Permission - Model is enabled, affecting the built-in crypto, https, and tls modules. * Run-Time Loadable Extensions cannot be loaded when the Permission Model is enabled, affecting the sqlite module. * Using existing file descriptors via the `node:fs` module bypasses the diff --git a/doc/api/tls.md b/doc/api/tls.md index 34f8c3b99e93..20eb161a2437 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -182,8 +182,8 @@ On the client connection, a custom `checkServerIdentity` should be passed because the default one will fail in the absence of a certificate. According to the [RFC 4279][], PSK identities up to 128 bytes in length and -PSKs up to 64 bytes in length must be supported. As of OpenSSL 1.1.0 -maximum identity size is 128 bytes, and maximum PSK length is 256 bytes. +PSKs up to 64 bytes in length must be supported. In OpenSSL the maximum +identity size is 128 bytes, and the maximum PSK length is 256 bytes. The current implementation doesn't support asynchronous PSK callbacks due to the limitations of the underlying OpenSSL API. @@ -1236,7 +1236,7 @@ For example, a TLSv1.2 protocol with AES256-SHA cipher: ``` See -[SSL\_CIPHER\_get\_name](https://www.openssl.org/docs/man1.1.1/man3/SSL_CIPHER_get_name.html) +[SSL\_CIPHER\_get\_name](https://www.openssl.org/docs/man3.0/man3/SSL_CIPHER_get_name.html) for more information. ### `tlsSocket.getEphemeralKeyInfo()` @@ -1488,7 +1488,7 @@ added: v12.11.0 the client in the order of decreasing preference. See -[SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_shared_sigalgs.html) +[SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man3.0/man3/SSL_get_shared_sigalgs.html) for more information. ### `tlsSocket.getTLSTicket()` @@ -1966,9 +1966,10 @@ argument. added: v0.11.13 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine`, `privateKeyEngine` and - `privateKeyIdentifier` options are runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine`, `privateKeyEngine`, or + `privateKeyIdentifier` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v26.4.0 - v24.19.0 @@ -2077,14 +2078,12 @@ changes: The list can contain digest algorithms (`SHA256`, `MD5` etc.), public key algorithms (`RSA-PSS`, `ECDSA` etc.), combination of both (e.g 'RSA+SHA384') or TLS v1.3 scheme names (e.g. `rsa_pss_pss_sha512`). - See [OpenSSL man pages](https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set1_sigalgs_list.html) + See [OpenSSL man pages](https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set1_sigalgs_list.html) for more info. * `ciphers` {string} Cipher suite specification, replacing the default. For more information, see [Modifying the default TLS cipher suite][]. Permitted ciphers can be obtained via [`tls.getCiphers()`][]. Cipher names must be uppercased in order for OpenSSL to accept them. - * `clientCertEngine` {string} Name of an OpenSSL engine which can provide the - client certificate. **Deprecated.** * `crl` {string|string\[]|Buffer|Buffer\[]} PEM formatted CRLs (Certificate Revocation Lists). * `dhparam` {string|Buffer} `'auto'` or custom Diffie-Hellman parameters, @@ -2115,12 +2114,6 @@ changes: occur in an array. `object.passphrase` is optional. Encrypted keys will be decrypted with `object.passphrase` if provided, or `options.passphrase` if it is not. - * `privateKeyEngine` {string} Name of an OpenSSL engine to get private key - from. Should be used together with `privateKeyIdentifier`. **Deprecated.** - * `privateKeyIdentifier` {string} Identifier of a private key managed by - an OpenSSL engine. Should be used together with `privateKeyEngine`. - Should not be set together with `key`, because both options define a - private key in different ways. **Deprecated.** * `maxVersion` {string} Optionally set the maximum TLS version to allow. One of `'TLSv1.3'`, `'TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified along with the `secureProtocol` option; use one or the other. @@ -2194,8 +2187,9 @@ permissible, use 2048 bits or larger for stronger security. added: v0.3.2 changes: - version: REPLACEME - pr-url: https://github.com/nodejs/node/pull/63966 - description: The `clientCertEngine` option is runtime deprecated. + pr-url: https://github.com/nodejs/node/pull/64777 + description: Using the `clientCertEngine` option now throws + `ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED`. - version: - v22.4.0 - v20.16.0 @@ -2246,8 +2240,6 @@ changes: If a string is returned that does not match one of the client's ALPN protocols, an error will be thrown. This option cannot be used with the `ALPNProtocols` option, and setting both options will throw an error. - * `clientCertEngine` {string} Name of an OpenSSL engine which can provide the - client certificate. **Deprecated.** * `enableTrace` {boolean} If `true`, [`tls.TLSSocket.enableTrace()`][] will be called on new connections. Tracing can be enabled after the secure connection is established, but this option must be used to trace the secure @@ -2584,7 +2576,7 @@ added: v0.11.3 [RFC 5077]: https://tools.ietf.org/html/rfc5077 [RFC 5929]: https://tools.ietf.org/html/rfc5929 [RFC 8879]: https://tools.ietf.org/html/rfc8879 -[SSL_METHODS]: https://www.openssl.org/docs/man1.1.1/man7/ssl.html#Dealing-with-Protocol-Methods +[SSL_METHODS]: https://www.openssl.org/docs/man3.0/man7/ssl.html#Dealing-with-Protocol-Methods [Session Resumption]: #session-resumption [Stream]: stream.md#stream [TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS @@ -2601,8 +2593,8 @@ added: v0.11.3 [`Duplex`]: stream.md#class-streamduplex [`NODE_EXTRA_CA_CERTS`]: cli.md#node_extra_ca_certsfile [`NODE_OPTIONS`]: cli.md#node_optionsoptions -[`SSL_export_keying_material`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_export_keying_material.html -[`SSL_get_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html +[`SSL_export_keying_material`]: https://www.openssl.org/docs/man3.0/man3/SSL_export_keying_material.html +[`SSL_get_version`]: https://www.openssl.org/docs/man3.0/man3/SSL_get_version.html [`crypto.getCurves()`]: crypto.md#cryptogetcurves [`import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [`net.Server.address()`]: net.md#serveraddress @@ -2637,6 +2629,6 @@ added: v0.11.3 [`x509.checkHost()`]: crypto.md#x509checkhostname-options [asn1.js]: https://www.npmjs.com/package/asn1.js [certificate object]: #certificate-object -[cipher list format]: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html#CIPHER-LIST-FORMAT +[cipher list format]: https://www.openssl.org/docs/man3.0/man1/ciphers.html#CIPHER-LIST-FORMAT [forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy [perfect forward secrecy]: #perfect-forward-secrecy diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 6e2acacd5854..bf91a29d1250 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -119,15 +119,15 @@ WICG proposal: Algorithms: -* `'AES-OCB'`[^openssl30] +* `'AES-OCB'`[^noboringssl] * `'Argon2d'`[^openssl32] * `'Argon2i'`[^openssl32] * `'Argon2id'`[^openssl32] * `'ChaCha20-Poly1305'` * `'cSHAKE128'` * `'cSHAKE256'` -* `'KMAC128'`[^openssl30] -* `'KMAC256'`[^openssl30] +* `'KMAC128'`[^noboringssl] +* `'KMAC256'`[^noboringssl] * `'KT128'` * `'KT256'` * `'ML-DSA-44'`[^openssl35] @@ -2721,7 +2721,7 @@ added: [^modern-algos]: See [Modern Algorithms in the Web Cryptography API][] -[^openssl30]: Requires OpenSSL >= 3.0 +[^noboringssl]: Not available when Node.js is built against BoringSSL [^openssl32]: Requires OpenSSL >= 3.2 diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 4618a5f17df1..57c79ea2ba6c 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -405,7 +405,7 @@ }, "openssl-legacy-provider": { "type": "boolean", - "description": "enable OpenSSL 3.0 legacy provider" + "description": "enable OpenSSL's legacy provider" }, "openssl-shared-config": { "type": "boolean", diff --git a/doc/node.1 b/doc/node.1 index 96f1c0f5867e..38f797785b23 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -513,9 +513,8 @@ The default is \fBverbatim\fR and \fBdns.setDefaultResultOrder()\fR have higher priority than \fB--dns-result-order\fR. . .It Fl -enable-fips -Enable FIPS mode at startup. With OpenSSL 3, a configured provider named -\fBfips\fR must be available and initialize successfully. With OpenSSL 1.1.1, -Node.js must be built against a FIPS-capable OpenSSL. +Enable FIPS mode at startup. A configured provider named \fBfips\fR must be +available and initialize successfully. . .It Fl -enable-source-maps Enable Source Map support for stack traces. @@ -1145,12 +1144,11 @@ usually only useful for developers debugging Node.js itself. . .It Fl -openssl-config Ns = Ns Ar file Load an OpenSSL configuration file on startup. The file can activate an -OpenSSL 3 FIPS provider or configure a FIPS-capable OpenSSL 1.1.1 build. See -FIPS mode. +OpenSSL FIPS provider. See FIPS mode. This option takes precedence over the \fBOPENSSL_CONF\fR environment variable. . .It Fl -openssl-legacy-provider -Enable OpenSSL 3.0 legacy provider. For more information please see +Enable OpenSSL's legacy provider. For more information please see OSSL_PROVIDER-legacy. . .It Fl -openssl-shared-config diff --git a/lib/crypto.js b/lib/crypto.js index ac4b0a33efb8..e1de96dd14d3 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -119,7 +119,6 @@ const { getCiphers, getCurves, getHashes, - setEngine, secureHeapUsed, } = require('internal/crypto/util'); const Certificate = require('internal/crypto/certificate'); @@ -225,7 +224,6 @@ module.exports = { scrypt, scryptSync, sign: signOneShot, - setEngine, timingSafeEqual, getFips, setFips, @@ -340,13 +338,6 @@ function getRandomBytesAlias(key) { } ObjectDefineProperties(module.exports, { - fips: { - __proto__: null, - get: deprecate(getFips, 'The crypto.fips is deprecated. ' + - 'Please use crypto.getFips()', 'DEP0093'), - set: deprecate(setFips, 'The crypto.fips is deprecated. ' + - 'Please use crypto.setFips()', 'DEP0093'), - }, constants: { __proto__: null, configurable: false, diff --git a/lib/https.js b/lib/https.js index 6ae2e5d8a213..d1bc8287c75a 100644 --- a/lib/https.js +++ b/lib/https.js @@ -49,6 +49,9 @@ const { ERR_PROXY_TUNNEL } = require('internal/errors').codes; assertCrypto(); const tls = require('tls'); +const { + validateOpenSSLEngineOptions, +} = require('internal/tls/secure-context'); const kPerRequestCheckServerIdentity = Symbol('per-request checkServerIdentity'); let perRequestCheckServerIdentityIndex = 0; const { @@ -465,6 +468,7 @@ function Agent(options) { return new Agent(options); options = { __proto__: null, ...options }; + validateOpenSSLEngineOptions(options); options.defaultPort ??= 443; options.protocol ??= 'https:'; FunctionPrototypeCall(HttpAgent, this, options); @@ -513,6 +517,7 @@ function getPfxAgentKey(pfx, passphrase) { * @returns {string} */ Agent.prototype.getName = function getName(options = kEmptyObject) { + validateOpenSSLEngineOptions(options); let name = FunctionPrototypeCall(HttpAgent.prototype.getName, this, options); name += ':'; @@ -523,10 +528,6 @@ Agent.prototype.getName = function getName(options = kEmptyObject) { if (options.cert) name += options.cert; - name += ':'; - if (options.clientCertEngine) - name += options.clientCertEngine; - name += ':'; if (options.ciphers) name += options.ciphers; @@ -587,14 +588,6 @@ Agent.prototype.getName = function getName(options = kEmptyObject) { if (options.sigalgs) name += JSONStringify(options.sigalgs); - name += ':'; - if (options.privateKeyIdentifier) - name += options.privateKeyIdentifier; - - name += ':'; - if (options.privateKeyEngine) - name += options.privateKeyEngine; - if (options[kPerRequestCheckServerIdentity]) name += `:${options[kPerRequestCheckServerIdentity]}`; @@ -670,6 +663,7 @@ function request(...args) { if (args[0] && typeof args[0] !== 'function') { ObjectAssign(options, ArrayPrototypeShift(args)); } + validateOpenSSLEngineOptions(options); if (options.checkServerIdentity !== undefined && options.checkServerIdentity !== tls.checkServerIdentity && diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index 1de25e514793..ff4ebd8caf60 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -36,7 +36,6 @@ const { getCiphers: _getCiphers, getCurves: _getCurves, getHashes: _getHashes, - setEngine: _setEngine, secureHeapUsed: _secureHeapUsed, getCachedAliases, getOpenSSLSecLevelCrypto: getOpenSSLSecLevel, @@ -57,18 +56,10 @@ const isFips = getFipsCrypto() === 1; const { getOptionValue } = require('internal/options'); -const { - crypto: { - ENGINE_METHOD_ALL, - }, -} = internalBinding('constants'); - const normalizeHashName = require('internal/crypto/hashnames'); const { codes: { - ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED, - ERR_CRYPTO_ENGINE_UNKNOWN, ERR_INVALID_ARG_TYPE, }, hideStackFrames, @@ -76,7 +67,6 @@ const { const { validateArray, - validateNumber, validateString, } = require('internal/validators'); @@ -86,7 +76,6 @@ const { cachedResult, emitExperimentalWarning, filterDuplicateStrings, - getDeprecationWarningEmitter, lazyDOMException, setOwnProperty, } = require('internal/util'); @@ -174,29 +163,6 @@ const getHashes = cachedArrayByFipsGeneration( const getCurves = cachedResult(() => filterDuplicateStrings(_getCurves())); -const emitOpenSSLEngineDeprecation = getDeprecationWarningEmitter( - 'DEP0183', - 'OpenSSL engine-based APIs are deprecated.', -); - -function setEngine(id, flags) { - validateString(id, 'id'); - if (flags) - validateNumber(flags, 'flags'); - flags = flags >>> 0; - - // Use provided engine for everything by default - if (flags === 0) - flags = ENGINE_METHOD_ALL; - - emitOpenSSLEngineDeprecation(); - - if (typeof _setEngine !== 'function') - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - if (!_setEngine(id, flags)) - throw new ERR_CRYPTO_ENGINE_UNKNOWN(id); -} - const getArrayBufferOrView = hideStackFrames((buffer, name, encoding) => { if (isAnyArrayBuffer(buffer)) return buffer; @@ -1144,9 +1110,7 @@ module.exports = { getDataViewOrTypedArrayBuffer, getHashes, getOptionalByteLength, - emitOpenSSLEngineDeprecation, kHandle, - setEngine, toBuf, kNamedCurveAliases, diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 438bde842d8b..92ecdd2956dd 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1170,11 +1170,10 @@ E('ERR_CONSTRUCT_CALL_REQUIRED', 'Class constructor %s cannot be invoked without E('ERR_CONTEXT_NOT_INITIALIZED', 'context used is not initialized', Error); E('ERR_CRYPTO_ARGON2_NOT_SUPPORTED', 'Argon2 algorithm not supported', Error); E('ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - 'Custom engines not supported by this OpenSSL', Error); + 'Custom engines not supported by this version of Node.js', Error); E('ERR_CRYPTO_ECDH_INVALID_FORMAT', 'Invalid ECDH format: %s', TypeError); E('ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY', 'Public key is not valid for specified curve', Error); -E('ERR_CRYPTO_ENGINE_UNKNOWN', 'Engine "%s" was not found', Error); E('ERR_CRYPTO_FIPS_FORCED', 'Cannot set FIPS mode, it was forced with --force-fips at startup.', Error); E('ERR_CRYPTO_FIPS_UNAVAILABLE', 'Cannot set FIPS mode in a non-FIPS build.', diff --git a/lib/internal/tls/secure-context.js b/lib/internal/tls/secure-context.js index 597d4fce9271..9dccdb8aacfd 100644 --- a/lib/internal/tls/secure-context.js +++ b/lib/internal/tls/secure-context.js @@ -34,7 +34,6 @@ const { } = require('internal/validators'); const { - emitOpenSSLEngineDeprecation, toBuf, } = require('internal/crypto/util'); @@ -128,8 +127,26 @@ function processCiphers(ciphers, name) { return { cipherList, cipherSuites }; } +function validateOpenSSLEngineOptions(options) { + const { + clientCertEngine, + privateKeyEngine, + privateKeyIdentifier, + } = options; + + // OpenSSL engine support has reached End-of-Life. Keep recognizing these + // options so that their use throws instead of appearing to work while being + // silently ignored. + if (clientCertEngine != null || + privateKeyEngine != null || + privateKeyIdentifier != null) { + throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); + } +} + function configSecureContext(context, options = kEmptyObject, name = 'options') { validateObject(options, name); + validateOpenSSLEngineOptions(options); const { allowPartialTrustChain, @@ -137,15 +154,12 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') cert, certificateCompression, ciphers = getDefaultCiphers(), - clientCertEngine, crl, dhparam, ecdhCurve = getDefaultEcdhCurve(), key, passphrase, pfx, - privateKeyIdentifier, - privateKeyEngine, sessionIdContext, sessionTimeout, sigalgs, @@ -256,36 +270,6 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') context.setSigalgs(sigalgs); } - if (privateKeyIdentifier !== undefined && privateKeyIdentifier !== null) { - if (privateKeyEngine === undefined || privateKeyEngine === null) { - // Engine is required when privateKeyIdentifier is present - throw new ERR_INVALID_ARG_VALUE(`${name}.privateKeyEngine`, - privateKeyEngine); - } - if (key) { - // Both data key and engine key can't be set at the same time - throw new ERR_INVALID_ARG_VALUE(`${name}.privateKeyIdentifier`, - privateKeyIdentifier); - } - - if (typeof privateKeyIdentifier === 'string' && - typeof privateKeyEngine === 'string') { - emitOpenSSLEngineDeprecation(); - if (context.setEngineKey) - context.setEngineKey(privateKeyIdentifier, privateKeyEngine); - else - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - } else if (typeof privateKeyIdentifier !== 'string') { - throw new ERR_INVALID_ARG_TYPE(`${name}.privateKeyIdentifier`, - ['string', 'null', 'undefined'], - privateKeyIdentifier); - } else { - throw new ERR_INVALID_ARG_TYPE(`${name}.privateKeyEngine`, - ['string', 'null', 'undefined'], - privateKeyEngine); - } - } - validateString(ecdhCurve, `${name}.ecdhCurve`); context.setECDHCurve(ecdhCurve); @@ -331,18 +315,6 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') } } - if (typeof clientCertEngine === 'string') { - emitOpenSSLEngineDeprecation(); - if (typeof context.setClientCertEngine !== 'function') - throw new ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED(); - else - context.setClientCertEngine(clientCertEngine); - } else if (clientCertEngine !== undefined && clientCertEngine !== null) { - throw new ERR_INVALID_ARG_TYPE(`${name}.clientCertEngine`, - ['string', 'null', 'undefined'], - clientCertEngine); - } - if (ticketKeys !== undefined && ticketKeys !== null) { validateBuffer(ticketKeys, `${name}.ticketKeys`); if (ticketKeys.byteLength !== 48) { @@ -362,4 +334,5 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') module.exports = { configSecureContext, + validateOpenSSLEngineOptions, }; diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js index 1c6e0577ce3d..862701488e1e 100644 --- a/lib/internal/tls/wrap.js +++ b/lib/internal/tls/wrap.js @@ -46,6 +46,9 @@ const EE = require('events'); const net = require('net'); const tls = require('tls'); const common = require('internal/tls/common'); +const { + validateOpenSSLEngineOptions, +} = require('internal/tls/secure-context'); const { kReinitializeHandle } = require('internal/net'); const JSStreamSocket = require('internal/js_stream_socket'); const { Buffer } = require('buffer'); @@ -620,6 +623,7 @@ function initRead(tlsSocket, socket) { function TLSSocket(socket, opts) { const tlsOptions = { ...opts }; + validateOpenSSLEngineOptions(tlsOptions); let enableTrace = tlsOptions.enableTrace; if (enableTrace == null) { @@ -1440,7 +1444,6 @@ function tlsConnectionListener(rawSocket) { // - rejectUnauthorized. Boolean, default to true. // - key. string. // - cert: string. -// - clientCertEngine: string. // - ca: string or array of strings. // - sessionTimeout: integer. // @@ -1532,6 +1535,7 @@ exports.createServer = function createServer(options, listener) { Server.prototype.setSecureContext = function(options) { validateObject(options, 'options'); + validateOpenSSLEngineOptions(options); if (options.pfx) this.pfx = options.pfx; @@ -1553,11 +1557,6 @@ Server.prototype.setSecureContext = function(options) { else this.cert = undefined; - if (options.clientCertEngine) - this.clientCertEngine = options.clientCertEngine; - else - this.clientCertEngine = undefined; - if (options.ca) this.ca = options.ca; else @@ -1624,8 +1623,6 @@ Server.prototype.setSecureContext = function(options) { if (options.ticketKeys) this.ticketKeys = options.ticketKeys; - this.privateKeyIdentifier = options.privateKeyIdentifier; - this.privateKeyEngine = options.privateKeyEngine; this.certificateCompression = options.certificateCompression; this._sharedCreds = tls.createSecureContext({ @@ -1633,7 +1630,6 @@ Server.prototype.setSecureContext = function(options) { key: this.key, passphrase: this.passphrase, cert: this.cert, - clientCertEngine: this.clientCertEngine, ca: this.ca, ciphers: this.ciphers, sigalgs: this.sigalgs, @@ -1648,8 +1644,6 @@ Server.prototype.setSecureContext = function(options) { sessionIdContext: this.sessionIdContext, ticketKeys: this.ticketKeys, sessionTimeout: this.sessionTimeout, - privateKeyIdentifier: this.privateKeyIdentifier, - privateKeyEngine: this.privateKeyEngine, certificateCompression: this.certificateCompression, }); }; @@ -1847,6 +1841,7 @@ exports.connect = function connect(...args) { minDHSize: 1024, ...options, }; + validateOpenSSLEngineOptions(options); if (!options.keepAlive) options.singleUse = true; diff --git a/node.gyp b/node.gyp index b99755575020..427b371ad65a 100644 --- a/node.gyp +++ b/node.gyp @@ -749,87 +749,22 @@ }, }, }], - ['node_fipsinstall=="true"', { - 'variables': { - 'openssl-cli': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)openssl-cli<(EXECUTABLE_SUFFIX)', - 'provider_name': 'libopenssl-fipsmodule', - 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', - 'conditions': [ - ['GENERATOR == "ninja"', { - 'fipsmodule_internal': '<(PRODUCT_DIR)/lib/<(provider_name).so', - 'fipsmodule': '<(PRODUCT_DIR)/obj/lib/openssl-modules/fips.so', - 'fipsconfig': '<(PRODUCT_DIR)/obj/lib/fipsmodule.cnf', - 'opensslconfig_internal': '<(PRODUCT_DIR)/obj/lib/openssl.cnf', - }, { - 'fipsmodule_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/<(provider_name).so', - 'fipsmodule': '<(PRODUCT_DIR)/obj.target/deps/openssl/lib/openssl-modules/fips.so', - 'fipsconfig': '<(PRODUCT_DIR)/obj.target/deps/openssl/fipsmodule.cnf', - 'opensslconfig_internal': '<(PRODUCT_DIR)/obj.target/deps/openssl/openssl.cnf', - }], - ], - }, - 'actions': [ - { - 'action_name': 'fipsinstall', - 'process_outputs_as_sources': 1, - 'inputs': [ - '<(fipsmodule_internal)', - ], - 'outputs': [ - '<(fipsconfig)', - ], - 'action': [ - '<(openssl-cli)', 'fipsinstall', - '-provider_name', '<(provider_name)', - '-module', '<(fipsmodule_internal)', - '-out', '<(fipsconfig)', - #'-quiet', - ], - }, - { - 'action_name': 'copy_fips_module', - 'inputs': [ - '<(fipsmodule_internal)', - ], - 'outputs': [ - '<(fipsmodule)', - ], - 'action': [ - '<(python)', 'tools/copyfile.py', - '<(fipsmodule_internal)', - '<(fipsmodule)', - ], - }, - { - 'action_name': 'copy_openssl_cnf_and_include_fips_cnf', - 'inputs': [ '<(opensslconfig)', ], - 'outputs': [ '<(opensslconfig_internal)', ], - 'action': [ - '<(python)', 'tools/enable_fips_include.py', - '<(opensslconfig)', - '<(opensslconfig_internal)', - '<(fipsconfig)', - ], - }, + ], + 'variables': { + 'opensslconfig_internal': '<(obj_dir)/deps/openssl/openssl.cnf', + 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', + }, + 'actions': [ + { + 'action_name': 'reset_openssl_cnf', + 'inputs': [ '<(opensslconfig)', ], + 'outputs': [ '<(opensslconfig_internal)', ], + 'action': [ + '<(python)', 'tools/copyfile.py', + '<(opensslconfig)', + '<(opensslconfig_internal)', ], - }, { - 'variables': { - 'opensslconfig_internal': '<(obj_dir)/deps/openssl/openssl.cnf', - 'opensslconfig': './deps/openssl/nodejs-openssl.cnf', - }, - 'actions': [ - { - 'action_name': 'reset_openssl_cnf', - 'inputs': [ '<(opensslconfig)', ], - 'outputs': [ '<(opensslconfig_internal)', ], - 'action': [ - '<(python)', 'tools/copyfile.py', - '<(opensslconfig)', - '<(opensslconfig_internal)', - ], - }, - ], - }], + }, ], }, # node_core_target_name { diff --git a/src/crypto/README.md b/src/crypto/README.md index 4bfec21359e0..8f696def87c1 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -96,8 +96,8 @@ using CipherCtxPointer = DeleteFnPtr; Examples of these being used are pervasive through the `src/crypto` code. `HMACCtxPointer` is a dedicated HMAC state wrapper rather than a plain -`DeleteFnPtr` alias. On OpenSSL 3 and later it owns the provider-backed -`EVP_MAC`/`EVP_MAC_CTX` state. On OpenSSL 1.1.1 and BoringSSL it owns the +`DeleteFnPtr` alias. On OpenSSL it owns the provider-backed +`EVP_MAC`/`EVP_MAC_CTX` state. On BoringSSL it owns the legacy `HMAC_CTX` state. HMAC call sites should use `HMACCtxPointer::New()`, `init()`, `update()`, and `digest()`/`digestInto()` so the backend selection stays contained in ncrypto. diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index dfd797c82659..baad87976de6 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -830,8 +830,8 @@ bool CipherBase::Final(std::unique_ptr* out) { static_cast(ctx_.getBlockSize()), BackingStoreInitializationMode::kUninitialized); -#if !OPENSSL_VERSION_PREREQ(3, 0) - // OpenSSL v1.x doesn't verify the presence of the auth tag so do +#ifdef OPENSSL_IS_BORINGSSL + // BoringSSL doesn't verify the presence of the auth tag so do // it ourselves, see https://github.com/nodejs/node/issues/45874. if (kind_ == kDecipher && ctx_.isChaCha20Poly1305() && auth_tag_state_ != kAuthTagSetByUser) { diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index 2919a2c0174b..117adea1adb4 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -35,12 +35,8 @@ namespace node { using ncrypto::BIOPointer; using ncrypto::Cipher; using ncrypto::ClearErrorOnReturn; -using ncrypto::CryptoErrorList; using ncrypto::DHPointer; using ncrypto::Digest; -#ifndef OPENSSL_NO_ENGINE -using ncrypto::EnginePointer; -#endif // !OPENSSL_NO_ENGINE using ncrypto::EVPKeyPointer; using ncrypto::MarkPopErrorOnReturn; using ncrypto::SSLPointer; @@ -1352,11 +1348,6 @@ Local SecureContext::GetConstructorTemplate( SetProtoMethodNoSideEffect( isolate, tmpl, "getIssuer", GetCertificate); -#ifndef OPENSSL_NO_ENGINE - SetProtoMethod(isolate, tmpl, "setEngineKey", SetEngineKey); - SetProtoMethod(isolate, tmpl, "setClientCertEngine", SetClientCertEngine); -#endif // !OPENSSL_NO_ENGINE - #define SET_INTEGER_CONSTANTS(name, value) \ tmpl->Set(FIXED_ONE_BYTE_STRING(isolate, name), \ Integer::NewFromUnsigned(isolate, value)); @@ -1441,11 +1432,6 @@ void SecureContext::RegisterExternalReferences( registry->Register(GetCertificate); registry->Register(GetCertificate); -#ifndef OPENSSL_NO_ENGINE - registry->Register(SetEngineKey); - registry->Register(SetClientCertEngine); -#endif // !OPENSSL_NO_ENGINE - registry->Register(CtxGetter); registry->Register(GetBundledRootCertificates); @@ -1606,7 +1592,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { // SSLv3 is disabled because it's susceptible to downgrade attacks (POODLE.) SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv2); SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_NO_SSLv3); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL SSL_CTX_set_options(sc->ctx_.get(), SSL_OP_ALLOW_CLIENT_RENEGOTIATION); #endif @@ -1634,7 +1620,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { return THROW_ERR_CRYPTO_OPERATION_FAILED( env, "Error generating ticket keys"); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(sc->ctx_.get(), TicketCompatibilityCallback); #else @@ -1725,54 +1711,6 @@ void SecureContext::SetSigalgs(const FunctionCallbackInfo& args) { return ThrowCryptoError(env, ERR_get_error()); } -#ifndef OPENSSL_NO_ENGINE -void SecureContext::SetEngineKey(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - - SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); - - CHECK_EQ(args.Length(), 2); - - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CryptoErrorList errors; - Utf8Value engine_id(env->isolate(), args[1]); - auto engine = EnginePointer::getEngineByName(*engine_id, &errors); - if (!engine) { - Local exception; - if (errors.empty()) { - errors.add(getNodeCryptoErrorString(NodeCryptoError::ENGINE_NOT_FOUND, - *engine_id)); - } - if (cryptoErrorListToException(env, errors).ToLocal(&exception)) - env->isolate()->ThrowException(exception); - return; - } - - if (!engine.init(true /* finish on exit*/)) { - return THROW_ERR_CRYPTO_OPERATION_FAILED( - env, "Failure to initialize engine"); - } - - Utf8Value key_name(env->isolate(), args[0]); - auto key = engine.loadPrivateKey(*key_name); - - if (!key) - return ThrowCryptoError(env, ERR_get_error(), "ENGINE_load_private_key"); - - if (!SSL_CTX_use_PrivateKey(sc->ctx_.get(), key.get())) - return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_use_PrivateKey"); - - sc->private_key_engine_ = std::move(engine); -} -#endif // !OPENSSL_NO_ENGINE - Maybe SecureContext::AddCert(Environment* env, BIOPointer&& bio) { ClearErrorOnReturn clear_error_on_return; // TODO(tniessen): this should be checked by the caller and not treated as ok @@ -1954,7 +1892,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { if (!bio) return; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer params(PEM_read_bio_Parameters(bio.get(), nullptr)); if (params && params.id() == EVP_PKEY_DH) dh.reset(params.release()); #else @@ -1978,7 +1916,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { env->isolate(), "DH parameter is less than 2048 bits")); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVPKeyPointer dh_pkey(dh.release()); if (!SSL_CTX_set0_tmp_dh_pkey(sc->ctx_.get(), dh_pkey.get())) { #else @@ -1987,7 +1925,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { return THROW_ERR_CRYPTO_OPERATION_FAILED( env, "Error setting temp DH parameter"); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER dh_pkey.release(); #endif } @@ -2290,7 +2228,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { // TODO(@jasnell): Should this use ThrowCryptoError? unsigned long err = ERR_get_error(); // NOLINT(runtime/int) -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { // OpenSSL's "unsupported" error without any context is very // common and not very helpful, so we override it: @@ -2306,53 +2244,6 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { } } -#ifndef OPENSSL_NO_ENGINE -void SecureContext::SetClientCertEngine( - const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - CHECK_EQ(args.Length(), 1); - CHECK(args[0]->IsString()); - - SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); - - MarkPopErrorOnReturn mark_pop_error_on_return; - - // SSL_CTX_set_client_cert_engine does not itself support multiple - // calls by cleaning up before overwriting the client_cert_engine - // internal context variable. - // Instead of trying to fix up this problem we in turn also do not - // support multiple calls to SetClientCertEngine. - CHECK(!sc->client_cert_engine_provided_); - - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CryptoErrorList errors; - const Utf8Value engine_id(env->isolate(), args[0]); - auto engine = EnginePointer::getEngineByName(*engine_id, &errors); - if (!engine) { - Local exception; - if (errors.empty()) { - errors.add(getNodeCryptoErrorString(NodeCryptoError::ENGINE_NOT_FOUND, - *engine_id)); - } - if (cryptoErrorListToException(env, errors).ToLocal(&exception)) - env->isolate()->ThrowException(exception); - return; - } - - // Note that this takes another reference to `engine`. - if (!engine.setClientCertEngine(sc->ctx_.get())) - return ThrowCryptoError(env, ERR_get_error()); - sc->client_cert_engine_provided_ = true; -} -#endif // !OPENSSL_NO_ENGINE - void SecureContext::GetTicketKeys(const FunctionCallbackInfo& args) { SecureContext* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); @@ -2392,7 +2283,7 @@ void SecureContext::EnableTicketKeyCallback( SecureContext* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER SSL_CTX_set_tlsext_ticket_key_evp_cb(wrap->ctx_.get(), TicketKeyCallback); #else SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback); @@ -2400,7 +2291,7 @@ void SecureContext::EnableTicketKeyCallback( } namespace { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER bool InitTicketHmac(EVP_MAC_CTX* hctx, const unsigned char* key, size_t key_len) { @@ -2424,7 +2315,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl, unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -2521,7 +2412,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl, unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 8cf19a724493..ac1ba8f3d415 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -118,9 +118,6 @@ class SecureContext final : public BaseObject { static void New(const v8::FunctionCallbackInfo& args); static void Init(const v8::FunctionCallbackInfo& args); static void SetKey(const v8::FunctionCallbackInfo& args); -#ifndef OPENSSL_NO_ENGINE - static void SetEngineKey(const v8::FunctionCallbackInfo& args); -#endif // !OPENSSL_NO_ENGINE static void SetCert(const v8::FunctionCallbackInfo& args); static void AddCACert(const v8::FunctionCallbackInfo& args); static void SetAllowPartialTrustChain( @@ -147,10 +144,6 @@ class SecureContext final : public BaseObject { static void GetMaxProto(const v8::FunctionCallbackInfo& args); static void Close(const v8::FunctionCallbackInfo& args); static void LoadPKCS12(const v8::FunctionCallbackInfo& args); -#ifndef OPENSSL_NO_ENGINE - static void SetClientCertEngine( - const v8::FunctionCallbackInfo& args); -#endif // !OPENSSL_NO_ENGINE static void GetTicketKeys(const v8::FunctionCallbackInfo& args); static void SetTicketKeys(const v8::FunctionCallbackInfo& args); static void EnableTicketKeyCallback( @@ -164,7 +157,7 @@ class SecureContext final : public BaseObject { unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -175,7 +168,7 @@ class SecureContext final : public BaseObject { unsigned char* name, unsigned char* iv, EVP_CIPHER_CTX* ectx, -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER EVP_MAC_CTX* hctx, #else HMAC_CTX* hctx, @@ -191,10 +184,6 @@ class SecureContext final : public BaseObject { ncrypto::X509Pointer issuer_; // Non-owning cache for SSL_CTX_get_cert_store(ctx_.get()) X509_STORE* own_cert_store_cache_ = nullptr; -#ifndef OPENSSL_NO_ENGINE - bool client_cert_engine_provided_ = false; - ncrypto::EnginePointer private_key_engine_; -#endif // !OPENSSL_NO_ENGINE unsigned char ticket_key_name_[16]; unsigned char ticket_key_aes_[16]; diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 7fbaf4fff5d9..d79a7148c898 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -92,20 +92,14 @@ MaybeLocal DataPointerToBuffer(Environment* env, DataPointer&& data) { void PutDhError(int reason) { #ifdef OPENSSL_IS_BORINGSSL OPENSSL_PUT_ERROR(DH, reason); -#elif NCRYPTO_USE_OPENSSL3_PROVIDER - ERR_raise(ERR_LIB_DH, reason); #else - ERR_put_error(ERR_LIB_DH, 0, reason, __FILE__, __LINE__); + ERR_raise(ERR_LIB_DH, reason); #endif } -#if defined(OPENSSL_IS_BORINGSSL) || !NCRYPTO_USE_OPENSSL3_PROVIDER -void PutBnError(int reason) { #ifdef OPENSSL_IS_BORINGSSL +void PutBnError(int reason) { OPENSSL_PUT_ERROR(BN, reason); -#else - ERR_put_error(ERR_LIB_BN, 0, reason, __FILE__, __LINE__); -#endif } #endif @@ -134,11 +128,7 @@ void New(const FunctionCallbackInfo& args) { int32_t bits = args[0].As()->Value(); if (bits < 2) { #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 PutDhError(DH_R_MODULUS_TOO_SMALL); -#else - PutBnError(BN_R_BITS_TOO_SMALL); -#endif // OPENSSL_VERSION_MAJOR >= 3 #else // OPENSSL_IS_BORINGSSL PutBnError(BN_R_BITS_TOO_SMALL); #endif // OPENSSL_IS_BORINGSSL @@ -206,7 +196,7 @@ void New(const FunctionCallbackInfo& args) { } } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER if (BN_num_bits(bn_p.get()) >= 512 && BN_cmp(bn_g.get(), bn_p.get()) >= 0) { PutDhError(DH_R_BAD_GENERATOR); return ThrowCryptoError(env, ERR_get_error(), "Invalid generator"); diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 976c921fee94..681ca532df4a 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -82,7 +82,7 @@ constexpr BoringSSLDigest kBoringSSLDigests[] = { void ResetHashCache(Environment* env, uint64_t generation, Local algorithm_cache = Local()) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::DigestCache* cache = env->provider_digest_cache.get(); CHECK_NOT_NULL(cache); if (!algorithm_cache.IsEmpty()) { @@ -113,7 +113,7 @@ bool SynchronizeHashCache(Environment* env, return true; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const EVP_MD* GetCachedMDByID(Environment* env, int32_t id, Local algorithm_cache = Local()) { @@ -241,7 +241,7 @@ void SaveSupportedHashAlgorithms(const EVP_MD* md, Environment* env = static_cast(arg); env->supported_hash_algorithms.push_back(from); } -#endif // NCRYPTO_USE_OPENSSL3_PROVIDER +#endif // NCRYPTO_USE_OPENSSL_PROVIDER const std::vector& GetSupportedHashAlgorithms(Environment* env) { while (true) { @@ -254,7 +254,7 @@ const std::vector& GetSupportedHashAlgorithms(Environment* env) { static_cast(digest.get); env->supported_hash_algorithms.emplace_back(digest.name); } -#elif NCRYPTO_USE_OPENSSL3_PROVIDER +#elif NCRYPTO_USE_OPENSSL_PROVIDER // Since we'll fetch the EVP_MD*, cache them along the way to speed up // later lookups instead of throwing them away immediately. EVP_MD_do_all_sorted(SaveSupportedHashAlgorithmsAndCacheMD, env); @@ -290,7 +290,7 @@ void Hash::GetCachedAliases(const FunctionCallbackInfo& args) { size_t size = 0; LocalVector names(isolate); LocalVector values(isolate); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const auto& aliases = env->provider_digest_cache->aliases(); size = aliases.size(); names.reserve(size); @@ -317,7 +317,7 @@ const EVP_MD* GetDigestImplementation( CHECK(algorithm_cache->IsObject()); DCHECK(!digest_owner.has_value()); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER Local cache = algorithm_cache.As(); int32_t cache_id = cache_id_val.As()->Value(); if (cache_id != -1) { @@ -358,7 +358,7 @@ const EVP_MD* GetDigestImplementation( } void MarkInvalidXofLength() { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH); #else EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH); @@ -373,7 +373,7 @@ void MarkInvalidXofLength() { // version-independent. #if !OPENSSL_VERSION_PREREQ(3, 4) bool IsShakeDigest(const EVP_MD* md) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER return EVP_MD_is_a(md, "SHAKE128") || EVP_MD_is_a(md, "SHAKE256"); #else const char* name = OBJ_nid2sn(EVP_MD_type(md)); @@ -537,7 +537,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo& args) { CHECK(args[6]->IsUint32() || args[6]->IsUndefined()); // outputLength if (args.Length() == 7) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int32_t cache_id = args[1].As()->Value(); if (cache_id != -1) { if (const EVP_MD* md = @@ -619,7 +619,7 @@ void Hash::New(const FunctionCallbackInfo& args) { xof_md_len = Just(args[1].As()->Value()); } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // This is the common path after the first lookup. Avoid constructing a // digest owner when the Environment already owns the cached implementation. if (args.Length() == 4 && args[0]->IsString()) { diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 2d80caf76661..16ba98b68675 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -1337,7 +1337,7 @@ void KeyObjectHandle::Equals(const FunctionCallbackInfo& args) { case kKeyTypePrivate: { EVP_PKEY* pkey = key.GetAsymmetricKey().get(); EVP_PKEY* pkey2 = key2.GetAsymmetricKey().get(); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int ok = EVP_PKEY_eq(pkey, pkey2); #else int ok = EVP_PKEY_cmp(pkey, pkey2); diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index e80c70c961df..5c0ab2e2d814 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -40,7 +40,7 @@ using v8::Value; namespace crypto { namespace { bool IsRsaPssDigestEncodable(const Digest& digest) { -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const int nid = EVP_MD_type(digest.get()); if (nid == NID_undef) return false; @@ -365,7 +365,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { KeyType type = d_value->IsString() ? kKeyTypePrivate : kKeyTypePublic; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER ncrypto::Rsa rsa_view; #else RSAPointer rsa(RSA_new()); @@ -437,7 +437,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local jwk) { } } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER auto pkey = EVPKeyPointer::NewRSA(rsa_view); #else auto pkey = EVPKeyPointer::NewRSA(std::move(rsa)); diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index 5e09477a6913..0ddd465438ab 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -8,7 +8,7 @@ #include "env-inl.h" #include "memory_tracker-inl.h" #include "openssl/ec.h" -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER #include #include #endif @@ -405,7 +405,7 @@ bool MayBeSM2Key(const EVPKeyPointer& key) { if (key.id() == EVP_PKEY_SM2) return true; if (key.id() != EVP_PKEY_EC) return false; -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER // An ECKeyPointer would also need the public point, which a provider-backed // key need not expose. char group_name[64]; diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 5a531209e232..ec0a57c4c33a 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -80,7 +80,7 @@ namespace { // that the user user Connection::VerifyError after the `secure` // callback has been made. int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) { - // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb: + // From https://www.openssl.org/docs/man3.0/man3/SSL_verify_cb: // // If VerifyCallback returns 1, the verification process is continued. If // VerifyCallback always returns 1, the TLS/SSL handshake will not be @@ -935,7 +935,7 @@ void TLSWrap::ClearOut() { return; const char* ls = ERR_lib_error_string(ssl_err); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; #else const char* fs = ERR_func_error_string(ssl_err); diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index edaf4bdbe2fe..737da506f4e4 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -14,7 +14,7 @@ #include "math.h" -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL #include "openssl/provider.h" #endif @@ -29,9 +29,6 @@ using ncrypto::BignumPointer; using ncrypto::BIOPointer; using ncrypto::CryptoErrorList; using ncrypto::DataPointer; -#ifndef OPENSSL_NO_ENGINE -using ncrypto::EnginePointer; -#endif // !OPENSSL_NO_ENGINE using ncrypto::SSLPointer; using v8::Array; using v8::ArrayBuffer; @@ -211,7 +208,7 @@ std::optional ProcessFipsOptions() { const bool force_fips = per_process::cli_options->force_fips_crypto; if (!enable_fips && !force_fips) return std::nullopt; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // Whether FIPS-approved implementations are reachable is decided by the // OpenSSL configuration, not by Node.js. Refuse to start rather than // restrict the default property query to a provider that is not there, @@ -265,15 +262,6 @@ void InitCryptoOnce() { OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); CHECK_NOT_NULL(settings); -#if OPENSSL_VERSION_MAJOR < 3 - // --openssl-config=... - if (!per_process::cli_options->openssl_config.empty()) { - const char* conf = per_process::cli_options->openssl_config.c_str(); - OPENSSL_INIT_set_config_filename(settings, conf); - } -#endif - -#if OPENSSL_VERSION_MAJOR >= 3 // --openssl-legacy-provider if (per_process::cli_options->openssl_legacy_provider) { OSSL_PROVIDER* legacy_provider = OSSL_PROVIDER_load(nullptr, "legacy"); @@ -281,7 +269,6 @@ void InitCryptoOnce() { fprintf(stderr, "Unable to load legacy provider.\n"); } } -#endif OPENSSL_init_ssl(0, settings); @@ -328,10 +315,6 @@ void InitCryptoOnce() { // Turn off compression. Saves memory and protects against CRIME attacks. // No-op with OPENSSL_NO_COMP builds of OpenSSL. sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); - -#ifndef OPENSSL_NO_ENGINE - EnginePointer::initEnginesOnce(); -#endif // !OPENSSL_NO_ENGINE } void GetFipsCrypto(const FunctionCallbackInfo& args) { @@ -691,7 +674,7 @@ Maybe Decorate(Environment* env, if (err == 0) return JustVoid(); // No decoration necessary. const char* ls = ERR_lib_error_string(err); -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER const char* fs = nullptr; #else const char* fs = ERR_func_error_string(err); @@ -832,28 +815,6 @@ void ThrowCryptoError(Environment* env, env->isolate()->ThrowException(exception); } -#ifndef OPENSSL_NO_ENGINE -void SetEngine(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - if (env->permission()->enabled()) [[unlikely]] { - return THROW_ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED( - env, - "Programmatic selection of OpenSSL engines is unsupported while the " - "experimental permission model is enabled"); - } - - CHECK(args.Length() >= 2 && args[0]->IsString()); - uint32_t flags; - if (!args[1]->Uint32Value(env->context()).To(&flags)) return; - - const node::Utf8Value engine_id(env->isolate(), args[0]); - // If the engine name is not known, calling setAsDefault on the - // empty engine pointer will be non-op that always returns false. - args.GetReturnValue().Set( - EnginePointer::getEngineByName(*engine_id).setAsDefault(flags)); -} -#endif // !OPENSSL_NO_ENGINE - MaybeLocal EncodeBignum(Environment* env, const BIGNUM* bn, int size) { EscapableHandleScope scope(env->isolate()); auto buf = BignumPointer::EncodePadded(bn, size); @@ -999,10 +960,6 @@ void SecureHeapUsed(const FunctionCallbackInfo& args) { namespace Util { void Initialize(Environment* env, Local target) { Local context = env->context(); -#ifndef OPENSSL_NO_ENGINE - SetMethod(context, target, "setEngine", SetEngine); -#endif // !OPENSSL_NO_ENGINE - SetMethodNoSideEffect(context, target, "getFipsCrypto", GetFipsCrypto); SetMethodNoSideEffect( context, target, "getFipsCryptoGeneration", GetFipsCryptoGeneration); @@ -1020,10 +977,6 @@ void Initialize(Environment* env, Local target) { context, target, "getOpenSSLSecLevelCrypto", GetOpenSSLSecLevelCrypto); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { -#ifndef OPENSSL_NO_ENGINE - registry->Register(SetEngine); -#endif // !OPENSSL_NO_ENGINE - registry->Register(GetFipsCrypto); registry->Register(GetFipsCryptoGeneration); registry->Register(SetFipsCrypto); diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 62ae32d277d9..6276928bcbc8 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -110,7 +110,6 @@ void Decode(const v8::FunctionCallbackInfo& args, V(DERIVING_BITS_FAILED, "Deriving bits failed") \ V(ECDH_FAILED, "ECDH key agreement failed") \ V(ENCAPSULATION_FAILED, "Encapsulation failed") \ - V(ENGINE_NOT_FOUND, "Engine \"%s\" was not found") \ V(HKDF_FAILED, "HKDF derivation failed") \ V(INVALID_KEY_TYPE, "Invalid key type") \ V(KEY_GENERATION_JOB_FAILED, "Key generation job failed") \ diff --git a/src/env.cc b/src/env.cc index d679652818c9..6562c40681b7 100644 --- a/src/env.cc +++ b/src/env.cc @@ -881,7 +881,7 @@ Environment::Environment(IsolateData* isolate_data, ? AllocateEnvironmentThreadId().id : thread_id.id), thread_name_(thread_name) { -#if HAVE_OPENSSL && NCRYPTO_USE_OPENSSL3_PROVIDER +#if HAVE_OPENSSL && NCRYPTO_USE_OPENSSL_PROVIDER provider_digest_cache = std::make_unique(); provider_cipher_cache = std::make_unique(); #endif diff --git a/src/node.cc b/src/node.cc index 5e00996c1ba3..74f3f708d24f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -50,7 +50,7 @@ #if HAVE_OPENSSL #include "ncrypto.h" #include "node_crypto.h" -#if OPENSSL_VERSION_MAJOR >= 3 && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE) +#if !defined(OPENSSL_IS_BORINGSSL) && !defined(CONF_MFLAGS_IGNORE_MISSING_FILE) // OpenSSL hides this deprecated macro under OPENSSL_NO_DEPRECATED, but the // non-deprecated OPENSSL_INIT settings API still accepts the flag value. #define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 @@ -1156,7 +1156,6 @@ InitializeOncePerProcessInternal(const std::vector& args, if (!(flags & ProcessInitializationFlags::kNoInitOpenSSL)) { #if HAVE_OPENSSL #ifndef OPENSSL_IS_BORINGSSL -#if OPENSSL_VERSION_MAJOR >= 3 auto GetOpenSSLErrorString = []() -> std::string { std::string ret; ERR_print_errors_cb( @@ -1172,6 +1171,7 @@ InitializeOncePerProcessInternal(const std::vector& args, // In the case of FIPS builds we should make sure // the random source is properly initialized first. + // // Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to // avoid the default behavior where errors raised during the parsing of the // OpenSSL configuration file are not propagated and cannot be detected. @@ -1228,11 +1228,7 @@ InitializeOncePerProcessInternal(const std::vector& args, GetOpenSSLErrorString()); return result; } -#else // OPENSSL_VERSION_MAJOR < 3 - if (FIPS_mode()) { - OPENSSL_init(); - } -#endif + if (auto fips_error = crypto::ProcessFipsOptions()) { result->exit_code_ = ExitCode::kGenericUserError; result->early_return_ = true; diff --git a/src/node_config.cc b/src/node_config.cc index 7245d9130d03..2de1ee244ddb 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -64,8 +64,6 @@ static void InitConfig(Local target, READONLY_FALSE_PROPERTY(target, "hasOpenSSL"); #endif // HAVE_OPENSSL - READONLY_TRUE_PROPERTY(target, "fipsMode"); - #ifdef NODE_HAVE_I18N_SUPPORT READONLY_TRUE_PROPERTY(target, "hasIntl"); diff --git a/src/node_constants.cc b/src/node_constants.cc index bd3b66414d18..fd1f87fc5884 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -57,7 +57,7 @@ #if !defined(RSA_PKCS1_PSS_PADDING) #define RSA_PKCS1_PSS_PADDING 6 #endif -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL // OpenSSL hides these deprecated DH check constants under // OPENSSL_NO_DEPRECATED, but the numeric verifyError values remain public API. #if !defined(DH_CHECK_P_NOT_PRIME) @@ -73,25 +73,6 @@ #define DH_NOT_SUITABLE_GENERATOR 0x08 #endif #endif -#ifndef OPENSSL_NO_ENGINE -#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3 -// Engine constants remain public API while engine implementation lives in the -// dedicated compatibility target. -#define ENGINE_METHOD_RSA (unsigned int)0x0001 -#define ENGINE_METHOD_DSA (unsigned int)0x0002 -#define ENGINE_METHOD_DH (unsigned int)0x0004 -#define ENGINE_METHOD_RAND (unsigned int)0x0008 -#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 -#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 -#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 -#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 -#define ENGINE_METHOD_EC (unsigned int)0x0800 -#define ENGINE_METHOD_ALL (unsigned int)0xFFFF -#define ENGINE_METHOD_NONE (unsigned int)0x0000 -#else -#include -#endif -#endif // !OPENSSL_NO_ENGINE #endif // HAVE_OPENSSL #if defined(__POSIX__) @@ -959,54 +940,6 @@ void DefineCryptoConstants(Local target) { NODE_DEFINE_CONSTANT(target, SSL_OP_TLS_ROLLBACK_BUG); #endif -# ifndef OPENSSL_NO_ENGINE - -# ifdef ENGINE_METHOD_RSA - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RSA); -# endif - -# ifdef ENGINE_METHOD_DSA - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DSA); -# endif - -# ifdef ENGINE_METHOD_DH - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DH); -# endif - -# ifdef ENGINE_METHOD_RAND - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_RAND); -# endif - -# ifdef ENGINE_METHOD_EC - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_EC); -# endif - -# ifdef ENGINE_METHOD_CIPHERS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_CIPHERS); -# endif - -# ifdef ENGINE_METHOD_DIGESTS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_DIGESTS); -# endif - -# ifdef ENGINE_METHOD_PKEY_METHS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_METHS); -# endif - -# ifdef ENGINE_METHOD_PKEY_ASN1_METHS - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_PKEY_ASN1_METHS); -# endif - -# ifdef ENGINE_METHOD_ALL - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_ALL); -# endif - -# ifdef ENGINE_METHOD_NONE - NODE_DEFINE_CONSTANT(target, ENGINE_METHOD_NONE); -# endif - -# endif // !OPENSSL_NO_ENGINE - #ifdef DH_CHECK_P_NOT_SAFE_PRIME NODE_DEFINE_CONSTANT(target, DH_CHECK_P_NOT_SAFE_PRIME); #endif diff --git a/src/node_constants.h b/src/node_constants.h index 97429c0e5e94..115de09587d3 100644 --- a/src/node_constants.h +++ b/src/node_constants.h @@ -48,7 +48,7 @@ #define DEFAULT_CIPHER_LIST_CORE NODE_OPENSSL_DEFAULT_CIPHER_LIST #else // TLSv1.3 suites start with TLS_, and are the OpenSSL defaults, see: -// https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_ciphersuites.html +// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_ciphersuites.html #define DEFAULT_CIPHER_LIST_CORE \ "TLS_AES_256_GCM_SHA384:" \ "TLS_CHACHA20_POLY1305_SHA256:" \ diff --git a/src/node_errors.h b/src/node_errors.h index 62cfba88f00d..a59b8d3919f1 100644 --- a/src/node_errors.h +++ b/src/node_errors.h @@ -50,7 +50,6 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details); V(ERR_CONSTRUCT_CALL_INVALID, TypeError) \ V(ERR_CPU_PROFILE_NOT_STARTED, Error) \ V(ERR_CPU_PROFILE_TOO_MANY, Error) \ - V(ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED, Error) \ V(ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, Error) \ V(ERR_CRYPTO_INITIALIZATION_FAILED, Error) \ V(ERR_CRYPTO_INVALID_AUTH_TAG, TypeError) \ diff --git a/src/node_metadata.cc b/src/node_metadata.cc index b91b1b488148..68daae837fc1 100644 --- a/src/node_metadata.cc +++ b/src/node_metadata.cc @@ -68,7 +68,7 @@ static constexpr size_t search(const char* s, char c, size_t n = 0) { static inline std::string GetOpenSSLVersion() { // sample openssl version string format - // for reference: "OpenSSL 1.1.0i 14 Aug 2018" + // for reference: "OpenSSL 3.5.7 9 Jun 2026" const char* version = OpenSSL_version(OPENSSL_VERSION); const size_t first_space = search(version, ' '); diff --git a/src/node_options.cc b/src/node_options.cc index 3226b7429d42..b323b2d136c4 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -1497,9 +1497,9 @@ PerProcessOptionsParser::PerProcessOptionsParser( kAllowedInEnvvar); #endif // V8_ENABLE_SANDBOX #endif // HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) AddOption("--openssl-legacy-provider", - "enable OpenSSL 3.0 legacy provider", + "enable OpenSSL's legacy provider", BOOL_FIELD(openssl_legacy_provider), kAllowedInEnvvar); AddOption("--openssl-shared-config", @@ -1507,7 +1507,7 @@ PerProcessOptionsParser::PerProcessOptionsParser( BOOL_FIELD(openssl_shared_config), kAllowedInEnvvar); -#endif // OPENSSL_VERSION_MAJOR +#endif // HAVE_OPENSSL && !OPENSSL_IS_BORINGSSL AddOption("--use-largepages", "This option is no longer supported and a no-op. It still accepts" " these values for compatibility: 'off' (default), 'on' (report a " diff --git a/src/node_options.h b/src/node_options.h index cf103aeffbf1..a49be9a7b84c 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -411,7 +411,7 @@ class PerProcessOptions : public Options { DEFINE_BOOL_FIELD(enable_fips_crypto) = false; DEFINE_BOOL_FIELD(force_fips_crypto) = false; #endif // HAVE_OPENSSL -#if OPENSSL_VERSION_MAJOR >= 3 +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL) DEFINE_BOOL_FIELD(openssl_legacy_provider) = false; DEFINE_BOOL_FIELD(openssl_shared_config) = false; #endif diff --git a/test/addons/openssl-client-cert-engine/binding.gyp b/test/addons/openssl-client-cert-engine/binding.gyp deleted file mode 100644 index 726f135a4caf..000000000000 --- a/test/addons/openssl-client-cert-engine/binding.gyp +++ /dev/null @@ -1,23 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['OS=="mac" and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'xcode_settings': { - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ] - } - ] -} diff --git a/test/addons/openssl-client-cert-engine/test.js b/test/addons/openssl-client-cert-engine/test.js deleted file mode 100644 index 4f7c7d7ac0f1..000000000000 --- a/test/addons/openssl-client-cert-engine/test.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; -const common = require('../../common'); -const fixture = require('../../common/fixtures'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const fs = require('fs'); -const path = require('path'); - -const engine = path.join(__dirname, - `/build/${common.buildType}/testengine.engine`); - -if (!fs.existsSync(engine)) - common.skip('no client cert engine'); - -const assert = require('assert'); -const https = require('https'); - -const agentKey = fs.readFileSync(fixture.path('/keys/agent1-key.pem')); -const agentCert = fs.readFileSync(fixture.path('/keys/agent1-cert.pem')); -const agentCa = fs.readFileSync(fixture.path('/keys/ca1-cert.pem')); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -const serverOptions = { - key: agentKey, - cert: agentCert, - ca: agentCa, - requestCert: true, - rejectUnauthorized: true, -}; - -const server = https.createServer(serverOptions, common.mustCall((req, res) => { - res.writeHead(200); - res.end('hello world'); -})).listen(0, common.localhostIPv4, common.mustCall(() => { - const clientOptions = { - method: 'GET', - host: common.localhostIPv4, - port: server.address().port, - path: '/test', - clientCertEngine: engine, // `engine` will provide key+cert - rejectUnauthorized: false, // Prevent failing on self-signed certificates - headers: {}, - }; - - const req = https.request(clientOptions, common.mustCall((response) => { - let body = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => { - body += chunk; - }); - - response.on('end', common.mustCall(() => { - assert.strictEqual(body, 'hello world'); - server.close(); - })); - })); - - req.end(); -})); diff --git a/test/addons/openssl-client-cert-engine/testengine.cc b/test/addons/openssl-client-cert-engine/testengine.cc deleted file mode 100644 index 95712901e69c..000000000000 --- a/test/addons/openssl-client-cert-engine/testengine.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testengine" -#define TEST_ENGINE_NAME "dummy test engine" - -#define AGENT_KEY "test/fixtures/keys/agent1-key.pem" -#define AGENT_CERT "test/fixtures/keys/agent1-cert.pem" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -std::string LoadFile(const char* filename) { - std::ifstream file(filename); - return std::string(std::istreambuf_iterator(file), - std::istreambuf_iterator()); -} - - -int EngineLoadSSLClientCert(ENGINE* engine, - SSL* ssl, - STACK_OF(X509_NAME)* ca_dn, - X509** ppcert, - EVP_PKEY** ppkey, - STACK_OF(X509)** pother, - UI_METHOD* ui_method, - void* callback_data) { - if (ppcert != nullptr) { - std::string cert = LoadFile(AGENT_CERT); - if (cert.empty()) { - return 0; - } - - BIO* bio = BIO_new_mem_buf(cert.data(), cert.size()); - *ppcert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); - BIO_vfree(bio); - if (*ppcert == nullptr) { - printf("Could not read certificate\n"); - return 0; - } - } - - if (ppkey != nullptr) { - std::string key = LoadFile(AGENT_KEY); - if (key.empty()) { - return 0; - } - - BIO* bio = BIO_new_mem_buf(key.data(), key.size()); - *ppkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr); - BIO_vfree(bio); - if (*ppkey == nullptr) { - printf("Could not read private key\n"); - return 0; - } - } - - return 1; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - ENGINE_set_load_ssl_client_cert_function(engine, EngineLoadSSLClientCert); - - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/addons/openssl-key-engine/binding.gyp b/test/addons/openssl-key-engine/binding.gyp deleted file mode 100644 index fc1fafa89bab..000000000000 --- a/test/addons/openssl-key-engine/binding.gyp +++ /dev/null @@ -1,23 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testkeyengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['OS=="mac" and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testkeyengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'xcode_settings': { - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ] - } - ] -} diff --git a/test/addons/openssl-key-engine/test.js b/test/addons/openssl-key-engine/test.js deleted file mode 100644 index 92b7bb558ad7..000000000000 --- a/test/addons/openssl-key-engine/test.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict'; -const common = require('../../common'); -const fixture = require('../../common/fixtures'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const fs = require('fs'); -const path = require('path'); - -const engine = path.join(__dirname, - `/build/${common.buildType}/testkeyengine.engine`); - -if (!fs.existsSync(engine)) - common.skip('no client cert engine'); - -const assert = require('assert'); -const https = require('https'); - -const agentKey = fs.readFileSync(fixture.path('/keys/agent1-key.pem')); -const agentCert = fs.readFileSync(fixture.path('/keys/agent1-cert.pem')); -const agentCa = fs.readFileSync(fixture.path('/keys/ca1-cert.pem')); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -const serverOptions = { - key: agentKey, - cert: agentCert, - ca: agentCa, - requestCert: true, - rejectUnauthorized: true, -}; - -const server = https.createServer(serverOptions, common.mustCall((req, res) => { - res.writeHead(200); - res.end('hello world'); -})).listen(0, common.localhostIPv4, common.mustCall(() => { - const clientOptions = { - method: 'GET', - host: common.localhostIPv4, - port: server.address().port, - path: '/test', - privateKeyEngine: engine, - privateKeyIdentifier: 'dummykey', - cert: agentCert, - rejectUnauthorized: false, // Prevent failing on self-signed certificates - headers: {}, - }; - - const req = https.request(clientOptions, common.mustCall((response) => { - let body = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => { - body += chunk; - }); - - response.on('end', common.mustCall(() => { - assert.strictEqual(body, 'hello world'); - server.close(); - })); - })); - - req.end(); -})); diff --git a/test/addons/openssl-key-engine/testkeyengine.cc b/test/addons/openssl-key-engine/testkeyengine.cc deleted file mode 100644 index 704027ba5a43..000000000000 --- a/test/addons/openssl-key-engine/testkeyengine.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include - -#include -#include -#include - -#include -#include -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testkeyengine" -#define TEST_ENGINE_NAME "dummy test key engine" - -#define PRIVATE_KEY "test/fixtures/keys/agent1-key.pem" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -std::string LoadFile(const char* filename) { - std::ifstream file(filename); - return std::string(std::istreambuf_iterator(file), - std::istreambuf_iterator()); -} - -static EVP_PKEY* EngineLoadPrivkey(ENGINE* engine, const char* name, - UI_METHOD* ui_method, void* callback_data) { - if (strcmp(name, "dummykey") == 0) { - std::string key = LoadFile(PRIVATE_KEY); - BIO* bio = BIO_new_mem_buf(key.data(), key.size()); - EVP_PKEY* ret = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr); - - BIO_vfree(bio); - if (ret != nullptr) { - return ret; - } - } - - return nullptr; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - ENGINE_set_load_privkey_function(engine, EngineLoadPrivkey); - - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/addons/openssl-providers/binding.cc b/test/addons/openssl-providers/binding.cc index 785a103bb6c6..36f8de59ccd9 100644 --- a/test/addons/openssl-providers/binding.cc +++ b/test/addons/openssl-providers/binding.cc @@ -1,8 +1,9 @@ #include #include -#include -#if OPENSSL_VERSION_MAJOR >= 3 +// BoringSSL declares OPENSSL_IS_BORINGSSL in crypto.h. +#include +#ifndef OPENSSL_IS_BORINGSSL #include #endif @@ -18,7 +19,7 @@ using v8::Object; using v8::String; using v8::Value; -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL int collectProviders(OSSL_PROVIDER* provider, void* cbdata) { static_cast*>(cbdata)->push_back(provider); return 1; @@ -28,7 +29,7 @@ int collectProviders(OSSL_PROVIDER* provider, void* cbdata) { inline void GetProviders(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); LocalVector arr(isolate, 0); -#if OPENSSL_VERSION_MAJOR >= 3 +#ifndef OPENSSL_IS_BORINGSSL std::vector providers; OSSL_PROVIDER_do_all(nullptr, &collectProviders, &providers); for (auto provider : providers) { diff --git a/test/addons/openssl-providers/providers.cjs b/test/addons/openssl-providers/providers.cjs index fc0f93ef45c8..07a096564439 100644 --- a/test/addons/openssl-providers/providers.cjs +++ b/test/addons/openssl-providers/providers.cjs @@ -4,10 +4,8 @@ const common = require('../../common'); if (!common.hasCrypto) { common.skip('missing crypto'); } -const { hasOpenSSL3 } = require('../../common/crypto'); - -if (!hasOpenSSL3) { - common.skip('this test requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) { + common.skip('OpenSSL provider support is required'); } const assert = require('node:assert'); const { diff --git a/test/addons/openssl-test-engine/binding.gyp b/test/addons/openssl-test-engine/binding.gyp deleted file mode 100644 index fe18de701bbd..000000000000 --- a/test/addons/openssl-test-engine/binding.gyp +++ /dev/null @@ -1,33 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'testsetengine', - 'type': 'none', - 'includes': ['../common.gypi'], - 'conditions': [ - ['(OS=="mac" or OS=="linux") and ' - 'node_use_openssl=="true" and ' - 'node_shared=="false" and ' - 'node_shared_openssl=="false"', { - 'type': 'shared_library', - 'sources': [ 'testsetengine.cc' ], - 'product_extension': 'engine', - 'include_dirs': ['../../../deps/openssl/openssl/include'], - 'conditions': [ - ['OS=="mac"', { - 'xcode_settings': { - 'OTHER_CFLAGS': ['-Wno-deprecated-declarations'], - 'OTHER_LDFLAGS': ['-undefined', 'dynamic_lookup'], - }, - }], - ['OS=="linux"', { - 'cflags': [ - '-Wno-deprecated-declarations', - ], - }], - ], - }], - ], - } - ] -} diff --git a/test/addons/openssl-test-engine/test.js b/test/addons/openssl-test-engine/test.js deleted file mode 100644 index e4ce6b5b519a..000000000000 --- a/test/addons/openssl-test-engine/test.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; -const common = require('../../common'); - -// This tests crypto.setEngine(). - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const crypto = require('crypto'); -const fs = require('fs'); -const path = require('path'); - -// Engine support in OpenSSL is checked later on. -let hasEngineSupport = true; - -assert.throws(() => crypto.setEngine(true), /ERR_INVALID_ARG_TYPE|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); -assert.throws(() => crypto.setEngine('/path/to/engine', 'notANumber'), - /ERR_INVALID_ARG_TYPE/); - -{ - const invalidEngineName = 'xxx'; - assert.throws(() => crypto.setEngine(invalidEngineName), - /ERR_CRYPTO_ENGINE_UNKNOWN|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); - assert.throws(() => crypto.setEngine(invalidEngineName, - crypto.constants.ENGINE_METHOD_RSA), - /ERR_CRYPTO_ENGINE_UNKNOWN|ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED/); -} - -try { - crypto.setEngine('dynamic'); - crypto.setEngine('dynamic'); - - crypto.setEngine('dynamic', crypto.constants.ENGINE_METHOD_RSA); - crypto.setEngine('dynamic', crypto.constants.ENGINE_METHOD_RSA); -} catch (err) { - assert.strictEqual(err.code, 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED'); - hasEngineSupport = false; -} - -if (hasEngineSupport) { - const engine = path.join(__dirname, - `/build/${common.buildType}/testsetengine.engine`); - - if (!fs.existsSync(engine)) - common.skip('no engine'); - - { - const engineId = path.parse(engine).name; - const execDir = path.parse(engine).dir; - - crypto.setEngine(engine); - // OpenSSL 3.0.1 and 1.1.1m now throw errors if an engine is loaded again - // with a duplicate absolute path. - // TODO(richardlau): figure out why this fails on macOS but not Linux. - // crypto.setEngine(engine); - - // crypto.setEngine(engine, crypto.constants.ENGINE_METHOD_RSA); - // crypto.setEngine(engine, crypto.constants.ENGINE_METHOD_RSA); - - process.env.OPENSSL_ENGINES = execDir; - - crypto.setEngine(engineId); - crypto.setEngine(engineId); - - crypto.setEngine(engineId, crypto.constants.ENGINE_METHOD_RSA); - crypto.setEngine(engineId, crypto.constants.ENGINE_METHOD_RSA); - } -} diff --git a/test/addons/openssl-test-engine/testsetengine.cc b/test/addons/openssl-test-engine/testsetengine.cc deleted file mode 100644 index 04f57ec4ba66..000000000000 --- a/test/addons/openssl-test-engine/testsetengine.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#ifndef ENGINE_CMD_BASE -# error did not get engine.h -#endif - -#define TEST_ENGINE_ID "testsetengine" -#define TEST_ENGINE_NAME "dummy test engine" - -#ifdef _WIN32 -# define DEFAULT_VISIBILITY __declspec(dllexport) -#else -# define DEFAULT_VISIBILITY __attribute__((visibility("default"))) -#endif - -namespace { - -int EngineInit(ENGINE* engine) { - return 1; -} - -int EngineFinish(ENGINE* engine) { - return 1; -} - -int EngineDestroy(ENGINE* engine) { - return 1; -} - -int bind_fn(ENGINE* engine, const char* id) { - ENGINE_set_id(engine, TEST_ENGINE_ID); - ENGINE_set_name(engine, TEST_ENGINE_NAME); - ENGINE_set_init_function(engine, EngineInit); - ENGINE_set_finish_function(engine, EngineFinish); - ENGINE_set_destroy_function(engine, EngineDestroy); - return 1; -} - -extern "C" { - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_CHECK_FN(); - DEFAULT_VISIBILITY IMPLEMENT_DYNAMIC_BIND_FN(bind_fn); -} - -} // anonymous namespace diff --git a/test/cctest/test_node_crypto_env.cc b/test/cctest/test_node_crypto_env.cc index fddf584d7d41..4c349ac1a0af 100644 --- a/test/cctest/test_node_crypto_env.cc +++ b/test/cctest/test_node_crypto_env.cc @@ -26,7 +26,7 @@ TEST_F(NodeCryptoEnv, LoadBIO) { // just put a random string into BIO Local key = String::NewFromUtf8(isolate_, "abcdef").ToLocalChecked(); ncrypto::BIOPointer bio(node::crypto::LoadBIO(*env, key)); -#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#ifndef OPENSSL_IS_BORINGSSL const int ofs = 2; ASSERT_EQ(BIO_seek(bio.get(), ofs), ofs); ASSERT_EQ(BIO_tell(bio.get()), ofs); @@ -35,7 +35,7 @@ TEST_F(NodeCryptoEnv, LoadBIO) { "any errors on the OpenSSL error stack\n"; } -#if NCRYPTO_USE_OPENSSL3_PROVIDER +#if NCRYPTO_USE_OPENSSL_PROVIDER TEST_F(NodeCryptoEnv, ExportIncompleteRsaPrivateKeyAsJwk) { v8::HandleScope handle_scope(isolate_); Argv argv; diff --git a/test/doctool/test-doc-api-json.mjs b/test/doctool/test-doc-api-json.mjs index 2f085ad9b439..070ff57c47df 100644 --- a/test/doctool/test-doc-api-json.mjs +++ b/test/doctool/test-doc-api-json.mjs @@ -158,5 +158,5 @@ for await (const dirent of await fs.opendir(new URL('../../out/doc/api/', import assert.partialDeepStrictEqual(allExpectedKeys, findAllKeys(json)); } -assert.strictEqual(numberOfDeprecatedSections, 45); // Increase this number every time a new API is deprecated. +assert.strictEqual(numberOfDeprecatedSections, 44); // Increase this number every time a new API is deprecated. assert.strictEqual(numberOfRemovedAPIs, 46); // Increase this number every time a section is marked as removed. diff --git a/test/fixtures/openssl_fips_disabled.cnf b/test/fixtures/openssl_fips_disabled.cnf deleted file mode 100644 index 253c6906e3f3..000000000000 --- a/test/fixtures/openssl_fips_disabled.cnf +++ /dev/null @@ -1,12 +0,0 @@ -# Skeleton openssl.cnf for testing with FIPS - -nodejs_conf = openssl_conf_section -authorityKeyIdentifier=keyid:always,issuer:always - -[openssl_conf_section] - # Configuration module list -alg_section = evp_sect - -[ evp_sect ] -# Set to "yes" to enter FIPS mode if supported -fips_mode = no diff --git a/test/fixtures/openssl_fips_enabled.cnf b/test/fixtures/openssl_fips_enabled.cnf deleted file mode 100644 index 79733c657a96..000000000000 --- a/test/fixtures/openssl_fips_enabled.cnf +++ /dev/null @@ -1,12 +0,0 @@ -# Skeleton openssl.cnf for testing with FIPS - -nodejs_conf = openssl_conf_section -authorityKeyIdentifier=keyid:always,issuer:always - -[openssl_conf_section] - # Configuration module list -alg_section = evp_sect - -[ evp_sect ] -# Set to "yes" to enter FIPS mode if supported -fips_mode = yes diff --git a/test/parallel/test-crypto-dep0183.js b/test/parallel/test-crypto-dep0183.js index c0b9a8e9f679..754b90d2de76 100644 --- a/test/parallel/test-crypto-dep0183.js +++ b/test/parallel/test-crypto-dep0183.js @@ -1,3 +1,4 @@ +// Flags: --expose-internals 'use strict'; const common = require('../common'); @@ -6,17 +7,90 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); +const https = require('https'); +const tls = require('tls'); +const { internalBinding } = require('internal/test/binding'); -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, +process.on('warning', (warning) => { + if (warning.code === 'DEP0183') + throw warning; }); -assert.throws( - () => crypto.setEngine('nodejs-test-invalid-engine'), - (err) => { - return err.code === 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED' || - err.code === 'ERR_CRYPTO_ENGINE_UNKNOWN'; - }, -); +// DEP0183: OpenSSL engine-based APIs have reached End-of-Life. +assert.strictEqual(Object.hasOwn(crypto, 'setEngine'), false); +import('node:crypto').then(common.mustCall((esmCrypto) => { + assert.strictEqual(Object.hasOwn(esmCrypto, 'setEngine'), false); +})); + +for (const name of [ + 'ENGINE_METHOD_RSA', + 'ENGINE_METHOD_DSA', + 'ENGINE_METHOD_DH', + 'ENGINE_METHOD_RAND', + 'ENGINE_METHOD_CIPHERS', + 'ENGINE_METHOD_DIGESTS', + 'ENGINE_METHOD_PKEY_METHS', + 'ENGINE_METHOD_PKEY_ASN1_METHS', + 'ENGINE_METHOD_EC', + 'ENGINE_METHOD_ALL', + 'ENGINE_METHOD_NONE', +]) { + assert.strictEqual(Object.hasOwn(crypto.constants, name), false); +} + +const binding = internalBinding('crypto'); +assert.strictEqual(Object.hasOwn(binding, 'setEngine'), false); +const secureContext = new binding.SecureContext(); +assert.strictEqual('setEngineKey' in secureContext, false); +assert.strictEqual('setClientCertEngine' in secureContext, false); + +const engineError = { + code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', + message: 'Custom engines not supported by this version of Node.js', +}; +const engineOptions = [ + { clientCertEngine: 'engine' }, + { clientCertEngine: 0 }, + { privateKeyEngine: 'engine' }, + { privateKeyEngine: false }, + { privateKeyIdentifier: 'key' }, + { privateKeyIdentifier: '' }, + { privateKeyIdentifier: 'key', privateKeyEngine: 'engine' }, +]; +const existingContext = tls.createSecureContext(); + +// The removed TLS options remain recognized so they cannot appear to work. +for (const options of engineOptions) { + assert.throws(() => tls.createSecureContext(options), engineError); + assert.throws(() => tls.createServer(options), engineError); + assert.throws( + () => tls.connect({ port: 443, secureContext: existingContext, ...options }), + engineError, + ); + assert.throws( + () => new tls.TLSSocket(undefined, { secureContext: existingContext, ...options }), + engineError, + ); + assert.throws( + () => https.request({ host: 'localhost', port: 443, agent: false, ...options }), + engineError, + ); +} + +// HTTPS rejects the options before a pooled socket could hide their use. +const agent = new https.Agent(); +const options = { host: 'example.com', port: 443 }; +for (const removedOption of [ + 'clientCertEngine', + 'privateKeyEngine', + 'privateKeyIdentifier', +]) { + assert.throws( + () => new https.Agent({ [removedOption]: 'engine' }), + engineError, + ); + assert.throws( + () => agent.getName({ ...options, [removedOption]: 'engine' }), + engineError, + ); +} diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js deleted file mode 100644 index 06c88272438a..000000000000 --- a/test/parallel/test-crypto-ecb.js +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -if (!common.hasCrypto) { - common.skip('missing crypto'); -} - -const { hasOpenSSL3 } = require('../common/crypto'); -const crypto = require('crypto'); - -if (crypto.getFips()) { - common.skip('BF-ECB is not FIPS 140-2 compatible'); -} - -if (hasOpenSSL3) { - common.skip('Blowfish is only available with the legacy provider in ' + - 'OpenSSl 3.x'); -} - -if (!crypto.getCiphers().includes('BF-ECB')) { - common.skip('BF-ECB cipher is not available'); -} - -const assert = require('assert'); - -// Testing whether EVP_CipherInit_ex is functioning correctly. -// Reference: bug#1997 - -{ - const encrypt = - crypto.createCipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); - let hex = encrypt.update('Hello World!', 'ascii', 'hex'); - hex += encrypt.final('hex'); - assert.strictEqual(hex.toUpperCase(), '6D385F424AAB0CFBF0BB86E07FFB7D71'); -} - -{ - const decrypt = - crypto.createDecipheriv('BF-ECB', 'SomeRandomBlahz0c5GZVnR', ''); - let msg = decrypt.update('6D385F424AAB0CFBF0BB86E07FFB7D71', 'hex', 'ascii'); - msg += decrypt.final('ascii'); - assert.strictEqual(msg, 'Hello World!'); -} diff --git a/test/parallel/test-crypto-getcipherinfo.js b/test/parallel/test-crypto-getcipherinfo.js index 5afd2e5a4208..59818da5b921 100644 --- a/test/parallel/test-crypto-getcipherinfo.js +++ b/test/parallel/test-crypto-getcipherinfo.js @@ -10,7 +10,7 @@ const { getCiphers, getCipherInfo, } = require('crypto'); -const { hasFIPS, hasOpenSSL3 } = require('../common/crypto'); +const { hasFIPS } = require('../common/crypto'); const assert = require('assert'); @@ -18,7 +18,7 @@ const ciphers = getCiphers(); assert.strictEqual(getCipherInfo(-1), undefined); assert.strictEqual(getCipherInfo('cipher that does not exist'), undefined); -if (hasOpenSSL3) { +if (!process.features.openssl_is_boringssl) { assert.deepStrictEqual( ciphers.filter((cipher) => cipher.includes('cbc-hmac')), []); for (const cipher of [ diff --git a/test/parallel/test-crypto-key-store-pkcs11.js b/test/parallel/test-crypto-key-store-pkcs11.js index 0fec81a9c647..5459ef39c915 100644 --- a/test/parallel/test-crypto-key-store-pkcs11.js +++ b/test/parallel/test-crypto-key-store-pkcs11.js @@ -3,9 +3,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3, 0)) - common.skip('requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) + common.skip('OpenSSL provider support is required'); // The PKCS#11 token, the OpenSSL configuration that activates a provider for // it, and the PIN that unlocks it are all provided by the environment. See diff --git a/test/parallel/test-crypto-key-store.js b/test/parallel/test-crypto-key-store.js index 58a23192b28f..97ee26280e62 100644 --- a/test/parallel/test-crypto-key-store.js +++ b/test/parallel/test-crypto-key-store.js @@ -3,8 +3,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); const { hasFIPS, hasOpenSSL } = require('../common/crypto'); -if (!hasOpenSSL(3)) - common.skip('requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) + common.skip('OpenSSL provider support is required'); // Verifies that crypto.createPrivateKey() can pass a WHATWG URL (here a file: // URI) to an OpenSSL STORE loader, and that the resulting KeyObject works for diff --git a/test/parallel/test-crypto-provider-cipher-cache-snapshot.js b/test/parallel/test-crypto-provider-cipher-cache-snapshot.js index 1afc5df8d94d..4693440e5ebf 100644 --- a/test/parallel/test-crypto-provider-cipher-cache-snapshot.js +++ b/test/parallel/test-crypto-provider-cipher-cache-snapshot.js @@ -5,13 +5,12 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const { hasOpenSSL3 } = require('../common/crypto'); const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { buildSnapshot, runWithSnapshot } = require('../common/snapshot'); -if (!hasOpenSSL3) - common.skip('this test requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) + common.skip('OpenSSL provider support is required'); const entry = fixtures.path('snapshot', 'crypto-provider-cipher-cache.js'); const buildEnv = { diff --git a/test/parallel/test-crypto-provider-cipher-cache.js b/test/parallel/test-crypto-provider-cipher-cache.js index bde9988480ed..2f7e294c0c32 100644 --- a/test/parallel/test-crypto-provider-cipher-cache.js +++ b/test/parallel/test-crypto-provider-cipher-cache.js @@ -5,9 +5,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); -if (!hasOpenSSL3) - common.skip('this test requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) + common.skip('OpenSSL provider support is required'); const assert = require('assert'); const { diff --git a/test/parallel/test-crypto-provider-hash-options.js b/test/parallel/test-crypto-provider-hash-options.js index 609d00d7f7b0..47692d6dbf9d 100644 --- a/test/parallel/test-crypto-provider-hash-options.js +++ b/test/parallel/test-crypto-provider-hash-options.js @@ -9,7 +9,7 @@ if (!common.hasCrypto) { if (Number(process.versions.openssl.split('.')[0]) < 4 || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 4 provider support is required'); + common.skip('OpenSSL 4.0 or later is required'); } const assert = require('node:assert'); diff --git a/test/parallel/test-crypto-provider-hashes.js b/test/parallel/test-crypto-provider-hashes.js index 166efaa0d7fd..d355b16be672 100644 --- a/test/parallel/test-crypto-provider-hashes.js +++ b/test/parallel/test-crypto-provider-hashes.js @@ -26,10 +26,8 @@ const { sign, verify, } = require('node:crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); - -if (!hasOpenSSL3 || process.features.openssl_is_boringssl) { - common.skip('OpenSSL 3 provider support is required'); +if (process.features.openssl_is_boringssl) { + common.skip('OpenSSL provider support is required'); } const { internalBinding } = require('internal/test/binding'); diff --git a/test/parallel/test-crypto-sec-level.js b/test/parallel/test-crypto-sec-level.js index f2c0e3900624..276a065029ed 100644 --- a/test/parallel/test-crypto-sec-level.js +++ b/test/parallel/test-crypto-sec-level.js @@ -11,7 +11,7 @@ const assert = require('assert'); // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour // This test simply validates that we can get some value for the secLevel // when needed by tests. const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); diff --git a/test/parallel/test-dsa-fips-invalid-key.js b/test/parallel/test-dsa-fips-invalid-key.js index 3df51bfbed35..43ac7e22ced6 100644 --- a/test/parallel/test-dsa-fips-invalid-key.js +++ b/test/parallel/test-dsa-fips-invalid-key.js @@ -9,7 +9,7 @@ const fixtures = require('../common/fixtures'); const crypto = require('crypto'); if (!crypto.getFips()) { - common.skip('node compiled without FIPS OpenSSL.'); + common.skip('OpenSSL is not configured for FIPS mode'); } const assert = require('assert'); diff --git a/test/parallel/test-https-agent-getname.js b/test/parallel/test-https-agent-getname.js index 8ead852b1df5..27dca59fec6e 100644 --- a/test/parallel/test-https-agent-getname.js +++ b/test/parallel/test-https-agent-getname.js @@ -13,13 +13,13 @@ const agent = new https.Agent(); // empty argument assert.strictEqual( agent.getName(), - 'localhost::::::::::::::::::::::' + 'localhost:::::::::::::::::::' ); // empty options assert.strictEqual( agent.getName({}), - 'localhost::::::::::::::::::::::' + 'localhost:::::::::::::::::::' ); // Pass all options arguments @@ -29,7 +29,6 @@ const options = { localAddress: '192.168.1.1', ca: 'ca', cert: 'cert', - clientCertEngine: 'dynamic', ciphers: 'ciphers', crl: [Buffer.from('c'), Buffer.from('r'), Buffer.from('l')], dhparam: 'dhparam', @@ -43,15 +42,13 @@ const options = { servername: 'localhost', sessionIdContext: 'sessionIdContext', sigalgs: 'sigalgs', - privateKeyIdentifier: 'privateKeyIdentifier', - privateKeyEngine: 'privateKeyEngine', }; assert.strictEqual( agent.getName(options), - '0.0.0.0:443:192.168.1.1:ca:cert:dynamic:ciphers:key:pfx:false:localhost:' + + '0.0.0.0:443:192.168.1.1:ca:cert:ciphers:key:pfx:false:localhost:' + '::secureProtocol:c,r,l:false:ecdhCurve:dhparam:0:sessionIdContext:' + - '"sigalgs":privateKeyIdentifier:privateKeyEngine' + '"sigalgs"' ); { diff --git a/test/parallel/test-permission-openssl-store.js b/test/parallel/test-permission-openssl-store.js index ca2f240a9520..a7055dcc6fc7 100644 --- a/test/parallel/test-permission-openssl-store.js +++ b/test/parallel/test-permission-openssl-store.js @@ -4,9 +4,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const { hasOpenSSL3 } = require('../common/crypto'); -if (!hasOpenSSL3) - common.skip('requires OpenSSL 3.x'); +if (process.features.openssl_is_boringssl) + common.skip('OpenSSL provider support is required'); // Verifies the openssl.store permission: allowed when --allow-openssl-store is // set, can be dropped at runtime, and denied by default in a child process. diff --git a/test/parallel/test-process-versions.js b/test/parallel/test-process-versions.js index 14ac88d76cd2..7b434d3e5daa 100644 --- a/test/parallel/test-process-versions.js +++ b/test/parallel/test-process-versions.js @@ -104,18 +104,14 @@ assert.match( assert.match(process.versions.modules, /^\d+$/); if (common.hasCrypto) { - const { hasOpenSSL3 } = require('../common/crypto'); assert.match(process.versions.ncrypto, commonTemplate); if (process.config.variables.node_shared_openssl) { assert.ok(process.versions.openssl); } else { - const versionRegex = hasOpenSSL3 ? - // The following also matches a development version of OpenSSL 3.x which - // can be in the format '3.0.0-alpha4-dev'. This can be handy when - // building and linking against the main development branch of OpenSSL. - /^\d+\.\d+\.\d+(?:[-+][a-z0-9]+)*$/ : - /^\d+\.\d+\.\d+[a-z]?(\+quic)?(-fips)?$/; - assert.match(process.versions.openssl, versionRegex); + // The following also matches a development version of OpenSSL 3.x which + // can be in the format '3.0.0-alpha4-dev'. This can be handy when + // building and linking against the main development branch of OpenSSL. + assert.match(process.versions.openssl, /^\d+\.\d+\.\d+(?:[-+][a-z0-9]+)*$/); } } diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index 8f3b2eafbb8a..d3714b469b1c 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -8,7 +8,7 @@ if (!common.hasCrypto) // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-tls-clientcertengine-invalid-arg-type.js b/test/parallel/test-tls-clientcertengine-invalid-arg-type.js deleted file mode 100644 index 811e320b0788..000000000000 --- a/test/parallel/test-tls-clientcertengine-invalid-arg-type.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -{ - assert.throws( - () => { tls.createSecureContext({ clientCertEngine: 0 }); }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)/ }); -} diff --git a/test/parallel/test-tls-clientcertengine-unsupported.js b/test/parallel/test-tls-clientcertengine-unsupported.js deleted file mode 100644 index aa0bf4a18d6a..000000000000 --- a/test/parallel/test-tls-clientcertengine-unsupported.js +++ /dev/null @@ -1,39 +0,0 @@ -// Flags: --expose-internals -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); - -common.expectWarning({ - 'internal/test/binding': - 'These APIs are for internal testing only. Do not use them.', - 'DeprecationWarning': { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -// Monkey-patch SecureContext -const { internalBinding } = require('internal/test/binding'); -const binding = internalBinding('crypto'); -const NativeSecureContext = binding.SecureContext; - -binding.SecureContext = function() { - const rv = new NativeSecureContext(); - rv.setClientCertEngine = undefined; - return rv; -}; - -const tls = require('tls'); - -{ - assert.throws( - () => { tls.createSecureContext({ clientCertEngine: 'Cannonmouth' }); }, - { - code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - message: 'Custom engines not supported by this OpenSSL' - } - ); -} diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js index 65f3dc6867c4..0b0cdb93dad5 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -41,7 +41,7 @@ const { // are available by default. Different OpenSSL versions have different // default security levels and we use this value to adjust what a test // expects based on the security level. You can read more in -// https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_security_level/#default-callback-behaviour +// https://docs.openssl.org/3.0/man3/SSL_CTX_set_security_level/#default-callback-behaviour const secLevel = require('internal/crypto/util').getOpenSSLSecLevel(); if (!opensslCli) { diff --git a/test/parallel/test-tls-error-stack.js b/test/parallel/test-tls-error-stack.js deleted file mode 100644 index 0a952a46bdd4..000000000000 --- a/test/parallel/test-tls-error-stack.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -// This tests that the crypto error stack can be correctly converted. -const common = require('../common'); -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -const secureContext = tls.createSecureContext(); -if (typeof secureContext.context.setClientCertEngine !== 'function') - common.skip('OpenSSL dropped engine support'); - -common.expectWarning({ - DeprecationWarning: { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -assert.throws(() => { - tls.createSecureContext({ clientCertEngine: 'x' }); -}, (err) => { - return err.name === 'Error' && - /could not load the shared library/.test(err.message) && - Array.isArray(err.opensslErrorStack) && - err.opensslErrorStack.length > 0; -}); diff --git a/test/parallel/test-tls-keyengine-invalid-arg-type.js b/test/parallel/test-tls-keyengine-invalid-arg-type.js deleted file mode 100644 index 72fe526daffa..000000000000 --- a/test/parallel/test-tls-keyengine-invalid-arg-type.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const tls = require('tls'); - -assert.throws( - () => { - tls.createSecureContext({ privateKeyEngine: 0, - privateKeyIdentifier: 'key' }); - }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)$/ }); - -assert.throws( - () => { - tls.createSecureContext({ privateKeyEngine: 'engine', - privateKeyIdentifier: 0 }); - }, - { code: 'ERR_INVALID_ARG_TYPE', - message: / Received type number \(0\)$/ }); diff --git a/test/parallel/test-tls-keyengine-unsupported.js b/test/parallel/test-tls-keyengine-unsupported.js deleted file mode 100644 index 3473fe533f22..000000000000 --- a/test/parallel/test-tls-keyengine-unsupported.js +++ /dev/null @@ -1,44 +0,0 @@ -// Flags: --expose-internals -'use strict'; -const common = require('../common'); - -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); - -common.expectWarning({ - 'internal/test/binding': - 'These APIs are for internal testing only. Do not use them.', - 'DeprecationWarning': { - DEP0183: 'OpenSSL engine-based APIs are deprecated.', - }, -}); - -// Monkey-patch SecureContext -const { internalBinding } = require('internal/test/binding'); -const binding = internalBinding('crypto'); -const NativeSecureContext = binding.SecureContext; - -binding.SecureContext = function() { - const rv = new NativeSecureContext(); - rv.setEngineKey = undefined; - return rv; -}; - -const tls = require('tls'); - -{ - assert.throws( - () => { - tls.createSecureContext({ - privateKeyEngine: 'engine', - privateKeyIdentifier: 'key' - }); - }, - { - code: 'ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED', - message: 'Custom engines not supported by this OpenSSL' - } - ); -} diff --git a/tools/enable_fips_include.py b/tools/enable_fips_include.py deleted file mode 100644 index cb24c7d83b68..000000000000 --- a/tools/enable_fips_include.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2008 the V8 project authors. All rights reserved. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import sys - -# Copy openssl.cnf into output directory -__import__('copyfile') - -# Open the copied openssl.cnf file -fin = open(sys.argv[2], "rt") -data = fin.read() -data = data.replace('# .include fipsmodule.cnf', '.include %s' % sys.argv[3]) -data = data.replace('# fips = fips_sect', 'fips = fips_sect') -data = data.replace('# activate = 1', 'activate = 1') -fin.close() -fin = open(sys.argv[2], "wt") -fin.write(data) -fin.close() diff --git a/tools/eslint-rules/crypto-check.js b/tools/eslint-rules/crypto-check.js index 10862c1b160b..bd79303829bf 100644 --- a/tools/eslint-rules/crypto-check.js +++ b/tools/eslint-rules/crypto-check.js @@ -48,7 +48,7 @@ module.exports = { } function isCryptoCheck(node) { - return utils.usesCommonProperty(node, ['hasCrypto', 'hasFipsCrypto']); + return utils.usesCommonProperty(node, ['hasCrypto']); } function checkCryptoCall(node) { diff --git a/tools/test.py b/tools/test.py index 2c2a4d78d80a..aa8c3fbddf53 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1460,7 +1460,7 @@ def BuildOptions(): help='Send SIGABRT instead of SIGTERM to kill processes that time out', default=False, action="store_true", dest="abort_on_timeout") result.add_argument("--type", - help="Type of build (simple, fips, coverage)", + help="Type of build (simple, coverage)", default=None) result.add_argument("--error-reporter", help="use error reporter if the test uses node:test", @@ -1622,14 +1622,9 @@ def ArgsToTestPaths(test_root, args, suites): def get_env_type(vm, options_type, context): if options_type is not None: - env_type = options_type - else: - # 'simple' is the default value for 'env_type'. - env_type = 'simple' - ssl_ver = Execute([vm, '-p', 'process.versions.openssl'], context).stdout - if 'fips' in ssl_ver: - env_type = 'fips' - return env_type + return options_type + # 'simple' is the default value for 'env_type'. + return 'simple' def get_asan_state(vm, context): diff --git a/typings/internalBinding/config.d.ts b/typings/internalBinding/config.d.ts index 5651b391b88e..e85f1a815a8e 100644 --- a/typings/internalBinding/config.d.ts +++ b/typings/internalBinding/config.d.ts @@ -2,7 +2,6 @@ export interface ConfigBinding { isDebugBuild: boolean; openSSLIsBoringSSL: boolean; hasOpenSSL: boolean; - fipsMode: boolean; hasIntl: boolean; hasSmallICU: boolean; hasTracing: boolean; diff --git a/typings/internalBinding/constants.d.ts b/typings/internalBinding/constants.d.ts index 3c29df44c133..ab3581ffa0f3 100644 --- a/typings/internalBinding/constants.d.ts +++ b/typings/internalBinding/constants.d.ts @@ -217,17 +217,6 @@ export interface ConstantsBinding { SSL_OP_NO_TLSv1_3: 536870912; SSL_OP_PRIORITIZE_CHACHA: 2097152; SSL_OP_TLS_ROLLBACK_BUG: 8388608; - ENGINE_METHOD_RSA: 1; - ENGINE_METHOD_DSA: 2; - ENGINE_METHOD_DH: 4; - ENGINE_METHOD_RAND: 8; - ENGINE_METHOD_EC: 2048; - ENGINE_METHOD_CIPHERS: 64; - ENGINE_METHOD_DIGESTS: 128; - ENGINE_METHOD_PKEY_METHS: 512; - ENGINE_METHOD_PKEY_ASN1_METHS: 1024; - ENGINE_METHOD_ALL: 65535; - ENGINE_METHOD_NONE: 0; DH_CHECK_P_NOT_SAFE_PRIME: 2; DH_CHECK_P_NOT_PRIME: 1; DH_UNABLE_TO_CHECK_GENERATOR: 4; diff --git a/typings/internalBinding/crypto.d.ts b/typings/internalBinding/crypto.d.ts index 9724b750e3e7..39f25f21ee86 100644 --- a/typings/internalBinding/crypto.d.ts +++ b/typings/internalBinding/crypto.d.ts @@ -697,7 +697,6 @@ declare namespace InternalCryptoBinding { init(secureProtocol: string | undefined, minVersion: number, maxVersion: number): void; setKey(key: ByteSource, passphrase?: ByteSource): void; setSigalgs(sigalgs: string): void; - setEngineKey?(privateKeyIdentifier: string, privateKeyEngine: string): void; setCert(cert: ByteSource): void; setAllowPartialTrustChain(): void; addCACert(cert: ByteSource): void; @@ -717,7 +716,6 @@ declare namespace InternalCryptoBinding { setCertificateCompression(algorithms: number): void; close(): void; loadPKCS12(pfx: ByteSource, passphrase?: ByteSource): void; - setClientCertEngine(clientCertEngine: string): void; getTicketKeys(): Buffer; setTicketKeys(keys: ByteSource): void; enableTicketKeyCallback(): void; @@ -1003,7 +1001,6 @@ export interface CryptoBinding { resetRootCertStore(): void; secureBuffer(length: number): Uint8Array | undefined; secureHeapUsed(): bigint | undefined; - setEngine?(engine: string, flags: number): void; setFipsCrypto(fips: boolean | number): void; startLoadingCertificatesOffThread(): void; testFipsCrypto(): 0 | 1;