fix_handle_boringssl_and_openssl_incompatibilities.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Shelley Vohr <[email protected]>
  3. Date: Wed, 12 Feb 2020 15:08:04 -0800
  4. Subject: fix: handle BoringSSL and OpenSSL incompatibilities
  5. This patch corrects for imcompatibilities between OpenSSL, which Node.js uses,
  6. and BoringSSL which Electron uses via Chromium. Each incompatibility typically has
  7. ~2 paths forward:
  8. * Upstream a shim or adapted implementation to BoringSSL
  9. * Alter Node.js functionality to something which both libraries can handle.
  10. Where possible, we should seek to make this patch as minimal as possible.
  11. Upstreams:
  12. - https://github.com/nodejs/node/pull/39054
  13. - https://github.com/nodejs/node/pull/39138
  14. - https://github.com/nodejs/node/pull/39136
  15. diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc
  16. index 4f0637f9511d1b90ae9d33760428dceb772667bd..5aba390c49613816ac359dfe995dc2c0a93f2206 100644
  17. --- a/src/crypto/crypto_cipher.cc
  18. +++ b/src/crypto/crypto_cipher.cc
  19. @@ -1088,7 +1088,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
  20. if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) {
  21. return ThrowCryptoError(env, ERR_get_error());
  22. }
  23. -
  24. +#ifndef OPENSSL_IS_BORINGSSL
  25. int rsa_pkcs1_implicit_rejection =
  26. EVP_PKEY_CTX_ctrl_str(ctx.get(), "rsa_pkcs1_implicit_rejection", "1");
  27. // From the doc -2 means that the option is not supported.
  28. @@ -1104,6 +1104,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo<Value>& args) {
  29. "RSA_PKCS1_PADDING is no longer supported for private decryption,"
  30. " this can be reverted with --security-revert=CVE-2023-46809");
  31. }
  32. +#endif
  33. }
  34. const EVP_MD* digest = nullptr;
  35. diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc
  36. index 85d48dfd2c15c453707bf6eb94e22f89b4f856b2..fe31a9a7f465a03d2de365cef392dfbb7c540156 100644
  37. --- a/src/crypto/crypto_common.cc
  38. +++ b/src/crypto/crypto_common.cc
  39. @@ -158,7 +158,7 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
  40. const unsigned char* buf;
  41. size_t len;
  42. size_t rem;
  43. -
  44. +#ifndef OPENSSL_IS_BORINGSSL
  45. if (!SSL_client_hello_get0_ext(
  46. ssl.get(),
  47. TLSEXT_TYPE_application_layer_protocol_negotiation,
  48. @@ -171,13 +171,15 @@ const char* GetClientHelloALPN(const SSLPointer& ssl) {
  49. len = (buf[0] << 8) | buf[1];
  50. if (len + 2 != rem) return nullptr;
  51. return reinterpret_cast<const char*>(buf + 3);
  52. +#endif
  53. + return nullptr;
  54. }
  55. const char* GetClientHelloServerName(const SSLPointer& ssl) {
  56. const unsigned char* buf;
  57. size_t len;
  58. size_t rem;
  59. -
  60. +#ifndef OPENSSL_IS_BORINGSSL
  61. if (!SSL_client_hello_get0_ext(
  62. ssl.get(),
  63. TLSEXT_TYPE_server_name,
  64. @@ -199,6 +201,8 @@ const char* GetClientHelloServerName(const SSLPointer& ssl) {
  65. if (len + 2 > rem)
  66. return nullptr;
  67. return reinterpret_cast<const char*>(buf + 5);
  68. +#endif
  69. + return nullptr;
  70. }
  71. const char* GetServerName(SSL* ssl) {
  72. @@ -1036,14 +1040,14 @@ MaybeLocal<Array> GetClientHelloCiphers(
  73. Environment* env,
  74. const SSLPointer& ssl) {
  75. EscapableHandleScope scope(env->isolate());
  76. - const unsigned char* buf;
  77. - size_t len = SSL_client_hello_get0_ciphers(ssl.get(), &buf);
  78. + // const unsigned char* buf = nullptr;
  79. + size_t len = 0; // SSL_client_hello_get0_ciphers(ssl.get(), &buf);
  80. size_t count = len / 2;
  81. MaybeStackBuffer<Local<Value>, 16> ciphers(count);
  82. int j = 0;
  83. for (size_t n = 0; n < len; n += 2) {
  84. - const SSL_CIPHER* cipher = SSL_CIPHER_find(ssl.get(), buf);
  85. - buf += 2;
  86. + const SSL_CIPHER* cipher = nullptr; // SSL_CIPHER_find(ssl.get(), buf);
  87. + // buf += 2;
  88. Local<Object> obj = Object::New(env->isolate());
  89. if (!Set(env->context(),
  90. obj,
  91. @@ -1096,8 +1100,11 @@ MaybeLocal<Object> GetEphemeralKey(Environment* env, const SSLPointer& ssl) {
  92. EscapableHandleScope scope(env->isolate());
  93. Local<Object> info = Object::New(env->isolate());
  94. +#ifndef OPENSSL_IS_BORINGSSL
  95. if (!SSL_get_peer_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
  96. -
  97. +#else
  98. + if (!SSL_get_server_tmp_key(ssl.get(), &raw_key)) return scope.Escape(info);
  99. +#endif
  100. Local<Context> context = env->context();
  101. crypto::EVPKeyPointer key(raw_key);
  102. diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
  103. index cef0c877c67643d47da787eddb95ed5a410a941b..1b8af49a48f1a34a92d4f0b502d435f3a4ab5d8e 100644
  104. --- a/src/crypto/crypto_context.cc
  105. +++ b/src/crypto/crypto_context.cc
  106. @@ -63,7 +63,7 @@ inline X509_STORE* GetOrCreateRootCertStore() {
  107. // Caller responsible for BIO_free_all-ing the returned object.
  108. BIOPointer LoadBIO(Environment* env, Local<Value> v) {
  109. if (v->IsString() || v->IsArrayBufferView()) {
  110. - BIOPointer bio(BIO_new(BIO_s_secmem()));
  111. + BIOPointer bio(BIO_new(BIO_s_mem()));
  112. if (!bio) return nullptr;
  113. ByteSource bsrc = ByteSource::FromStringOrBuffer(env, v);
  114. if (bsrc.size() > INT_MAX) return nullptr;
  115. @@ -882,10 +882,12 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
  116. // If the user specified "auto" for dhparams, the JavaScript layer will pass
  117. // true to this function instead of the original string. Any other string
  118. // value will be interpreted as custom DH parameters below.
  119. +#ifndef OPENSSL_IS_BORINGSSL
  120. if (args[0]->IsTrue()) {
  121. CHECK(SSL_CTX_set_dh_auto(sc->ctx_.get(), true));
  122. return;
  123. }
  124. +#endif
  125. DHPointer dh;
  126. {
  127. diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc
  128. index dac37f52b9687cadfa2d02152241e9a6e4c16ddf..d47cfa4ad8707ed7f0a42e7fe176fec25be64305 100644
  129. --- a/src/crypto/crypto_dh.cc
  130. +++ b/src/crypto/crypto_dh.cc
  131. @@ -154,13 +154,11 @@ bool DiffieHellman::Init(BignumPointer&& bn_p, int g) {
  132. bool DiffieHellman::Init(const char* p, int p_len, int g) {
  133. dh_.reset(DH_new());
  134. if (p_len <= 0) {
  135. - ERR_put_error(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX,
  136. - BN_R_BITS_TOO_SMALL, __FILE__, __LINE__);
  137. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
  138. return false;
  139. }
  140. if (g <= 1) {
  141. - ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
  142. - DH_R_BAD_GENERATOR, __FILE__, __LINE__);
  143. + OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
  144. return false;
  145. }
  146. BignumPointer bn_p(
  147. @@ -176,20 +174,17 @@ bool DiffieHellman::Init(const char* p, int p_len, int g) {
  148. bool DiffieHellman::Init(const char* p, int p_len, const char* g, int g_len) {
  149. dh_.reset(DH_new());
  150. if (p_len <= 0) {
  151. - ERR_put_error(ERR_LIB_BN, BN_F_BN_GENERATE_PRIME_EX,
  152. - BN_R_BITS_TOO_SMALL, __FILE__, __LINE__);
  153. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
  154. return false;
  155. }
  156. if (g_len <= 0) {
  157. - ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
  158. - DH_R_BAD_GENERATOR, __FILE__, __LINE__);
  159. + OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
  160. return false;
  161. }
  162. BignumPointer bn_g(
  163. BN_bin2bn(reinterpret_cast<const unsigned char*>(g), g_len, nullptr));
  164. if (BN_is_zero(bn_g.get()) || BN_is_one(bn_g.get())) {
  165. - ERR_put_error(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS,
  166. - DH_R_BAD_GENERATOR, __FILE__, __LINE__);
  167. + OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
  168. return false;
  169. }
  170. BignumPointer bn_p(
  171. @@ -219,8 +214,10 @@ typedef BignumPointer (*StandardizedGroupInstantiator)();
  172. inline StandardizedGroupInstantiator FindDiffieHellmanGroup(const char* name) {
  173. #define V(n, p) \
  174. if (StringEqualNoCase(name, n)) return InstantiateStandardizedGroup<p>
  175. +#ifndef OPENSSL_IS_BORINGSSL
  176. V("modp1", BN_get_rfc2409_prime_768);
  177. V("modp2", BN_get_rfc2409_prime_1024);
  178. +#endif
  179. V("modp5", BN_get_rfc3526_prime_1536);
  180. V("modp14", BN_get_rfc3526_prime_2048);
  181. V("modp15", BN_get_rfc3526_prime_3072);
  182. @@ -565,9 +562,11 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
  183. key_params = EVPKeyPointer(EVP_PKEY_new());
  184. CHECK(key_params);
  185. CHECK_EQ(EVP_PKEY_assign_DH(key_params.get(), dh.release()), 1);
  186. - } else if (int* prime_size = std::get_if<int>(&params->params.prime)) {
  187. + } else if (std::get_if<int>(&params->params.prime)) {
  188. EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DH, nullptr));
  189. EVP_PKEY* raw_params = nullptr;
  190. +#ifndef OPENSSL_IS_BORINGSSL
  191. + int* prime_size = std::get_if<int>(&params->params.prime);
  192. if (!param_ctx ||
  193. EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
  194. EVP_PKEY_CTX_set_dh_paramgen_prime_len(
  195. @@ -581,6 +580,9 @@ EVPKeyCtxPointer DhKeyGenTraits::Setup(DhKeyPairGenConfig* params) {
  196. }
  197. key_params = EVPKeyPointer(raw_params);
  198. +#else
  199. + return EVPKeyCtxPointer();
  200. +#endif
  201. } else {
  202. UNREACHABLE();
  203. }
  204. diff --git a/src/crypto/crypto_dsa.cc b/src/crypto/crypto_dsa.cc
  205. index 3fa4a415dc911a13afd90dfb31c1ed4ad0fd268f..fa48dffc31342c44a1c1207b9d4c3dc72ed93b60 100644
  206. --- a/src/crypto/crypto_dsa.cc
  207. +++ b/src/crypto/crypto_dsa.cc
  208. @@ -40,7 +40,7 @@ namespace crypto {
  209. EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
  210. EVPKeyCtxPointer param_ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, nullptr));
  211. EVP_PKEY* raw_params = nullptr;
  212. -
  213. +#ifndef OPENSSL_IS_BORINGSSL
  214. if (!param_ctx ||
  215. EVP_PKEY_paramgen_init(param_ctx.get()) <= 0 ||
  216. EVP_PKEY_CTX_set_dsa_paramgen_bits(
  217. @@ -55,7 +55,9 @@ EVPKeyCtxPointer DsaKeyGenTraits::Setup(DsaKeyPairGenConfig* params) {
  218. return EVPKeyCtxPointer();
  219. }
  220. }
  221. -
  222. +#else
  223. + return EVPKeyCtxPointer();
  224. +#endif
  225. if (EVP_PKEY_paramgen(param_ctx.get(), &raw_params) <= 0)
  226. return EVPKeyCtxPointer();
  227. diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc
  228. index 35474c31bfc2e3692b7ca10e4ed7026b9c275dfb..43c42c14f75018d4705f218fe4ed7e5dacb46bb8 100644
  229. --- a/src/crypto/crypto_keys.cc
  230. +++ b/src/crypto/crypto_keys.cc
  231. @@ -1239,6 +1239,7 @@ void KeyObjectHandle::GetAsymmetricKeyType(
  232. }
  233. bool KeyObjectHandle::CheckEcKeyData() const {
  234. +#ifndef OPENSSL_IS_BORINGSSL
  235. MarkPopErrorOnReturn mark_pop_error_on_return;
  236. const ManagedEVPPKey& key = data_->GetAsymmetricKey();
  237. @@ -1257,6 +1258,9 @@ bool KeyObjectHandle::CheckEcKeyData() const {
  238. #else
  239. return EVP_PKEY_public_check(ctx.get()) == 1;
  240. #endif
  241. +#else
  242. + return true;
  243. +#endif
  244. }
  245. void KeyObjectHandle::CheckEcKeyData(const FunctionCallbackInfo<Value>& args) {
  246. diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc
  247. index 48154df7dc91ed7c0d65323199bc2f59dfc68135..6431e5c3062890975854780d15ecb84370b81770 100644
  248. --- a/src/crypto/crypto_random.cc
  249. +++ b/src/crypto/crypto_random.cc
  250. @@ -140,7 +140,7 @@ Maybe<bool> RandomPrimeTraits::AdditionalConfig(
  251. params->bits = bits;
  252. params->safe = safe;
  253. - params->prime.reset(BN_secure_new());
  254. + params->prime.reset(BN_new());
  255. if (!params->prime) {
  256. THROW_ERR_CRYPTO_OPERATION_FAILED(env, "could not generate prime");
  257. return Nothing<bool>();
  258. diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc
  259. index 23b2b8c56dec8ac600b8f14b78d9e80b7fa3ed3b..e7a8fe4181542252d9142ea9460cacc5b4acd00d 100644
  260. --- a/src/crypto/crypto_rsa.cc
  261. +++ b/src/crypto/crypto_rsa.cc
  262. @@ -616,10 +616,11 @@ Maybe<bool> GetRsaKeyDetail(
  263. }
  264. if (params->saltLength != nullptr) {
  265. - if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
  266. - ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
  267. - return Nothing<bool>();
  268. - }
  269. + // TODO(codebytere): Upstream a shim to BoringSSL?
  270. + // if (ASN1_INTEGER_get_int64(&salt_length, params->saltLength) != 1) {
  271. + // ThrowCryptoError(env, ERR_get_error(), "ASN1_INTEGER_get_in64 error");
  272. + // return Nothing<bool>();
  273. + // }
  274. }
  275. if (target
  276. diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
  277. index 990638ec3993bde40ad3dd40d373d816ebc66a6a..63d971e1fe6b861e29c12f04563701b01fdfb976 100644
  278. --- a/src/crypto/crypto_util.cc
  279. +++ b/src/crypto/crypto_util.cc
  280. @@ -518,24 +518,15 @@ Maybe<void> Decorate(Environment* env,
  281. V(BIO) \
  282. V(PKCS7) \
  283. V(X509V3) \
  284. - V(PKCS12) \
  285. V(RAND) \
  286. - V(DSO) \
  287. V(ENGINE) \
  288. V(OCSP) \
  289. V(UI) \
  290. V(COMP) \
  291. V(ECDSA) \
  292. V(ECDH) \
  293. - V(OSSL_STORE) \
  294. - V(FIPS) \
  295. - V(CMS) \
  296. - V(TS) \
  297. V(HMAC) \
  298. - V(CT) \
  299. - V(ASYNC) \
  300. - V(KDF) \
  301. - V(SM2) \
  302. + V(HKDF) \
  303. V(USER) \
  304. #define V(name) case ERR_LIB_##name: lib = #name "_"; break;
  305. @@ -716,7 +707,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
  306. CHECK(args[0]->IsUint32());
  307. Environment* env = Environment::GetCurrent(args);
  308. uint32_t len = args[0].As<Uint32>()->Value();
  309. - void* data = OPENSSL_secure_zalloc(len);
  310. + void* data = OPENSSL_malloc(len);
  311. if (data == nullptr) {
  312. // There's no memory available for the allocation.
  313. // Return nothing.
  314. @@ -727,7 +718,7 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
  315. data,
  316. len,
  317. [](void* data, size_t len, void* deleter_data) {
  318. - OPENSSL_secure_clear_free(data, len);
  319. + OPENSSL_clear_free(data, len);
  320. },
  321. data);
  322. Local<ArrayBuffer> buffer = ArrayBuffer::New(env->isolate(), store);
  323. @@ -735,10 +726,12 @@ void SecureBuffer(const FunctionCallbackInfo<Value>& args) {
  324. }
  325. void SecureHeapUsed(const FunctionCallbackInfo<Value>& args) {
  326. +#ifndef OPENSSL_IS_BORINGSSL
  327. Environment* env = Environment::GetCurrent(args);
  328. if (CRYPTO_secure_malloc_initialized())
  329. args.GetReturnValue().Set(
  330. BigInt::New(env->isolate(), CRYPTO_secure_used()));
  331. +#endif
  332. }
  333. } // namespace
  334. diff --git a/src/env.h b/src/env.h
  335. index 30561ab7a24c734be71ed29d963c11e2ea2c2b22..7cb77fb4f35a60fbda5b868798321ac8b6340bfa 100644
  336. --- a/src/env.h
  337. +++ b/src/env.h
  338. @@ -49,7 +49,7 @@
  339. #include "uv.h"
  340. #include "v8.h"
  341. -#if HAVE_OPENSSL
  342. +#if HAVE_OPENSSL && OPENSSL_VERSION_MAJOR >= 3
  343. #include <openssl/evp.h>
  344. #endif
  345. @@ -1065,7 +1065,7 @@ class Environment : public MemoryRetainer {
  346. kExitInfoFieldCount
  347. };
  348. -#if HAVE_OPENSSL
  349. +#if HAVE_OPENSSL// && !defined(OPENSSL_IS_BORINGSSL)
  350. #if OPENSSL_VERSION_MAJOR >= 3
  351. // We declare another alias here to avoid having to include crypto_util.h
  352. using EVPMDPointer = DeleteFnPtr<EVP_MD, EVP_MD_free>;
  353. diff --git a/src/node_metadata.h b/src/node_metadata.h
  354. index cf051585e779e2b03bd7b95fe5008b89cc7f8162..9de49c6828468fdf846dcd4ad445390f14446099 100644
  355. --- a/src/node_metadata.h
  356. +++ b/src/node_metadata.h
  357. @@ -6,7 +6,7 @@
  358. #include <string>
  359. #include "node_version.h"
  360. -#if HAVE_OPENSSL
  361. +#if 0
  362. #include <openssl/crypto.h>
  363. #if NODE_OPENSSL_HAS_QUIC
  364. #include <openssl/quic.h>
  365. diff --git a/src/node_options.cc b/src/node_options.cc
  366. index dba59c5560c22899bd108789360f21fd85dd41bf..818baf611fcab7838a339f3ea137467653e270d0 100644
  367. --- a/src/node_options.cc
  368. +++ b/src/node_options.cc
  369. @@ -6,7 +6,7 @@
  370. #include "node_external_reference.h"
  371. #include "node_internals.h"
  372. #include "node_sea.h"
  373. -#if HAVE_OPENSSL
  374. +#if HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
  375. #include "openssl/opensslv.h"
  376. #endif
  377. diff --git a/src/node_options.h b/src/node_options.h
  378. index 10c220f66122336215f25b9674acfdfe6df82a8e..e8b2243d24fe95ff31254071133fb646e186c07e 100644
  379. --- a/src/node_options.h
  380. +++ b/src/node_options.h
  381. @@ -11,7 +11,7 @@
  382. #include "node_mutex.h"
  383. #include "util.h"
  384. -#if HAVE_OPENSSL
  385. +#if 0
  386. #include "openssl/opensslv.h"
  387. #endif