@@ -4721,7 +4721,16 @@ void Hash::Initialize(Environment* env, Local<Object> target) {
47214721void Hash::New (const FunctionCallbackInfo<Value>& args) {
47224722 Environment* env = Environment::GetCurrent (args);
47234723
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+ }
47254734
47264735 Maybe<unsigned int > xof_md_len = Nothing<unsigned int >();
47274736 if (!args[1 ]->IsUndefined ()) {
@@ -4730,17 +4739,19 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
47304739 }
47314740
47324741 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)) {
47344743 return ThrowCryptoError (env, ERR_get_error (),
47354744 " Digest method not supported" );
47364745 }
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+ }
47374751}
47384752
47394753
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) {
47444755 mdctx_.reset (EVP_MD_CTX_new ());
47454756 if (!mdctx_ || EVP_DigestInit_ex (mdctx_.get (), md, nullptr ) <= 0 ) {
47464757 mdctx_.reset ();
0 commit comments