chore: reduce crypto patch surface (#20646)

* reduce oaeplabel_option patch

* remove now-compatible patch

* note upstream
This commit is contained in:
Shelley Vohr 2019-10-21 08:02:23 -07:00 committed by GitHub
parent 7b28cd33cb
commit 0abbb35c4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 9 additions and 300 deletions

View file

@ -34,12 +34,10 @@ fix_extern_the_nativemoduleenv_and_options_parser_for_debug_builds.patch
chore_read_nobrowserglobals_from_global_not_process.patch
chore_split_createenvironment_into_createenvironment_and.patch
chore_handle_default_configuration_not_being_set_in_the_electron_env.patch
revert_crypto_add_outputlength_option_to_crypto_createhash.patch
fsevents-stop-using-fsevents-to-watch-files.patch
fsevents-regression-in-watching.patch
build_bring_back_node_with_ltcg_configuration.patch
revert_tls_add_option_to_override_signature_algorithms.patch
revert_crypto_fix_openssl_return_code_handling.patch
revert_crypto_add_oaeplabel_option.patch
fix_windows_compilation_on_libuv_setsockopt.patch
fix_don_t_use_node-controlled_preparestacktrace.patch

View file

@ -3,13 +3,15 @@ From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 15 Oct 2019 11:30:27 -0700
Subject: Revert "crypto: add oaepLabel option"
This partially reverts commit 54f327b4dcb37f373bc4146686c7e4edcd9c524d.
This partially reverts https://github.com/nodejs/node/pull/29489.
The BoringSSL incompatibilities (OPENSSL_memdup) will be shimmed in and this should
be removed when the associated update is rolled into Chromium.
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index be53ccc9759fcfb4cfa301e02fee6ff46b681033..2f73b3dc13a7f38b44f5f095da5dae3e24e7a629 100644
index 63dd6a1863..1ca4c75d64 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -5188,16 +5186,6 @@ bool PublicKeyCipher::Cipher(Environment* env,
@@ -5188,17 +5188,6 @@ bool PublicKeyCipher::Cipher(Environment* env,
return false;
}
@ -17,7 +19,8 @@ index be53ccc9759fcfb4cfa301e02fee6ff46b681033..2f73b3dc13a7f38b44f5f095da5dae3e
- // OpenSSL takes ownership of the label, so we need to create a copy.
- void* label = OPENSSL_memdup(oaep_label, oaep_label_len);
- CHECK_NOT_NULL(label);
- if (!EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label, oaep_label_len)) {
- if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label,
- oaep_label_len)) {
- OPENSSL_free(label);
- return false;
- }

View file

@ -1,264 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nitish Sakhawalkar <nitsakh@icloud.com>
Date: Mon, 12 Aug 2019 12:54:47 -0700
Subject: Revert "crypto: add outputLength option to crypto.createHash"
This reverts commit b7c6ad595b80442e433c6308dc5b80ed641866e0.
diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 8132e2975483b8fda95fe4466910dd42f74866cd..9b7aab3009770bb7816493581d82b63b7e19f2f3 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -1845,10 +1845,6 @@ and description of each available elliptic curve.
### crypto.createHash(algorithm[, options])
<!-- YAML
added: v0.1.92
-changes:
- - version: v12.8.0
- pr-url: https://github.com/nodejs/node/pull/28805
- description: The `outputLength` option was added for XOF hash functions.
-->
* `algorithm` {string}
@@ -1857,8 +1853,7 @@ changes:
Creates and returns a `Hash` object that can be used to generate hash digests
using the given `algorithm`. Optional `options` argument controls stream
-behavior. For XOF hash functions such as `'shake256'`, the `outputLength` option
-can be used to specify the desired output length in bytes.
+behavior.
The `algorithm` is dependent on the available algorithms supported by the
version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc.
diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js
index 3812ecfe68..7e81769eee 100644
--- a/lib/internal/crypto/hash.js
+++ b/lib/internal/crypto/hash.js
@@ -24,10 +24,7 @@ const {
ERR_CRYPTO_HASH_UPDATE_FAILED,
ERR_INVALID_ARG_TYPE
} = require('internal/errors').codes;
-const {
- validateString,
- validateUint32
-} = require('internal/validators');
+const { validateString } = require('internal/validators');
const { isArrayBufferView } = require('internal/util/types');
const LazyTransform = require('internal/streams/lazy_transform');
const kState = Symbol('kState');
@@ -37,11 +34,7 @@ function Hash(algorithm, options) {
if (!(this instanceof Hash))
return new Hash(algorithm, options);
validateString(algorithm, 'algorithm');
- const xofLen = typeof options === 'object' && options !== null ?
- options.outputLength : undefined;
- if (xofLen !== undefined)
- validateUint32(xofLen, 'options.outputLength');
- this[kHandle] = new _Hash(algorithm, xofLen);
+ this[kHandle] = new _Hash(algorithm);
this[kState] = {
[kFinalized]: false
};
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index cd09cdb3f2244825f6631891b94e61eeb6bc60bf..177de527c634671c571ebe4c2cfdeedc1c423ecc 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -4563,21 +4563,15 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
const node::Utf8Value hash_type(env->isolate(), args[0]);
- Maybe<unsigned int> xof_md_len = Nothing<unsigned int>();
- if (!args[1]->IsUndefined()) {
- CHECK(args[1]->IsUint32());
- xof_md_len = Just<unsigned int>(args[1].As<Uint32>()->Value());
- }
-
Hash* hash = new Hash(env, args.This());
- if (!hash->HashInit(*hash_type, xof_md_len)) {
+ if (!hash->HashInit(*hash_type)) {
return ThrowCryptoError(env, ERR_get_error(),
"Digest method not supported");
}
}
-bool Hash::HashInit(const char* hash_type, Maybe<unsigned int> xof_md_len) {
+bool Hash::HashInit(const char* hash_type) {
const EVP_MD* md = EVP_get_digestbyname(hash_type);
if (md == nullptr)
return false;
@@ -4738,17 +4738,6 @@ bool Hash::HashInit(const char* hash_type, Maybe<unsigned int> xof_md_len) {
return false;
}
- md_len_ = EVP_MD_size(md);
- if (xof_md_len.IsJust() && xof_md_len.FromJust() != md_len_) {
- // This is a little hack to cause createHash to fail when an incorrect
- // hashSize option was passed for a non-XOF hash function.
- if ((EVP_MD_flags(md) & EVP_MD_FLAG_XOF) == 0) {
- EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
- return false;
- }
- md_len_ = xof_md_len.FromJust();
- }
-
return true;
}
@@ -4646,40 +4628,13 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
}
- // TODO(tniessen): SHA3_squeeze does not work for zero-length outputs on all
- // platforms and will cause a segmentation fault if called. This workaround
- // causes hash.digest() to correctly return an empty buffer / string.
- // See https://github.com/openssl/openssl/issues/9431.
- if (!hash->has_md_ && hash->md_len_ == 0) {
- hash->has_md_ = true;
- }
-
- if (!hash->has_md_) {
+ if (hash->md_len_ == 0) {
// Some hash algorithms such as SHA3 do not support calling
// EVP_DigestFinal_ex more than once, however, Hash._flush
// and Hash.digest can both be used to retrieve the digest,
// so we need to cache it.
// See https://github.com/nodejs/node/issues/28245.
-
- hash->md_value_ = MallocOpenSSL<unsigned char>(hash->md_len_);
-
- size_t default_len = EVP_MD_CTX_size(hash->mdctx_.get());
- int ret;
- if (hash->md_len_ == default_len) {
- ret = EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_,
- &hash->md_len_);
- } else {
- ret = EVP_DigestFinalXOF(hash->mdctx_.get(), hash->md_value_,
- hash->md_len_);
- }
-
- if (ret != 1) {
- OPENSSL_free(hash->md_value_);
- hash->md_value_ = nullptr;
- return ThrowCryptoError(env, ERR_get_error());
- }
-
- hash->has_md_ = true;
+ EVP_DigestFinal_ex(hash->mdctx_.get(), hash->md_value_, &hash->md_len_);
}
Local<Value> error;
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 04a06affce1de8c567034d084c43b1a016076353..e526325a60feaa345f02e021f7ba1c9e3d8ca602 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -585,7 +585,7 @@ class Hash : public BaseObject {
SET_MEMORY_INFO_NAME(Hash)
SET_SELF_SIZE(Hash)
- bool HashInit(const char* hash_type, v8::Maybe<unsigned int> xof_md_len);
+ bool HashInit(const char* hash_type);
bool HashUpdate(const char* data, int len);
protected:
@@ -596,21 +596,18 @@ class Hash : public BaseObject {
Hash(Environment* env, v8::Local<v8::Object> wrap)
: BaseObject(env, wrap),
mdctx_(nullptr),
- has_md_(false),
- md_value_(nullptr) {
+ md_len_(0) {
MakeWeak();
}
~Hash() override {
- if (md_value_ != nullptr)
- OPENSSL_clear_free(md_value_, md_len_);
+ OPENSSL_cleanse(md_value_, md_len_);
}
private:
EVPMDPointer mdctx_;
- bool has_md_;
+ unsigned char md_value_[EVP_MAX_MD_SIZE];
unsigned int md_len_;
- unsigned char* md_value_;
};
class SignBase : public BaseObject {
diff --git a/test/parallel/test-crypto-hash.js b/test/parallel/test-crypto-hash.js
index 4d3214adb2db0b31e9172f3f20b056b5f1af3c7d..de15f00bc918aa4a80b02ae0c51957be264eb3c5 100644
--- a/test/parallel/test-crypto-hash.js
+++ b/test/parallel/test-crypto-hash.js
@@ -185,71 +185,3 @@ common.expectsError(
assert(instance instanceof Hash, 'Hash is expected to return a new instance' +
' when called without `new`');
}
-
-// Test XOF hash functions and the outputLength option.
-{
- // Default outputLengths.
- assert.strictEqual(crypto.createHash('shake128').digest('hex'),
- '7f9c2ba4e88f827d616045507605853e');
- assert.strictEqual(crypto.createHash('shake128', null).digest('hex'),
- '7f9c2ba4e88f827d616045507605853e');
- assert.strictEqual(crypto.createHash('shake256').digest('hex'),
- '46b9dd2b0ba88d13233b3feb743eeb24' +
- '3fcd52ea62b81b82b50c27646ed5762f');
-
- // Short outputLengths.
- assert.strictEqual(crypto.createHash('shake128', { outputLength: 0 })
- .digest('hex'),
- '');
- assert.strictEqual(crypto.createHash('shake128', { outputLength: 5 })
- .digest('hex'),
- '7f9c2ba4e8');
- assert.strictEqual(crypto.createHash('shake128', { outputLength: 15 })
- .digest('hex'),
- '7f9c2ba4e88f827d61604550760585');
- assert.strictEqual(crypto.createHash('shake256', { outputLength: 16 })
- .digest('hex'),
- '46b9dd2b0ba88d13233b3feb743eeb24');
-
- // Large outputLengths.
- assert.strictEqual(crypto.createHash('shake128', { outputLength: 128 })
- .digest('hex'),
- '7f9c2ba4e88f827d616045507605853e' +
- 'd73b8093f6efbc88eb1a6eacfa66ef26' +
- '3cb1eea988004b93103cfb0aeefd2a68' +
- '6e01fa4a58e8a3639ca8a1e3f9ae57e2' +
- '35b8cc873c23dc62b8d260169afa2f75' +
- 'ab916a58d974918835d25e6a435085b2' +
- 'badfd6dfaac359a5efbb7bcc4b59d538' +
- 'df9a04302e10c8bc1cbf1a0b3a5120ea');
- const superLongHash = crypto.createHash('shake256', {
- outputLength: 1024 * 1024
- }).update('The message is shorter than the hash!')
- .digest('hex');
- assert.strictEqual(superLongHash.length, 2 * 1024 * 1024);
- assert.ok(superLongHash.endsWith('193414035ddba77bf7bba97981e656ec'));
- assert.ok(superLongHash.startsWith('a2a28dbc49cfd6e5d6ceea3d03e77748'));
-
- // Non-XOF hash functions should accept valid outputLength options as well.
- assert.strictEqual(crypto.createHash('sha224', { outputLength: 28 })
- .digest('hex'),
- 'd14a028c2a3a2bc9476102bb288234c4' +
- '15a2b01f828ea62ac5b3e42f');
-
- // Passing invalid sizes should throw during creation.
- common.expectsError(() => {
- crypto.createHash('sha256', { outputLength: 28 });
- }, {
- code: 'ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH'
- });
-
- for (const outputLength of [null, {}, 'foo', false]) {
- common.expectsError(() => crypto.createHash('sha256', { outputLength }),
- { code: 'ERR_INVALID_ARG_TYPE' });
- }
-
- for (const outputLength of [-1, .5, Infinity, 2 ** 90]) {
- common.expectsError(() => crypto.createHash('sha256', { outputLength }),
- { code: 'ERR_OUT_OF_RANGE' });
- }
-}

View file

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Tue, 15 Oct 2019 11:23:56 -0700
Subject: Revert "crypto: fix OpenSSL return code handling"
This reverts commit dd5d944005166fbbfd4b72b9779f398598b3481d.
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 63dd6a186366baad660ee8e38401ba842c6ddb17..be53ccc9759fcfb4cfa301e02fee6ff46b681033 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -5184,7 +5184,7 @@ bool PublicKeyCipher::Cipher(Environment* env,
return false;
if (digest != nullptr) {
- if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest) <= 0)
+ if (!EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), digest))
return false;
}
@@ -5192,8 +5192,7 @@ bool PublicKeyCipher::Cipher(Environment* env,
// OpenSSL takes ownership of the label, so we need to create a copy.
void* label = OPENSSL_memdup(oaep_label, oaep_label_len);
CHECK_NOT_NULL(label);
- if (0 >= EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label,
- oaep_label_len)) {
+ if (!EVP_PKEY_CTX_set0_rsa_oaep_label(ctx.get(), label, oaep_label_len)) {
OPENSSL_free(label);
return false;
}

View file

@ -4,6 +4,8 @@ Date: Tue, 15 Oct 2019 11:21:13 -0700
Subject: Revert "tls: add option to override signature algorithms"
This partially reverts commit 6272f82c07e913a76a316a786c9aadbc09f953ff.
Upstreamed at https://boringssl-review.googlesource.com/c/boringssl/+/38404
and can be removed when that is merged and rolled into Chromium.
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 870456216983c2685c53580e60c44aa4dd3f7267..63dd6a186366baad660ee8e38401ba842c6ddb17 100644