From 174f8c8d9126af7b1bed8e4c44cada529dcb68a0 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 10 Jul 2017 12:56:37 +0200 Subject: [PATCH] src: avoid heap allocation in sign.final() Put the 8 kB initial buffer on the stack first and don't copy it to the heap until its exact size is known (which is normally much smaller.) PR-URL: https://github.com/nodejs/node/pull/14122 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- src/node_crypto.cc | 27 +++++++++------------------ src/node_crypto.h | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 9ba146c82b4416..47df568c2d3d16 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4147,7 +4147,7 @@ static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md, SignBase::Error Sign::SignFinal(const char* key_pem, int key_pem_len, const char* passphrase, - unsigned char** sig, + unsigned char* sig, unsigned int* sig_len, int padding, int salt_len) { @@ -4196,7 +4196,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem, } #endif // NODE_FIPS_MODE - if (Node_SignFinal(&mdctx_, *sig, sig_len, pkey, padding, salt_len)) + if (Node_SignFinal(&mdctx_, sig, sig_len, pkey, padding, salt_len)) fatal = false; initialised_ = false; @@ -4222,9 +4222,6 @@ void Sign::SignFinal(const FunctionCallbackInfo& args) { Sign* sign; ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); - unsigned char* md_value; - unsigned int md_len; - unsigned int len = args.Length(); node::Utf8Value passphrase(env->isolate(), args[1]); @@ -4243,30 +4240,24 @@ void Sign::SignFinal(const FunctionCallbackInfo& args) { CHECK(maybe_salt_len.IsJust()); int salt_len = maybe_salt_len.ToChecked(); - md_len = 8192; // Maximum key size is 8192 bits - md_value = new unsigned char[md_len]; - ClearErrorOnReturn clear_error_on_return; + unsigned char md_value[8192]; + unsigned int md_len = sizeof(md_value); Error err = sign->SignFinal( buf, buf_len, len >= 2 && !args[1]->IsNull() ? *passphrase : nullptr, - &md_value, + md_value, &md_len, padding, salt_len); - if (err != kSignOk) { - delete[] md_value; - md_value = nullptr; - md_len = 0; + if (err != kSignOk) return sign->CheckThrow(err); - } - Local rc = Buffer::Copy(env->isolate(), - reinterpret_cast(md_value), - md_len).ToLocalChecked(); - delete[] md_value; + Local rc = + Buffer::Copy(env, reinterpret_cast(md_value), md_len) + .ToLocalChecked(); args.GetReturnValue().Set(rc); } diff --git a/src/node_crypto.h b/src/node_crypto.h index 33c9cf783ecedb..c1ba349d2d645d 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -587,7 +587,7 @@ class Sign : public SignBase { Error SignFinal(const char* key_pem, int key_pem_len, const char* passphrase, - unsigned char** sig, + unsigned char* sig, unsigned int *sig_len, int padding, int saltlen);