summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2020-04-10 12:42:22 +0200
committerMichaƫl Zasso <targos@protonmail.com>2020-05-04 14:23:21 +0200
commit637442fec9210bf985cf8dae8b8806b6d08e13ef (patch)
treebf9af79286dd948a8b682a91b8818f35fb6e6ecf
parentdb293c47dd48b4193d87172754e522a8c08a553d (diff)
downloadnode-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.js12
-rw-r--r--test/parallel/test-crypto-dh.js18
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');