@@ -4718,7 +4718,16 @@ void Hash::Initialize(Environment* env, Local<Object> target) {
4718
4718
void Hash::New (const FunctionCallbackInfo<Value>& args) {
4719
4719
Environment* env = Environment::GetCurrent (args);
4720
4720
4721
- const node::Utf8Value hash_type (env->isolate (), args[0 ]);
4721
+ const Hash* orig = nullptr ;
4722
+ const EVP_MD* md = nullptr ;
4723
+
4724
+ if (args[0 ]->IsObject ()) {
4725
+ ASSIGN_OR_RETURN_UNWRAP (&orig, args[0 ].As <Object>());
4726
+ md = EVP_MD_CTX_md (orig->mdctx_ .get ());
4727
+ } else {
4728
+ const node::Utf8Value hash_type (env->isolate (), args[0 ]);
4729
+ md = EVP_get_digestbyname (*hash_type);
4730
+ }
4722
4731
4723
4732
Maybe<unsigned int > xof_md_len = Nothing<unsigned int >();
4724
4733
if (!args[1 ]->IsUndefined ()) {
@@ -4727,17 +4736,19 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
4727
4736
}
4728
4737
4729
4738
Hash* hash = new Hash (env, args.This ());
4730
- if (!hash->HashInit (*hash_type , xof_md_len)) {
4739
+ if (md == nullptr || !hash->HashInit (md , xof_md_len)) {
4731
4740
return ThrowCryptoError (env, ERR_get_error (),
4732
4741
" Digest method not supported" );
4733
4742
}
4743
+
4744
+ if (orig != nullptr &&
4745
+ 0 >= EVP_MD_CTX_copy (hash->mdctx_ .get (), orig->mdctx_ .get ())) {
4746
+ return ThrowCryptoError (env, ERR_get_error (), " Digest copy error" );
4747
+ }
4734
4748
}
4735
4749
4736
4750
4737
- bool Hash::HashInit (const char * hash_type, Maybe<unsigned int > xof_md_len) {
4738
- const EVP_MD* md = EVP_get_digestbyname (hash_type);
4739
- if (md == nullptr )
4740
- return false ;
4751
+ bool Hash::HashInit (const EVP_MD* md, Maybe<unsigned int > xof_md_len) {
4741
4752
mdctx_.reset (EVP_MD_CTX_new ());
4742
4753
if (!mdctx_ || EVP_DigestInit_ex (mdctx_.get (), md, nullptr ) <= 0 ) {
4743
4754
mdctx_.reset ();
0 commit comments