Files
electron/patches/node/fix_handle_boringssl_and_openssl_incompatibilities.patch
electron-roller[bot] eb7a5c2548 chore: bump node to v20.18.3 (34-x-y) (#45575)
* chore: bump node in DEPS to v20.18.3

* src: fix outdated js2c.cc references

https://github.com/nodejs/node/pull/56133

* lib: remove startsWith/endsWith primordials for char checks

https://github.com/nodejs/node/pull/55407

* test,crypto: make crypto tests work with BoringSSL

https://github.com/nodejs/node/pull/55491

* fix: potential WIN32_LEAN_AND_MEAN redefinition

https://github.com/c-ares/c-ares/pull/869

* chore: fixup patch indices

* deps: update c-ares to v1.34.1

https://github.com/nodejs/node/pull/55369

* chore: fix bssl test

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-02-13 19:26:54 +01:00

416 lines
16 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 12 Feb 2020 15:08:04 -0800
Subject: fix: handle BoringSSL and OpenSSL incompatibilities
This patch corrects for imcompatibilities between OpenSSL, which Node.js uses,
and BoringSSL which Electron uses via Chromium. Each incompatibility typically has
~2 paths forward:
* Upstream a shim or adapted implementation to BoringSSL
* Alter Node.js functionality to something which both libraries can handle.
Where possible, we should seek to make this patch as minimal as possible.
Upstreams:
- https://github.com/nodejs/node/pull/39054
- https://github.com/nodejs/node/pull/39138
- https://github.com/nodejs/node/pull/39136
diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
index 4f0637f9511d1b90ae9d33760428dceb772667bd..5aba390c49613816ac359dfe995dc2c0a93f2206 100644
--- a/src/crypto/crypto_cipher.cc
+++ b/src/crypto/crypto_cipher.cc
@@ -1088,7 +1088,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
return ThrowCryptoError(env, ERR_get_error());
}
-
+#ifndef OPENSSL_IS_BORINGSSL
int rsa_pkcs1_implicit_rejection =
EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
// From the doc -2 means that the option is not supported.
@@ -1104,6 +1104,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
"RSA_PKCS1_PADDING is no longer supported for private decryption,"
" this can be reverted with --security-revert=CVE-2023-46809");
}
+#endif
}
const EVP_MD* digest = nullptr;
diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc
index 85d48dfd2c15c453707bf6eb94e22f89b4f856b2..fe31a9a7f465a03d2de365cef392dfbb7c540156 100644
--- a/src/crypto/crypto_common.cc
+++ b/src/crypto/crypto_common.cc
@@ -158,7 +158,7 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
const unsigned char* buf;
size_t len;
size_t rem;
-
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_client_hello_get0_ext(
ssl.get(),
TLSEXT_TYPE_application_layer_protocol_negotiation,
@@ -171,13 +171,15 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
len = (buf[0] << 8) | buf[1];
if (len + 2 != rem) return nullptr;
return reinterpret_cast<const char*>(buf + 3);
+#endif
+ return nullptr;
}
const char* GetClientHelloServerName(const SSLPointer& ssl) {
const unsigned char* buf;
size_t len;
size_t rem;
-
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_client_hello_get0_ext(
ssl.get(),
TLSEXT_TYPE_server_name,
@@ -199,6 +201,8 @@ const char* GetClientHelloServerName(const SSLPointer& ssl) {
if (len + 2 > rem)
return nullptr;
return reinterpret_cast<const char*>(buf + 5);
+#endif
+ return nullptr;
}
const char* GetServerName(SSL* ssl) {
@@ -1036,14 +1040,14 @@ MaybeLocal<Array> GetClientHelloCiphers(
Environment* env,
const SSLPointer& ssl) {
EscapableHandleScope scope(env->isolate());
- const unsigned char* buf;
- size_t len = SSL_client_hello_get0_ciphers(ssl.get(), &buf);
+ // const unsigned char* buf = nullptr;
+ size_t len = 0; // SSL_client_hello_get0_ciphers(ssl.get(), &buf);
size_t count = len / 2;
MaybeStackBuffer<Local<Value>, 16> ciphers(count);
int j = 0;
for (size_t n = 0; n < len; n += 2) {
- const SSL_CIPHER* cipher = SSL_CIPHER_find(ssl.get(), buf);
- buf += 2;
+ const SSL_CIPHER* cipher = nullptr; // SSL_CIPHER_find(ssl.get(), buf);
+ // buf += 2;
Local<Object> obj = Object::New(env->isolate());
if (!Set(env->context(),
obj,
@@ -1096,8 +1100,11 @@ MaybeLocal<Object> GetEphemeralKey(Environment* env, const SSLPointer& ssl) {
EscapableHandleScope scope(env->isolate());
Local<Object> info = Object::New(env->isolate());
+#ifndef OPENSSL_IS_BORINGSSL
if (!SSL_get_peer_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
-
+#else
+ if (!SSL_get_server_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
+#endif
Local<Context> context = env->context();
crypto::EVPKeyPointer key(raw_key);
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index cef0c877c67643d47da787eddb95ed5a410a941b..1b8af49a48f1a34a92d4f0b502d435f3a4ab5d8e 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -63,7 +63,7 @@ inline X509_STORE* GetOrCreateRootCertStore() {
// Caller responsible for BIO_free_all-ing the returned object.
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
if (v->IsString() || v->IsArrayBufferView()) {
- BIOPointer bio(BIO_new(BIO_s_secmem()));
+ BIOPointer bio(BIO_new(BIO_s_mem()));
if (!bio) return nullptr;
ByteSource bsrc = ByteSource::FromStringOrBuffer(env, v);
if (bsrc.size() > INT_MAX) return nullptr;
@@ -882,10 +882,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
// If the user specified "auto" for dhparams, the JavaScript layer will pass
// true to this function instead of the original string. Any other string
// value will be interpreted as custom DH parameters below.
+#ifndef OPENSSL_IS_BORINGSSL
if (args[0]->IsTrue()) {
CHECK(SSL_CTX_set_dh_auto(sc->ctx_.get(), true));
return;
}
+#endif
DHPointer dh;
{
diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
index dac37f52b9687cadfa2d02152241e9a6e4c16ddf..d47cfa4ad8707ed7f0a42e7fe176fec25be64305 100644
--- a/src/crypto/crypto_dh.cc
+++ b/src/crypto/crypto_dh.cc
@@ -154,13 +154,11 @@ bool DiffieHellman::Init(BignumPointer&& bn_p, int g) {
bool DiffieHellman::Init(const char* p, int p_len, int g) {
dh_.reset(DH_new());
if (p_len <= 0) {
- ERR_put_error(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX,
- BN_R_BITS_TOO_SMALL, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return false;
}
if (g <= 1) {
- ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
- DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return false;
}
BignumPointer bn_p(
@@ -176,20 +174,17 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
dh_.reset(DH_new());
if (p_len <= 0) {
- ERR_put_error(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX,
- BN_R_BITS_TOO_SMALL, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return false;
}
if (g_len <= 0) {
- ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
- DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return false;
}
BignumPointer bn_g(
BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, nullptr));
if (BN_is_zero(bn_g.get()) || BN_is_one(bn_g.get())) {
- ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
- DH_R_BAD_GENERATOR, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
return false;
}
BignumPointer bn_p(
@@ -219,8 +214,10 @@ typedef BignumPointer (*StandardizedGroupInstantiator)();
inline StandardizedGroupInstantiator FindDiffieHellmanGroup(const char* name) {
#define V(n, p) \
if (StringEqualNoCase(name, n)) return InstantiateStandardizedGroup<p>
+#ifndef OPENSSL_IS_BORINGSSL
V("modp1", BN_get_rfc2409_prime_768);
V("modp2", BN_get_rfc2409_prime_1024);
+#endif
V("modp5", BN_get_rfc3526_prime_1536);
V("modp14", BN_get_rfc3526_prime_2048);
V("modp15", BN_get_rfc3526_prime_3072);
@@ -565,9 +562,11 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
key_params = EVPKeyPointer(EVP_PKEY_new());
CHECK(key_params);
CHECK_EQ(EVP_PKEY_assign_DH(key_params.get(), dh.release()), 1);
- } else if (int* prime_size = std::get_if<int>(&params->params.prime)) {
+ } else if (std::get_if<int>(&params->params.prime)) {
EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr));
EVP_PKEY* raw_params = nullptr;
+#ifndef OPENSSL_IS_BORINGSSL
+ int* prime_size = std::get_if<int>(&params->params.prime);
if (!param_ctx ||
EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
EVP_PKEY_CTX_set_dh_paramgen_prime_len(
@@ -581,6 +580,9 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
}
key_params = EVPKeyPointer(raw_params);
+#else
+ return EVPKeyCtxPointer();
+#endif
} else {
UNREACHABLE();
}
diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc
index 3fa4a415dc911a13afd90dfb31c1ed4ad0fd268f..fa48dffc31342c44a1c1207b9d4c3dc72ed93b60 100644
--- a/src/crypto/crypto_dsa.cc
+++ b/src/crypto/crypto_dsa.cc
@@ -40,7 +40,7 @@ namespace crypto {
EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr));
EVP_PKEY* raw_params = nullptr;
-
+#ifndef OPENSSL_IS_BORINGSSL
if (!param_ctx ||
EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
EVP_PKEY_CTX_set_dsa_paramgen_bits(
@@ -55,7 +55,9 @@ EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
return EVPKeyCtxPointer();
}
}
-
+#else
+ return EVPKeyCtxPointer();
+#endif
if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
return EVPKeyCtxPointer();
diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc
index 35474c31bfc2e3692b7ca10e4ed7026b9c275dfb..43c42c14f75018d4705f218fe4ed7e5dacb46bb8 100644
--- a/src/crypto/crypto_keys.cc
+++ b/src/crypto/crypto_keys.cc
@@ -1239,6 +1239,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
}
bool KeyObjectHandle::CheckEcKeyData() const {
+#ifndef OPENSSL_IS_BORINGSSL
MarkPopErrorOnReturn mark_pop_error_on_return;
const ManagedEVPPKey& key = data_->GetAsymmetricKey();
@@ -1257,6 +1258,9 @@ bool KeyObjectHandle::CheckEcKeyData() const {
#else
return EVP_PKEY_public_check(ctx.get()) == 1;
#endif
+#else
+ return true;
+#endif
}
void KeyObjectHandle::CheckEcKeyData(const FunctionCallbackInfo<Value>& args) {
diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc
index 48154df7dc91ed7c0d65323199bc2f59dfc68135..6431e5c3062890975854780d15ecb84370b81770 100644
--- a/src/crypto/crypto_random.cc
+++ b/src/crypto/crypto_random.cc
@@ -140,7 +140,7 @@ Maybe<bool> RandomPrimeTraits::AdditionalConfig(
params->bits = bits;
params->safe = safe;
- params->prime.reset(BN_secure_new());
+ params->prime.reset(BN_new());
if (!params->prime) {
THROW_ERR_CRYPTO_OPERATION_FAILED(env, "could not generate prime");
return Nothing<bool>();
diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc
index 23b2b8c56dec8ac600b8f14b78d9e80b7fa3ed3b..e7a8fe4181542252d9142ea9460cacc5b4acd00d 100644
--- a/src/crypto/crypto_rsa.cc
+++ b/src/crypto/crypto_rsa.cc
@@ -616,10 +616,11 @@ Maybe<bool> GetRsaKeyDetail(
}
if (params->saltLength != nullptr) {
- if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
- ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
- return Nothing<bool>();
- }
+ // TODO(codebytere): Upstream a shim to BoringSSL?
+ // if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
+ // ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
+ // return Nothing<bool>();
+ // }
}
if (target
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 990638ec3993bde40ad3dd40d373d816ebc66a6a..63d971e1fe6b861e29c12f04563701b01fdfb976 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -518,24 +518,15 @@ Maybe<void> Decorate(Environment* env,
V(BIO) \
V(PKCS7) \
V(X509V3) \
- V(PKCS12) \
V(RAND) \
- V(DSO) \
V(ENGINE) \
V(OCSP) \
V(UI) \
V(COMP) \
V(ECDSA) \
V(ECDH) \
- V(OSSL_STORE) \
- V(FIPS) \
- V(CMS) \
- V(TS) \
V(HMAC) \
- V(CT) \
- V(ASYNC) \
- V(KDF) \
- V(SM2) \
+ V(HKDF) \
V(USER) \
#define V(name) case ERR_LIB_##name: lib = #name "_"; break;
@@ -716,7 +707,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsUint32());
Environment* env = Environment::GetCurrent(args);
uint32_t len = args[0].As<Uint32>()->Value();
- void* data = OPENSSL_secure_zalloc(len);
+ void* data = OPENSSL_malloc(len);
if (data == nullptr) {
// There's no memory available for the allocation.
// Return nothing.
@@ -727,7 +718,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
data,
len,
[](void* data, size_t len, void* deleter_data) {
- OPENSSL_secure_clear_free(data, len);
+ OPENSSL_clear_free(data, len);
},
data);
Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
@@ -735,10 +726,12 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
}
void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
+#ifndef OPENSSL_IS_BORINGSSL
Environment* env = Environment::GetCurrent(args);
if (CRYPTO_secure_malloc_initialized())
args.GetReturnValue().Set(
BigInt::New(env->isolate(), CRYPTO_secure_used()));
+#endif
}
} // namespace
diff --git a/src/env.h b/src/env.h
index 2ec0a56e05ff879df8c55bf140677e571a56fafa..a30c25a3a61dfe73944731760404c555f2782d72 100644
--- a/src/env.h
+++ b/src/env.h
@@ -49,7 +49,7 @@
#include "uv.h"
#include "v8.h"
-#if HAVE_OPENSSL
+#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3
#include <openssl/evp.h>
#endif
@@ -1051,7 +1051,7 @@ class Environment : public MemoryRetainer {
kExitInfoFieldCount
};
-#if HAVE_OPENSSL
+#if HAVE_OPENSSL// && !defined(OPENSSL_IS_BORINGSSL)
#if OPENSSL_VERSION_MAJOR >= 3
// We declare another alias here to avoid having to include crypto_util.h
using EVPMDPointer = DeleteFnPtr<EVP_MD, EVP_MD_free>;
diff --git a/src/node_metadata.h b/src/node_metadata.h
index cf051585e779e2b03bd7b95fe5008b89cc7f8162..9de49c6828468fdf846dcd4ad445390f14446099 100644
--- a/src/node_metadata.h
+++ b/src/node_metadata.h
@@ -6,7 +6,7 @@
#include <string>
#include "node_version.h"
-#if HAVE_OPENSSL
+#if 0
#include <openssl/crypto.h>
#if NODE_OPENSSL_HAS_QUIC
#include <openssl/quic.h>
diff --git a/src/node_options.cc b/src/node_options.cc
index f6ff810953b224b7e343d91e1065d95bc3e78d39..b7ef44b018c7aec59d8311642a811d1280247689 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -6,7 +6,7 @@
#include "node_external_reference.h"
#include "node_internals.h"
#include "node_sea.h"
-#if HAVE_OPENSSL
+#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
#include "openssl/opensslv.h"
#endif
diff --git a/src/node_options.h b/src/node_options.h
index 10c220f66122336215f25b9674acfdfe6df82a8e..e8b2243d24fe95ff31254071133fb646e186c07e 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -11,7 +11,7 @@
#include "node_mutex.h"
#include "util.h"
-#if HAVE_OPENSSL
+#if 0
#include "openssl/opensslv.h"
#endif