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