Commit 8be36fb4941 for nodejs
commit 8be36fb49413e8bbc0d4202eeb52b93c62ec4887
Author: Filip Skokan <panva.ip@gmail.com>
Date: Sun Jul 26 14:18:38 2026 +0200
crypto: remove legacy OpenSSL code paths
Remove the OpenSSL 1.x branches and stale version-specific assumptions
from src/. BoringSSL does not define OPENSSL_VERSION_MAJOR, so the
remaining version guards were excluding it as well; use
OPENSSL_IS_BORINGSSL checks instead, including the shared PKCS12 parser
and TLS PFX error handling.
Gate BoringSSL-only alternatives explicitly instead of leaving them
in #else branches, including the MAC/KMAC and OCB fallbacks. Fix the
BoringSSL guard on QUIC's unsupported-backend diagnostic.
Make the OpenSSL legacy-provider command-line help version-neutral.
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/64777
Fixes: https://github.com/nodejs/node/issues/56733
Refs: https://github.com/nodejs/node/pull/64211
Refs: https://github.com/nodejs/node/pull/63966
Refs: https://github.com/nodejs/node/pull/53329
Refs: https://github.com/nodejs/node/pull/48950
Refs: https://github.com/nodejs/node/issues/45465
Refs: https://github.com/nodejs/node/issues/42827
Refs: https://github.com/nodejs/node/issues/47076
Refs: https://github.com/nodejs/node/pull/62862
Refs: https://github.com/nodejs/node/pull/38512
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
diff --git a/src/crypto/README.md b/src/crypto/README.md
index 1655fc5ea0f..63f14030697 100644
--- a/src/crypto/README.md
+++ b/src/crypto/README.md
@@ -93,8 +93,8 @@ use their methods to keep that adaptation inside ncrypto.
Examples of these being used are pervasive through the `src/crypto` code.
`HMACCtxPointer` is a dedicated HMAC state wrapper rather than a plain
-`DeleteFnPtr` alias. On OpenSSL 3 and later it owns the provider-backed
-`EVP_MAC`/`EVP_MAC_CTX` state. On OpenSSL 1.1.1 and BoringSSL it owns the
+`DeleteFnPtr` alias. On OpenSSL it owns the provider-backed
+`EVP_MAC`/`EVP_MAC_CTX` state. On BoringSSL it owns the
legacy `HMAC_CTX` state. HMAC call sites should use `HMACCtxPointer::New()`,
`init()`, `update()`, and `digest()`/`digestInto()` so the backend selection
stays contained in ncrypto.
diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc
index ea869a8eef1..070c05582ee 100644
--- a/src/crypto/crypto_aes.cc
+++ b/src/crypto/crypto_aes.cc
@@ -150,11 +150,8 @@ WebCryptoCipherStatus AES_Cipher(Environment* env,
auto buf = DataPointer::Alloc(buf_len);
auto ptr = static_cast<unsigned char*>(buf.get());
- // In some outdated version of OpenSSL (e.g.
- // ubi81_sharedlibs_openssl111fips_x64) may be used in sharedlib mode, the
- // logic will be failed when input size is zero. The newer OpenSSL has fixed
- // it up. But we still have to regard zero as special in Node.js code to
- // prevent old OpenSSL failure.
+ // Some shared OpenSSL builds fail when the input size is zero. Keep handling
+ // zero-length input in Node.js to avoid relying on backend-specific behavior.
//
// Refs:
// https://github.com/openssl/openssl/commit/420cb707b880e4fb649094241371701013eeb15f
diff --git a/src/crypto/crypto_aes.h b/src/crypto/crypto_aes.h
index 6b18b1e29e2..bea409da94a 100644
--- a/src/crypto/crypto_aes.h
+++ b/src/crypto/crypto_aes.h
@@ -43,7 +43,7 @@ constexpr unsigned kNoAuthTagLength = static_cast<unsigned>(-1);
V(OCB_128, AES_Cipher, ncrypto::Cipher::AES_128_OCB()) \
V(OCB_192, AES_Cipher, ncrypto::Cipher::AES_192_OCB()) \
V(OCB_256, AES_Cipher, ncrypto::Cipher::AES_256_OCB())
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
#define VARIANTS_OCB(V)
#endif
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
index 348d96e6043..f28ecdae965 100644
--- a/src/crypto/crypto_cipher.cc
+++ b/src/crypto/crypto_cipher.cc
@@ -830,8 +830,8 @@ bool CipherBase::Final(std::unique_ptr<BackingStore>* out) {
static_cast<size_t>(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 5163cc1c445..4956d7f5908 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -1857,7 +1857,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& 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
@@ -1876,9 +1876,9 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
CHECK(SSL_CTX_set_min_proto_version(sc->ctx_.get(), min_version));
CHECK(SSL_CTX_set_max_proto_version(sc->ctx_.get(), max_version));
- // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
- // exposed in the public API. To retain compatibility, install a callback
- // which restores the old algorithm.
+ // The ticket key size changed after the original size was exposed in the
+ // public API. To retain compatibility, install a callback which restores
+ // the old algorithm.
if (!ncrypto::CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) ||
!ncrypto::CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) ||
!ncrypto::CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_))) {
@@ -1888,7 +1888,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
SSL_CTX_set_tlsext_ticket_key_evp_cb(sc->ctx_.get(),
TicketCompatibilityCallback);
-#else
+#elif NCRYPTO_USE_BORINGSSL
SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
#endif
}
@@ -2200,7 +2200,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVPKeyPointer params(PEM_read_bio_Parameters(bio.get(), nullptr));
if (params && params.isA(KeyAlgorithm::DH)) dh.reset(params.release());
-#else
+#elif NCRYPTO_USE_BORINGSSL
dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
#endif
}
@@ -2224,7 +2224,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVPKeyPointer dh_pkey(dh.release());
if (!SSL_CTX_set0_tmp_dh_pkey(sc->ctx_.get(), dh_pkey.get())) {
-#else
+#elif NCRYPTO_USE_BORINGSSL
if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
#endif
return THROW_ERR_CRYPTO_OPERATION_FAILED(
@@ -2438,12 +2438,12 @@ void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
namespace {
// The historical error shape for the TLS `pfx` option: the OpenSSL reason
-// string, except for OpenSSL 3's bare "unsupported" error, which on its own
+// string, except for OpenSSL's bare "unsupported" error, which on its own
// says nothing useful.
// TODO(@jasnell): Should this use ThrowCryptoError?
// NOLINTNEXTLINE(runtime/int) -- matches ERR_get_error()
void ThrowPFXError(Environment* env, unsigned long err) {
-#if OPENSSL_VERSION_MAJOR >= 3
+#ifndef OPENSSL_IS_BORINGSSL
if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) {
return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION(
env, "Unsupported PKCS12 PFX data");
@@ -2622,7 +2622,7 @@ void SecureContext::EnableTicketKeyCallback(
#if NCRYPTO_USE_OPENSSL_PROVIDER
SSL_CTX_set_tlsext_ticket_key_evp_cb(wrap->ctx_.get(), TicketKeyCallback);
-#else
+#elif NCRYPTO_USE_BORINGSSL
SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
#endif
}
@@ -2641,7 +2641,7 @@ bool InitTicketHmac(EVP_MAC_CTX* hctx,
};
return EVP_MAC_init(hctx, key, key_len, params) == 1;
}
-#else
+#elif NCRYPTO_USE_BORINGSSL
bool InitTicketHmac(HMAC_CTX* hctx, const unsigned char* key, size_t key_len) {
return HMAC_Init_ex(hctx, key, key_len, Digest::SHA256, nullptr) == 1;
}
@@ -2654,7 +2654,7 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
-#else
+#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc) {
@@ -2751,7 +2751,7 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
-#else
+#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc) {
diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h
index 1a4eba212b6..3a564f83827 100644
--- a/src/crypto/crypto_context.h
+++ b/src/crypto/crypto_context.h
@@ -112,7 +112,7 @@ class SecureContext final : public BaseObject {
static const int kTicketKeyIVIndex = 4;
protected:
- // OpenSSL structures are opaque. This is sizeof(SSL_CTX) for OpenSSL 1.1.1b:
+ // OpenSSL structures are opaque. Estimate SSL_CTX memory usage:
static const int64_t kExternalSize = 1024;
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
@@ -175,7 +175,7 @@ class SecureContext final : public BaseObject {
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
-#else
+#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc);
@@ -186,7 +186,7 @@ class SecureContext final : public BaseObject {
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
-#else
+#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc);
diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
index 8bfde65327f..a65cc2e12e5 100644
--- a/src/crypto/crypto_dh.cc
+++ b/src/crypto/crypto_dh.cc
@@ -81,20 +81,14 @@ MaybeLocal<Value> DataPointerToBuffer(Environment* env, DataPointer&& data) {
void PutDhError(int reason) {
#ifdef OPENSSL_IS_BORINGSSL
OPENSSL_PUT_ERROR(DH, reason);
-#elif NCRYPTO_USE_OPENSSL3_PROVIDER
- ERR_raise(ERR_LIB_DH, reason);
#else
- ERR_put_error(ERR_LIB_DH, 0, reason, __FILE__, __LINE__);
+ ERR_raise(ERR_LIB_DH, reason);
#endif
}
-#if defined(OPENSSL_IS_BORINGSSL) || !NCRYPTO_USE_OPENSSL3_PROVIDER
-void PutBnError(int reason) {
#ifdef OPENSSL_IS_BORINGSSL
+void PutBnError(int reason) {
OPENSSL_PUT_ERROR(BN, reason);
-#else
- ERR_put_error(ERR_LIB_BN, 0, reason, __FILE__, __LINE__);
-#endif
}
#endif
@@ -123,12 +117,8 @@ void New(const FunctionCallbackInfo<Value>& args) {
int32_t bits = args[0].As<Int32>()->Value();
if (bits < 2) {
#ifndef OPENSSL_IS_BORINGSSL
-#if OPENSSL_VERSION_MAJOR >= 3
PutDhError(DH_R_MODULUS_TOO_SMALL);
-#else
- PutBnError(BN_R_BITS_TOO_SMALL);
-#endif // OPENSSL_VERSION_MAJOR >= 3
-#else // OPENSSL_IS_BORINGSSL
+#elif defined(OPENSSL_IS_BORINGSSL)
PutBnError(BN_R_BITS_TOO_SMALL);
#endif // OPENSSL_IS_BORINGSSL
return ThrowCryptoError(env, ERR_get_error(), "Invalid prime length");
diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc
index 81977941889..11274d98568 100644
--- a/src/crypto/crypto_hash.cc
+++ b/src/crypto/crypto_hash.cc
@@ -226,7 +226,7 @@ void SaveSupportedProviderHashAlgorithms(EVP_MD* md, void* arg) {
EVP_MD_names_do_all(md, SaveSupportedProviderHashName, &context);
}
-#else
+#elif NCRYPTO_USE_BORINGSSL
void SaveSupportedHashAlgorithms(const EVP_MD* md,
const char* from,
const char* to,
@@ -253,7 +253,7 @@ const std::vector<std::string>& GetSupportedHashAlgorithms(Environment* env) {
// later lookups instead of throwing them away immediately.
EVP_MD_do_all_sorted(SaveSupportedHashAlgorithmsAndCacheMD, env);
EVP_MD_do_all_provided(nullptr, SaveSupportedProviderHashAlgorithms, env);
-#else
+#elif NCRYPTO_USE_BORINGSSL
EVP_MD_do_all_sorted(SaveSupportedHashAlgorithms, env);
#endif
#if NCRYPTO_USE_BORINGSSL
@@ -351,7 +351,7 @@ const EVP_MD* GetDigestImplementation(
return digest_owner->get();
}
return nullptr;
-#else
+#elif NCRYPTO_USE_BORINGSSL
Utf8Value utf8(env->isolate(), algorithm);
return ncrypto::getDigestByName(*utf8);
#endif
@@ -360,7 +360,7 @@ const EVP_MD* GetDigestImplementation(
void MarkInvalidXofLength() {
#if NCRYPTO_USE_OPENSSL_PROVIDER
ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
-#else
+#elif NCRYPTO_USE_BORINGSSL
EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
#endif
}
@@ -375,7 +375,7 @@ void MarkInvalidXofLength() {
bool IsShakeDigest(const EVP_MD* md) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
return EVP_MD_is_a(md, "SHAKE128") || EVP_MD_is_a(md, "SHAKE256");
-#else
+#elif NCRYPTO_USE_BORINGSSL
const char* name = OBJ_nid2sn(EVP_MD_type(md));
return name != nullptr &&
(strcmp(name, "SHAKE128") == 0 || strcmp(name, "SHAKE256") == 0);
@@ -546,7 +546,7 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
}
if (env->isolate()->HasPendingException()) return;
}
-#else
+#elif NCRYPTO_USE_BORINGSSL
Utf8Value utf8(env->isolate(), args[0]);
return OneShotDigestWithMD(
env, args, ncrypto::getDigestByName(*utf8), nullptr);
diff --git a/src/crypto/crypto_kem.h b/src/crypto/crypto_kem.h
index dc60001e2d1..bdc99499204 100644
--- a/src/crypto/crypto_kem.h
+++ b/src/crypto/crypto_kem.h
@@ -112,15 +112,15 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry);
#else
-// Provide stub implementations when OpenSSL < 3.0
+// Provide stub implementations when KEM is unavailable.
namespace node {
namespace crypto {
namespace KEM {
inline void Initialize(Environment* env, v8::Local<v8::Object> target) {
- // No-op when OpenSSL < 3.0
+ // No-op when KEM is unavailable.
}
inline void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
- // No-op when OpenSSL < 3.0
+ // No-op when KEM is unavailable.
}
} // namespace KEM
} // namespace crypto
diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc
index 71464785c11..88381b901cd 100644
--- a/src/crypto/crypto_keys.cc
+++ b/src/crypto/crypto_keys.cc
@@ -1313,9 +1313,9 @@ void KeyObjectHandle::Equals(const FunctionCallbackInfo<Value>& args) {
case kKeyTypePrivate: {
EVP_PKEY* pkey = key.GetAsymmetricKey().get();
EVP_PKEY* pkey2 = key2.GetAsymmetricKey().get();
-#if OPENSSL_VERSION_MAJOR >= 3
+#ifndef OPENSSL_IS_BORINGSSL
int ok = EVP_PKEY_eq(pkey, pkey2);
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
int ok = EVP_PKEY_cmp(pkey, pkey2);
#endif
if (ok == -2) {
diff --git a/src/crypto/crypto_kmac.h b/src/crypto/crypto_kmac.h
index 4f8fe27d2ff..7698a0dfaa1 100644
--- a/src/crypto/crypto_kmac.h
+++ b/src/crypto/crypto_kmac.h
@@ -64,7 +64,7 @@ void Initialize(Environment* env, v8::Local<v8::Object> target);
void RegisterExternalReferences(ExternalReferenceRegistry* registry);
} // namespace Kmac
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
// If there is no KMAC support, provide empty namespace functions.
namespace Kmac {
void Initialize(Environment* env, v8::Local<v8::Object> target) {}
diff --git a/src/crypto/crypto_mac.cc b/src/crypto/crypto_mac.cc
index 7f43e760ccf..ba34211275f 100644
--- a/src/crypto/crypto_mac.cc
+++ b/src/crypto/crypto_mac.cc
@@ -522,7 +522,7 @@ Mac::Mac(Environment* env,
has_output_length_(has_output_length) {
MakeWeak();
}
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
Mac::Mac(Environment* env, Local<Object> wrap) : BaseObject(env, wrap) {
MakeWeak();
}
@@ -531,7 +531,7 @@ Mac::Mac(Environment* env, Local<Object> wrap) : BaseObject(env, wrap) {
void Mac::MemoryInfo(MemoryTracker* tracker) const {
#if OPENSSL_WITH_EVP_MAC
tracker->TrackFieldWithSize("context", context_ ? kSizeOf_EVP_MAC_CTX : 0);
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
static_cast<void>(tracker);
#endif
}
@@ -570,7 +570,7 @@ void Mac::New(const FunctionCallbackInfo<Value>& args) {
std::move(initialized.context),
initialized.output_size,
initialized.has_output_length);
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args),
"MAC is not supported");
#endif
@@ -585,7 +585,7 @@ void Mac::MacUpdate(const FunctionCallbackInfo<Value>& args) {
size_t length) {
args.GetReturnValue().Set(mac->MacUpdate(data, length));
});
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args),
"MAC is not supported");
#endif
@@ -613,7 +613,7 @@ void Mac::MacFinal(const FunctionCallbackInfo<Value>& args) {
.ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
THROW_ERR_CRYPTO_MAC_NOT_SUPPORTED(Environment::GetCurrent(args),
"MAC is not supported");
#endif
@@ -627,7 +627,7 @@ void Mac::GetMacs(const FunctionCallbackInfo<Value>& args) {
if (ToV8Value(context, GetSupportedMacAlgorithms(env)).ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
args.GetReturnValue().Set(Array::New(args.GetIsolate(), 0));
#endif
}
diff --git a/src/crypto/crypto_mac.h b/src/crypto/crypto_mac.h
index 3223b148710..4da9dcef2dc 100644
--- a/src/crypto/crypto_mac.h
+++ b/src/crypto/crypto_mac.h
@@ -39,7 +39,7 @@ class Mac final : public BaseObject {
ncrypto::EVPMacCtxPointer context_;
size_t output_size_ = 0;
bool has_output_length_ = false;
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
Mac(Environment* env, v8::Local<v8::Object> wrap);
#endif
};
diff --git a/src/crypto/crypto_pkcs12.cc b/src/crypto/crypto_pkcs12.cc
index 8b0af44d9d7..b4e909b2629 100644
--- a/src/crypto/crypto_pkcs12.cc
+++ b/src/crypto/crypto_pkcs12.cc
@@ -60,8 +60,8 @@ PKCS12ParseResult ParsePKCS12Bundle(const BIOPointer& bio, const char* pass) {
return PKCS12ParseResult(PKCS12ParseError::NOT_RECOGNIZED, err);
}
#endif
-#if OPENSSL_VERSION_MAJOR >= 3
- // OpenSSL 3 reports algorithms that moved to the legacy provider as a
+#ifndef OPENSSL_IS_BORINGSSL
+ // OpenSSL reports algorithms that moved to the legacy provider as a
// bare "unsupported" error.
if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) {
return PKCS12ParseResult(PKCS12ParseError::UNSUPPORTED_ALGORITHM, err);
diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc
index c95bd46635f..1ec3a487dfe 100644
--- a/src/crypto/crypto_rsa.cc
+++ b/src/crypto/crypto_rsa.cc
@@ -50,7 +50,7 @@ bool IsRsaPssDigestEncodable(const Digest& digest) {
const ASN1_OBJECT* object = OBJ_nid2obj(nid);
return object != nullptr && OBJ_length(object) > 0;
-#else
+#elif NCRYPTO_USE_BORINGSSL
static_cast<void>(digest);
return true;
#endif
@@ -82,10 +82,8 @@ EVPKeyCtxPointer RsaKeyGenTraits::Setup(RsaKeyPairGenConfig* params) {
return {};
}
- // TODO(tniessen): This appears to only be necessary in OpenSSL 3, while
- // OpenSSL 1.1.1 behaves as recommended by RFC 8017 and defaults the MGF1
- // hash algorithm to the RSA-PSS hashAlgorithm. Remove this code if the
- // behavior of OpenSSL 3 changes.
+ // OpenSSL does not default the MGF1 hash algorithm to the RSA-PSS
+ // hashAlgorithm as recommended by RFC 8017, so set it explicitly.
auto& mgf1_md = params->params.mgf1_md;
if (!mgf1_md && params->params.md) {
mgf1_md = params->params.md;
@@ -397,7 +395,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local<Object> jwk) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
ncrypto::Rsa rsa_view;
-#else
+#elif NCRYPTO_USE_BORINGSSL
RSAPointer rsa(RSA_new());
if (!rsa) {
THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Unable to create RSA pointer");
@@ -511,7 +509,7 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local<Object> jwk) {
#if NCRYPTO_USE_OPENSSL_PROVIDER
auto pkey = EVPKeyPointer::NewRSA(rsa_view);
-#else
+#elif NCRYPTO_USE_BORINGSSL
auto pkey = EVPKeyPointer::NewRSA(std::move(rsa));
#endif
if (!pkey) {
diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc
index a73eb7220a4..5792de0515d 100644
--- a/src/crypto/crypto_tls.cc
+++ b/src/crypto/crypto_tls.cc
@@ -81,7 +81,7 @@ namespace {
// that the user user Connection::VerifyError after the `secure`
// callback has been made.
int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
- // From https://www.openssl.org/docs/man1.1.1/man3/SSL_verify_cb:
+ // From https://www.openssl.org/docs/man3.0/man3/SSL_verify_cb:
//
// If VerifyCallback returns 1, the verification process is continued. If
// VerifyCallback always returns 1, the TLS/SSL handshake will not be
@@ -544,9 +544,9 @@ void TLSWrap::InitSSL() {
SSL_set_mode(ssl_.get(), SSL_MODE_RELEASE_BUFFERS);
#endif // SSL_MODE_RELEASE_BUFFERS
- // This is default in 1.1.1, but set it anyway, Cycle() doesn't currently
- // re-call ClearIn() if SSL_read() returns SSL_ERROR_WANT_READ, so data can be
- // left sitting in the incoming enc_in_ and never get processed.
+ // Set SSL_MODE_AUTO_RETRY explicitly because Cycle() doesn't currently
+ // re-call ClearIn() if SSL_read() returns SSL_ERROR_WANT_READ, so data can
+ // be left sitting in the incoming enc_in_ and never get processed.
// - https://wiki.openssl.org/index.php/TLS1.3#Non-application_data_records
SSL_set_mode(ssl_.get(), SSL_MODE_AUTO_RETRY);
@@ -678,8 +678,8 @@ void TLSWrap::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
}
}
- // SSL_CB_HANDSHAKE_START and SSL_CB_HANDSHAKE_DONE are called
- // sending HelloRequest in OpenSSL-1.1.1.
+ // SSL_CB_HANDSHAKE_START and SSL_CB_HANDSHAKE_DONE are called when sending
+ // HelloRequest.
// We need to check whether this is in a renegotiation state or not.
if (where & SSL_CB_HANDSHAKE_DONE && !SSL_renegotiate_pending(ssl)) {
Debug(c, "SSLInfoCallback(SSL_CB_HANDSHAKE_DONE);");
@@ -953,7 +953,7 @@ void TLSWrap::ClearOut() {
const char* ls = ERR_lib_error_string(ssl_err);
#if NCRYPTO_USE_OPENSSL_PROVIDER
const char* fs = nullptr;
-#else
+#elif NCRYPTO_USE_BORINGSSL
const char* fs = ERR_func_error_string(ssl_err);
#endif
const char* rs = ERR_reason_error_string(ssl_err);
diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h
index ab602401887..f3e0dfff9bc 100644
--- a/src/crypto/crypto_tls.h
+++ b/src/crypto/crypto_tls.h
@@ -155,7 +155,7 @@ class TLSWrap : public AsyncWrap,
}
private:
- // OpenSSL structures are opaque. Estimate SSL memory size for OpenSSL 1.1.1b:
+ // OpenSSL structures are opaque. Estimate SSL memory usage:
// SSL: 6224
// SSL->SSL3_STATE: 1040
// ...some buffers: 42 * 1024
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index b980a578721..8dd7a14e205 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -19,7 +19,7 @@
#include <mutex>
#include "math.h"
-#if OPENSSL_VERSION_MAJOR >= 3
+#ifndef OPENSSL_IS_BORINGSSL
#include "openssl/provider.h"
#endif
@@ -451,7 +451,7 @@ std::optional<std::string> ProcessFipsOptions() {
const bool force_fips = per_process::cli_options->force_fips_crypto;
if (!enable_fips && !force_fips) return std::nullopt;
-#if OPENSSL_VERSION_MAJOR >= 3
+#ifndef OPENSSL_IS_BORINGSSL
// Whether FIPS-approved implementations are reachable is decided by the
// OpenSSL configuration, not by Node.js. Refuse to start rather than
// restrict the default property query to a provider that is not there,
@@ -505,15 +505,6 @@ void InitCryptoOnce() {
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
CHECK_NOT_NULL(settings);
-#if OPENSSL_VERSION_MAJOR < 3
- // --openssl-config=...
- if (!per_process::cli_options->openssl_config.empty()) {
- const char* conf = per_process::cli_options->openssl_config.c_str();
- OPENSSL_INIT_set_config_filename(settings, conf);
- }
-#endif
-
-#if OPENSSL_VERSION_MAJOR >= 3
// --openssl-legacy-provider
if (per_process::cli_options->openssl_legacy_provider) {
OSSL_PROVIDER* legacy_provider = OSSL_PROVIDER_load(nullptr, "legacy");
@@ -521,7 +512,6 @@ void InitCryptoOnce() {
fprintf(stderr, "Unable to load legacy provider.\n");
}
}
-#endif
OPENSSL_init_ssl(0, settings);
InstallFipsIndicatorCallback();
@@ -901,7 +891,7 @@ Maybe<void> Decorate(Environment* env,
const char* ls = ERR_lib_error_string(err);
#if NCRYPTO_USE_OPENSSL_PROVIDER
const char* fs = nullptr;
-#else
+#elif NCRYPTO_USE_BORINGSSL
const char* fs = ERR_func_error_string(err);
#endif
const char* rs = ERR_reason_error_string(err);
diff --git a/src/node.cc b/src/node.cc
index f7a19747bed..0b5b305d688 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -51,7 +51,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
@@ -1305,7 +1305,6 @@ InitializeOncePerProcessInternal(
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(
@@ -1321,6 +1320,7 @@ InitializeOncePerProcessInternal(
// 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.
@@ -1377,11 +1377,7 @@ InitializeOncePerProcessInternal(
GetOpenSSLErrorString());
return result;
}
-#else // OPENSSL_VERSION_MAJOR < 3
- if (FIPS_mode()) {
- OPENSSL_init();
- }
-#endif
+
if (auto fips_error = crypto::ProcessFipsOptions()) {
result->exit_code_ = ExitCode::kGenericUserError;
result->early_return_ = true;
diff --git a/src/node_constants.cc b/src/node_constants.cc
index e8815a80080..ee4eb04ba62 100644
--- a/src/node_constants.cc
+++ b/src/node_constants.cc
@@ -70,7 +70,7 @@
#define RSA_PSS_SALTLEN_AUTO -2
#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)
@@ -87,7 +87,7 @@
#endif
#endif
#ifndef OPENSSL_NO_ENGINE
-#if !defined(OPENSSL_IS_BORINGSSL) && OPENSSL_VERSION_MAJOR >= 3
+#ifndef OPENSSL_IS_BORINGSSL
// Engine constants remain public API while engine implementation lives in the
// dedicated compatibility target.
#define ENGINE_METHOD_RSA (unsigned int)0x0001
diff --git a/src/node_constants.h b/src/node_constants.h
index 7e02db84321..0658c94ef4e 100644
--- a/src/node_constants.h
+++ b/src/node_constants.h
@@ -36,7 +36,7 @@
#define DEFAULT_CIPHER_LIST_CORE NODE_OPENSSL_DEFAULT_CIPHER_LIST
#else
// TLSv1.3 suites start with TLS_, and are the OpenSSL defaults, see:
-// https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_ciphersuites.html
+// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_ciphersuites.html
#define DEFAULT_CIPHER_LIST_CORE \
"TLS_AES_256_GCM_SHA384:" \
"TLS_CHACHA20_POLY1305_SHA256:" \
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 99cb556ecd9..9b096ac8437 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -77,7 +77,7 @@ namespace crypto {
#if OPENSSL_WITH_EVP_MAC
#define KMAC_NAMESPACE_LIST(V) V(Kmac)
-#else
+#elif defined(OPENSSL_IS_BORINGSSL)
#define KMAC_NAMESPACE_LIST(V)
#endif // OPENSSL_WITH_EVP_MAC
diff --git a/src/node_metadata.cc b/src/node_metadata.cc
index 0f3a76105a1..44d9de8abd6 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 bdc8171529b..4ba4801ad1d 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -1790,9 +1790,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",
@@ -1800,7 +1800,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 6323f36dce1..f8aa5825386 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -445,7 +445,7 @@ class PerProcessOptions : public Options {
DEFINE_BOOL_FIELD(force_fips_crypto) = false;
std::string force_fips_crypto_policy = "provider";
#endif // HAVE_OPENSSL
-#if OPENSSL_VERSION_MAJOR >= 3
+#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
DEFINE_BOOL_FIELD(openssl_legacy_provider) = false;
DEFINE_BOOL_FIELD(openssl_shared_config) = false;
#endif
diff --git a/src/quic/tlscontext.h b/src/quic/tlscontext.h
index 8209eda12db..ecadc1fa78d 100644
--- a/src/quic/tlscontext.h
+++ b/src/quic/tlscontext.h
@@ -21,7 +21,7 @@ namespace node::quic {
class Session;
class TLSContext;
-#if OPENSSL_IS_BORING
+#ifdef OPENSSL_IS_BORINGSSL
static_assert(false,
"This implementation of tlscontext relies on OpenSSL APIS "
"that are not available in BoringSSL. An alternative impl "