123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Shelley Vohr <[email protected]>
- 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 67cd4f2adf15e7d8511f561c54163b1842e971af..7e0e1a62289289b8362870ba4869c97494b9298a 100644
- --- a/src/crypto/crypto_cipher.cc
- +++ b/src/crypto/crypto_cipher.cc
- @@ -28,7 +28,8 @@ using v8::Value;
- namespace crypto {
- namespace {
- bool IsSupportedAuthenticatedMode(const EVP_CIPHER* cipher) {
- - switch (EVP_CIPHER_mode(cipher)) {
- + const int mode = EVP_CIPHER_mode(cipher);
- + switch (mode) {
- case EVP_CIPH_CCM_MODE:
- case EVP_CIPH_GCM_MODE:
- #ifndef OPENSSL_NO_OCB
- @@ -1088,7 +1089,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 +1105,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 ee1c7931a5c83eec00fe05807ddb97572fe70cc9..8e297e57fdbc9fd42beb6e4a33cc91b9dd7316b8 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) {
- @@ -206,7 +210,10 @@ const char* GetServerName(SSL* ssl) {
- }
-
- bool SetGroups(SecureContext* sc, const char* groups) {
- +#ifndef OPENSSL_IS_BORINGSSL
- return SSL_CTX_set1_groups_list(sc->ctx().get(), groups) == 1;
- +#endif
- + return SSL_CTX_set1_curves_list(sc->ctx().get(), groups) == 1;
- }
-
- // When adding or removing errors below, please also update the list in the API
- @@ -1044,14 +1051,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,
- diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
- index 6e5bbe07d0c337b36f3157c2e6404fdc91849fd1..7ec682833213de9054a8c30751436d12baaea235 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;
- @@ -861,10 +861,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 b4447102a8478639a5aa774e583834d79808603f..ecf938d51ccdbfcb825d44c5ed4ea1229cb05389 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);
- @@ -559,15 +556,21 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
- return EVPKeyCtxPointer();
- }
-
- +#ifndef OPENSSL_IS_BORINGSSL
- prime_fixed_value->release();
- bn_g.release();
-
- 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>(¶ms->params.prime)) {
- +#else
- + return EVPKeyCtxPointer();
- +#endif
- + } else if (std::get_if<int>(¶ms->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>(¶ms->params.prime);
- if (!param_ctx ||
- EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
- EVP_PKEY_CTX_set_dh_paramgen_prime_len(
- @@ -581,6 +584,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 c5dd2fb8fce40f2bf6f9a8543047ffb50cc08084..d850af9257cc194ee385130ce3cd2c0101b2455f 100644
- --- a/src/crypto/crypto_keys.cc
- +++ b/src/crypto/crypto_keys.cc
- @@ -1241,6 +1241,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
- }
-
- bool KeyObjectHandle::CheckEcKeyData() const {
- +#ifndef OPENSSL_IS_BORINGSSL
- MarkPopErrorOnReturn mark_pop_error_on_return;
-
- const ManagedEVPPKey& key = data_->GetAsymmetricKey();
- @@ -1259,6 +1260,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 f222ab9cf5ccbc5dd3399b18d7688efda6672c93..349abd4d06e7f624a071b994271dedc31dc9229a 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 5734d8fdc5505e1586f571c19b840bd56e9c9f1f..3034b114e081e2b32dd5b71653927a41af7d48df 100644
- --- a/src/crypto/crypto_util.cc
- +++ b/src/crypto/crypto_util.cc
- @@ -517,24 +517,15 @@ Maybe<bool> Decorate(Environment* env, Local<Object> obj,
- 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;
- @@ -715,7 +706,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.
- @@ -726,7 +717,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);
- @@ -734,10 +725,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 3b3724d6c7156b87555be31470e75b1cf28b5e3f..910c69b6d1d17ef25201dbb39d3d074f4f3f011f 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
-
- @@ -1036,7 +1036,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.cc b/src/node_metadata.cc
- index 844c5ac2c2b948b3be35cb3e447717a510a463a6..72a75ee0bf391ea508441f49413f85c5b735b259 100644
- --- a/src/node_metadata.cc
- +++ b/src/node_metadata.cc
- @@ -21,7 +21,7 @@
- #include <zlib.h>
- #endif // NODE_BUNDLED_ZLIB
-
- -#if HAVE_OPENSSL
- +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
- #include <openssl/opensslv.h>
- #if NODE_OPENSSL_HAS_QUIC
- #include <openssl/quic.h>
- 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 7110b4d984b72fa8c9bef2cbe6e37b1871e14d08..753311e15f161547be4277016efe11cc57d351db 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 3c67c3680b045786dafb8435f5b311c3f386a943..546c3979e2c8d7498aa92df4c89ee867c6485080 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
-
|