Skip to content

Commit 4236175

Browse files
bnoordhuistargos
authored andcommitted
crypto: key size must be int32 in DiffieHellman()
The JS code accepted any value where `typeof sizeOrKey === 'number'` was true but the C++ code checked that `args[0]->IsInt32()` and subsequently aborted. Fixes: #32738 PR-URL: #32739 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Zeyu Yang <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent e05c29d commit 4236175

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

lib/internal/crypto/diffiehellman.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ const {
1414
ERR_INVALID_ARG_TYPE,
1515
ERR_INVALID_OPT_VALUE
1616
} = require('internal/errors').codes;
17-
const { validateString } = require('internal/validators');
17+
const {
18+
validateString,
19+
validateInt32,
20+
} = require('internal/validators');
1821
const { isArrayBufferView } = require('internal/util/types');
1922
const { KeyObject } = require('internal/crypto/keys');
2023
const {
@@ -51,6 +54,13 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
5154
);
5255
}
5356

57+
// Sizes < 0 don't make sense but they _are_ accepted (and subsequently
58+
// rejected with ERR_OSSL_BN_BITS_TOO_SMALL) by OpenSSL. The glue code
59+
// in node_crypto.cc accepts values that are IsInt32() for that reason
60+
// and that's why we do that here too.
61+
if (typeof sizeOrKey === 'number')
62+
validateInt32(sizeOrKey, 'sizeOrKey');
63+
5464
if (keyEncoding && !Buffer.isEncoding(keyEncoding) &&
5565
keyEncoding !== 'buffer') {
5666
genEncoding = generator;

test/parallel/test-crypto-dh.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ assert.strictEqual(secret2.toString('base64'), secret1);
2020
assert.strictEqual(dh1.verifyError, 0);
2121
assert.strictEqual(dh2.verifyError, 0);
2222

23+
// https://github.com/nodejs/node/issues/32738
24+
// XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError
25+
// instead of ERR_INVALID_ARG_TYPE and TypeError is questionable, IMO.
26+
assert.throws(() => crypto.createDiffieHellman(13.37), {
27+
code: 'ERR_OUT_OF_RANGE',
28+
name: 'RangeError',
29+
message: 'The value of "sizeOrKey" is out of range. ' +
30+
'It must be an integer. Received 13.37',
31+
});
32+
33+
for (const bits of [-1, 0, 1]) {
34+
assert.throws(() => crypto.createDiffieHellman(bits), {
35+
code: 'ERR_OSSL_BN_BITS_TOO_SMALL',
36+
name: 'Error',
37+
message: /bits too small/,
38+
});
39+
}
40+
2341
{
2442
const DiffieHellman = crypto.DiffieHellman;
2543
const dh = DiffieHellman(p1, 'buffer');

0 commit comments

Comments
 (0)