Skip to content

Commit 7678da4

Browse files
tniessenMylesBorins
authored andcommitted
crypto: handle exceptions in hmac/hash.digest
Forced conversion of the encoding parameter to a string within crypto.js, fixing segmentation faults in node_crypto.cc. Fixes: #9819 PR-URL: #12164 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent f1ea367 commit 7678da4

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-14
lines changed

‎lib/crypto.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ Hash.prototype.update = function(data, encoding){
7878

7979
Hash.prototype.digest=function(outputEncoding){
8080
outputEncoding=outputEncoding||exports.DEFAULT_ENCODING;
81-
returnthis._handle.digest(outputEncoding);
81+
// Explicit conversion for backward compatibility.
82+
returnthis._handle.digest(`${outputEncoding}`);
8283
};
8384

8485

‎src/node.cc‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,8 @@ enum encoding ParseEncoding(const char* encoding,
14831483
enum encoding ParseEncoding(Isolate* isolate,
14841484
Local<Value> encoding_v,
14851485
enum encoding default_encoding){
1486+
CHECK(!encoding_v.IsEmpty());
1487+
14861488
if (!encoding_v->IsString())
14871489
return default_encoding;
14881490

‎src/node_crypto.cc‎

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3783,9 +3783,8 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args){
37833783

37843784
enum encoding encoding = BUFFER;
37853785
if (args.Length() >= 1){
3786-
encoding = ParseEncoding(env->isolate(),
3787-
args[0]->ToString(env->isolate()),
3788-
BUFFER);
3786+
CHECK(args[0]->IsString());
3787+
encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
37893788
}
37903789

37913790
unsignedchar* md_value = nullptr;
@@ -3907,9 +3906,8 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args){
39073906

39083907
enum encoding encoding = BUFFER;
39093908
if (args.Length() >= 1){
3910-
encoding = ParseEncoding(env->isolate(),
3911-
args[0]->ToString(env->isolate()),
3912-
BUFFER);
3909+
CHECK(args[0]->IsString());
3910+
encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
39133911
}
39143912

39153913
unsignedchar md_value[EVP_MAX_MD_SIZE];
@@ -4132,10 +4130,8 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args){
41324130

41334131
unsignedint len = args.Length();
41344132
enum encoding encoding = BUFFER;
4135-
if (len >= 2 && args[1]->IsString()){
4136-
encoding = ParseEncoding(env->isolate(),
4137-
args[1]->ToString(env->isolate()),
4138-
BUFFER);
4133+
if (len >= 2){
4134+
encoding = ParseEncoding(env->isolate(), args[1], BUFFER);
41394135
}
41404136

41414137
node::Utf8Value passphrase(env->isolate(), args[2]);
@@ -4348,9 +4344,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args){
43484344

43494345
enum encoding encoding = UTF8;
43504346
if (args.Length() >= 3){
4351-
encoding = ParseEncoding(env->isolate(),
4352-
args[2]->ToString(env->isolate()),
4353-
UTF8);
4347+
encoding = ParseEncoding(env->isolate(), args[2], UTF8);
43544348
}
43554349

43564350
ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constassert=require('assert');
4+
constexecFile=require('child_process').execFile;
5+
6+
if(!common.hasCrypto){
7+
common.skip('missing crypto');
8+
return;
9+
}
10+
11+
constsetup='const enc ={toString: () =>{throw new Error("xyz")} };';
12+
13+
constscripts=[
14+
'crypto.createHash("sha256").digest(enc)',
15+
'crypto.createHmac("sha256", "msg").digest(enc)'
16+
];
17+
18+
scripts.forEach((script)=>{
19+
constnode=process.execPath;
20+
constcode=setup+''+script;
21+
execFile(node,['-e',code],common.mustCall((err,stdout,stderr)=>{
22+
assert(stderr.includes('Error: xyz'),'digest crashes');
23+
}));
24+
});

0 commit comments

Comments
(0)