Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2019-10-10 01:33:15 +0300
committerMyles Borins <myles.borins@gmail.com>2019-10-23 16:56:19 +0300
commit1d03df4c5e72c353ca36a44c0fb305ac62fee003 (patch)
tree0323bc3f5b21c9ef3c938c7b2eb1e83d3b85f6b7 /src/node_crypto.cc
parenta1c524d734c653309d5451e2841285bd22ac49ba (diff)
crypto: add Hash.prototype.copy() method
Make it possible to clone the internal state of a Hash object into a new Hash object, i.e., to fork the state of the object. Fixes: https://github.com/nodejs/node/issues/29903 PR-URL: https://github.com/nodejs/node/pull/29910 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_crypto.cc')
-rw-r--r--src/node_crypto.cc23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index d2563c0fb53..adefb7f482a 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -4720,7 +4720,16 @@ void Hash::Initialize(Environment* env, Local<Object> target) {
void Hash::New(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
- const node::Utf8Value hash_type(env->isolate(), args[0]);
+ const Hash* orig = nullptr;
+ const EVP_MD* md = nullptr;
+
+ if (args[0]->IsObject()) {
+ ASSIGN_OR_RETURN_UNWRAP(&orig, args[0].As<Object>());
+ md = EVP_MD_CTX_md(orig->mdctx_.get());
+ } else {
+ const node::Utf8Value hash_type(env->isolate(), args[0]);
+ md = EVP_get_digestbyname(*hash_type);
+ }
Maybe<unsigned int> xof_md_len = Nothing<unsigned int>();
if (!args[1]->IsUndefined()) {
@@ -4729,17 +4738,19 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
}
Hash* hash = new Hash(env, args.This());
- if (!hash->HashInit(*hash_type, xof_md_len)) {
+ if (md == nullptr || !hash->HashInit(md, xof_md_len)) {
return ThrowCryptoError(env, ERR_get_error(),
"Digest method not supported");
}
+
+ if (orig != nullptr &&
+ 0 >= EVP_MD_CTX_copy(hash->mdctx_.get(), orig->mdctx_.get())) {
+ return ThrowCryptoError(env, ERR_get_error(), "Digest copy error");
+ }
}
-bool Hash::HashInit(const char* hash_type, Maybe<unsigned int> xof_md_len) {
- const EVP_MD* md = EVP_get_digestbyname(hash_type);
- if (md == nullptr)
- return false;
+bool Hash::HashInit(const EVP_MD* md, Maybe<unsigned int> xof_md_len) {
mdctx_.reset(EVP_MD_CTX_new());
if (!mdctx_ || EVP_DigestInit_ex(mdctx_.get(), md, nullptr) <= 0) {
mdctx_.reset();