diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2020-04-10 12:42:22 +0200 |
---|---|---|
committer | Michaƫl Zasso <targos@protonmail.com> | 2020-05-04 14:23:21 +0200 |
commit | 637442fec9210bf985cf8dae8b8806b6d08e13ef (patch) | |
tree | bf9af79286dd948a8b682a91b8818f35fb6e6ecf | |
parent | db293c47dd48b4193d87172754e522a8c08a553d (diff) | |
download | node-new-637442fec9210bf985cf8dae8b8806b6d08e13ef.tar.gz |
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: https://github.com/nodejs/node/issues/32738
PR-URL: https://github.com/nodejs/node/pull/32739
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Zeyu Yang <himself65@outlook.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r-- | lib/internal/crypto/diffiehellman.js | 12 | ||||
-rw-r--r-- | test/parallel/test-crypto-dh.js | 18 |
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index ae6b68b73b..70e4100d50 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -14,7 +14,10 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_OPT_VALUE } = require('internal/errors').codes; -const { validateString } = require('internal/validators'); +const { + validateString, + validateInt32, +} = require('internal/validators'); const { isArrayBufferView } = require('internal/util/types'); const { KeyObject } = require('internal/crypto/keys'); const { @@ -51,6 +54,13 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { ); } + // Sizes < 0 don't make sense but they _are_ accepted (and subsequently + // rejected with ERR_OSSL_BN_BITS_TOO_SMALL) by OpenSSL. The glue code + // in node_crypto.cc accepts values that are IsInt32() for that reason + // and that's why we do that here too. + if (typeof sizeOrKey === 'number') + validateInt32(sizeOrKey, 'sizeOrKey'); + if (keyEncoding && !Buffer.isEncoding(keyEncoding) && keyEncoding !== 'buffer') { genEncoding = generator; diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index baa7402a88..f5eddb8c88 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -20,6 +20,24 @@ assert.strictEqual(secret2.toString('base64'), secret1); assert.strictEqual(dh1.verifyError, 0); assert.strictEqual(dh2.verifyError, 0); +// https://github.com/nodejs/node/issues/32738 +// XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError +// instead of ERR_INVALID_ARG_TYPE and TypeError is questionable, IMO. +assert.throws(() => crypto.createDiffieHellman(13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "sizeOrKey" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +for (const bits of [-1, 0, 1]) { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_BN_BITS_TOO_SMALL', + name: 'Error', + message: /bits too small/, + }); +} + { const DiffieHellman = crypto.DiffieHellman; const dh = DiffieHellman(p1, 'buffer'); |