Skip to content

Commit 4b073b0

Browse files
Linkgorontargos
authored andcommitted
crypto: fix generateKeyPair type checks
Change saltLength, divisorLength, primeLength and generator checks in generateKeyPair to int32 from uint32, to align with c++ code. fixes: #38358 PR-URL: #38364 Fixes: #38358 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent f455e08 commit 4b073b0

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

lib/internal/crypto/keygen.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const {
4040
const { customPromisifyArgs } = require('internal/util');
4141

4242
const {
43+
isInt32,
4344
isUint32,
4445
validateCallback,
4546
validateString,
@@ -194,7 +195,7 @@ function createJob(mode, type, options) {
194195
throw new ERR_INVALID_ARG_VALUE('options.hash', hash);
195196
if (mgf1Hash !== undefined && typeof mgf1Hash !== 'string')
196197
throw new ERR_INVALID_ARG_VALUE('options.mgf1Hash', mgf1Hash);
197-
if (saltLength !== undefined && !isUint32(saltLength))
198+
if (saltLength !== undefined && (!isInt32(saltLength) || saltLength < 0))
198199
throw new ERR_INVALID_ARG_VALUE('options.saltLength', saltLength);
199200

200201
return new RsaKeyPairGenJob(
@@ -217,7 +218,7 @@ function createJob(mode, type, options) {
217218
let { divisorLength } = options;
218219
if (divisorLength == null) {
219220
divisorLength = -1;
220-
} else if (!isUint32(divisorLength)) {
221+
} else if (!isInt32(divisorLength) || divisorLength < 0) {
221222
throw new ERR_INVALID_ARG_VALUE('options.divisorLength', divisorLength);
222223
}
223224

@@ -292,15 +293,15 @@ function createJob(mode, type, options) {
292293
if (!isArrayBufferView(prime))
293294
throw new ERR_INVALID_ARG_VALUE('options.prime', prime);
294295
} else if (primeLength != null) {
295-
if (!isUint32(primeLength))
296+
if (!isInt32(primeLength) || primeLength < 0)
296297
throw new ERR_INVALID_ARG_VALUE('options.primeLength', primeLength);
297298
} else {
298299
throw new ERR_MISSING_OPTION(
299300
'At least one of the group, prime, or primeLength options');
300301
}
301302

302303
if (generator != null) {
303-
if (!isUint32(generator))
304+
if (!isInt32(generator) || generator < 0)
304305
throw new ERR_INVALID_ARG_VALUE('options.generator', generator);
305306
}
306307
return new DhKeyPairGenJob(

test/parallel/test-crypto-keygen.js

+76-1
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
958958
}
959959

960960
// Test invalid divisor lengths.
961-
for (const divisorLength of ['a', true, {}, [], 4096.1]) {
961+
for (const divisorLength of ['a', true, {}, [], 4096.1, 2147483648, -1]) {
962962
assert.throws(() => generateKeyPair('dsa', {
963963
modulusLength: 2048,
964964
divisorLength
@@ -1081,6 +1081,52 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
10811081
message: 'Unknown DH group'
10821082
});
10831083

1084+
assert.throws(() => {
1085+
generateKeyPair('dh', {
1086+
primeLength: 2147483648
1087+
}, common.mustNotCall());
1088+
}, {
1089+
name: 'TypeError',
1090+
code: 'ERR_INVALID_ARG_VALUE',
1091+
message: "The property 'options.primeLength' is invalid. " +
1092+
'Received 2147483648',
1093+
});
1094+
1095+
assert.throws(() => {
1096+
generateKeyPair('dh', {
1097+
primeLength: -1
1098+
}, common.mustNotCall());
1099+
}, {
1100+
name: 'TypeError',
1101+
code: 'ERR_INVALID_ARG_VALUE',
1102+
message: "The property 'options.primeLength' is invalid. " +
1103+
'Received -1',
1104+
});
1105+
1106+
assert.throws(() => {
1107+
generateKeyPair('dh', {
1108+
primeLength: 2,
1109+
generator: 2147483648,
1110+
}, common.mustNotCall());
1111+
}, {
1112+
name: 'TypeError',
1113+
code: 'ERR_INVALID_ARG_VALUE',
1114+
message: "The property 'options.generator' is invalid. " +
1115+
'Received 2147483648',
1116+
});
1117+
1118+
assert.throws(() => {
1119+
generateKeyPair('dh', {
1120+
primeLength: 2,
1121+
generator: -1,
1122+
}, common.mustNotCall());
1123+
}, {
1124+
name: 'TypeError',
1125+
code: 'ERR_INVALID_ARG_VALUE',
1126+
message: "The property 'options.generator' is invalid. " +
1127+
'Received -1',
1128+
});
1129+
10841130
// Test incompatible options.
10851131
const allOpts = {
10861132
group: 'modp5',
@@ -1142,6 +1188,35 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
11421188
});
11431189
}
11441190

1191+
// too long salt length
1192+
assert.throws(() => {
1193+
generateKeyPair('rsa-pss', {
1194+
modulusLength: 512,
1195+
saltLength: 2147483648,
1196+
hash: 'sha256',
1197+
mgf1Hash: 'sha256'
1198+
}, common.mustNotCall());
1199+
}, {
1200+
name: 'TypeError',
1201+
code: 'ERR_INVALID_ARG_VALUE',
1202+
message: "The property 'options.saltLength' is invalid. " +
1203+
'Received 2147483648'
1204+
});
1205+
1206+
assert.throws(() => {
1207+
generateKeyPair('rsa-pss', {
1208+
modulusLength: 512,
1209+
saltLength: -1,
1210+
hash: 'sha256',
1211+
mgf1Hash: 'sha256'
1212+
}, common.mustNotCall());
1213+
}, {
1214+
name: 'TypeError',
1215+
code: 'ERR_INVALID_ARG_VALUE',
1216+
message: "The property 'options.saltLength' is invalid. " +
1217+
'Received -1'
1218+
});
1219+
11451220
// Invalid private key type.
11461221
for (const type of ['foo', 'spki']) {
11471222
assert.throws(() => {

0 commit comments

Comments
 (0)