Skip to content

Commit 174f8c8

Browse files
bnoordhuisaddaleax
authored andcommitted
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: #14122 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent efb7aef commit 174f8c8

File tree

2 files changed

+10
-19
lines changed

2 files changed

+10
-19
lines changed

src/node_crypto.cc

+9-18
Original file line numberDiff line numberDiff line change
@@ -4147,7 +4147,7 @@ static int Node_SignFinal(EVP_MD_CTX* mdctx, unsigned char* md,
41474147
SignBase::Error Sign::SignFinal(const char* key_pem,
41484148
int key_pem_len,
41494149
const char* passphrase,
4150-
unsigned char** sig,
4150+
unsigned char* sig,
41514151
unsigned int* sig_len,
41524152
int padding,
41534153
int salt_len) {
@@ -4196,7 +4196,7 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
41964196
}
41974197
#endif // NODE_FIPS_MODE
41984198

4199-
if (Node_SignFinal(&mdctx_, *sig, sig_len, pkey, padding, salt_len))
4199+
if (Node_SignFinal(&mdctx_, sig, sig_len, pkey, padding, salt_len))
42004200
fatal = false;
42014201

42024202
initialised_ = false;
@@ -4222,9 +4222,6 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
42224222
Sign* sign;
42234223
ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
42244224

4225-
unsigned char* md_value;
4226-
unsigned int md_len;
4227-
42284225
unsigned int len = args.Length();
42294226

42304227
node::Utf8Value passphrase(env->isolate(), args[1]);
@@ -4243,30 +4240,24 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
42434240
CHECK(maybe_salt_len.IsJust());
42444241
int salt_len = maybe_salt_len.ToChecked();
42454242

4246-
md_len = 8192; // Maximum key size is 8192 bits
4247-
md_value = new unsigned char[md_len];
4248-
42494243
ClearErrorOnReturn clear_error_on_return;
4244+
unsigned char md_value[8192];
4245+
unsigned int md_len = sizeof(md_value);
42504246

42514247
Error err = sign->SignFinal(
42524248
buf,
42534249
buf_len,
42544250
len >= 2 && !args[1]->IsNull() ? *passphrase : nullptr,
4255-
&md_value,
4251+
md_value,
42564252
&md_len,
42574253
padding,
42584254
salt_len);
4259-
if (err != kSignOk) {
4260-
delete[] md_value;
4261-
md_value = nullptr;
4262-
md_len = 0;
4255+
if (err != kSignOk)
42634256
return sign->CheckThrow(err);
4264-
}
42654257

4266-
Local<Object> rc = Buffer::Copy(env->isolate(),
4267-
reinterpret_cast<const char*>(md_value),
4268-
md_len).ToLocalChecked();
4269-
delete[] md_value;
4258+
Local<Object> rc =
4259+
Buffer::Copy(env, reinterpret_cast<char*>(md_value), md_len)
4260+
.ToLocalChecked();
42704261
args.GetReturnValue().Set(rc);
42714262
}
42724263

src/node_crypto.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ class Sign : public SignBase {
587587
Error SignFinal(const char* key_pem,
588588
int key_pem_len,
589589
const char* passphrase,
590-
unsigned char** sig,
590+
unsigned char* sig,
591591
unsigned int *sig_len,
592592
int padding,
593593
int saltlen);

0 commit comments

Comments
 (0)