From 989fd73f1e1561c76563692c44dd1aadecea8fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 29 Aug 2018 14:45:29 +0200 Subject: [PATCH] crypto: fix incorrect use of INT_MAX in validation The native crypto module doesn't export INT_MAX, so all occurrences in the JavaScript layer evaluated to undefined. This change removes all such occurrences and replaces validateInt32 with validateUint32 since the native layer assumes uint32_t anyway. The alternative would be to use the constant from the constants module, but that would be pointless as far as I can tell. PR-URL: https://github.com/nodejs/node/pull/22581 Reviewed-By: Anna Henningsen Reviewed-By: Ruben Bridgewater --- lib/internal/crypto/pbkdf2.js | 8 ++++---- lib/internal/crypto/scrypt.js | 20 ++++++++++---------- test/parallel/test-crypto-pbkdf2.js | 8 +++----- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index b6b61d35857628..9cbfb3dc64211d 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -2,8 +2,8 @@ const { AsyncWrap, Providers } = process.binding('async_wrap'); const { Buffer } = require('buffer'); -const { INT_MAX, pbkdf2: _pbkdf2 } = process.binding('crypto'); -const { validateInt32 } = require('internal/validators'); +const { pbkdf2: _pbkdf2 } = process.binding('crypto'); +const { validateUint32 } = require('internal/validators'); const { ERR_CRYPTO_INVALID_DIGEST, ERR_CRYPTO_PBKDF2_ERROR, @@ -59,8 +59,8 @@ function check(password, salt, iterations, keylen, digest, callback) { password = validateArrayBufferView(password, 'password'); salt = validateArrayBufferView(salt, 'salt'); - iterations = validateInt32(iterations, 'iterations', 0, INT_MAX); - keylen = validateInt32(keylen, 'keylen', 0, INT_MAX); + iterations = validateUint32(iterations, 'iterations', 0); + keylen = validateUint32(keylen, 'keylen', 0); return { password, salt, iterations, keylen, digest }; } diff --git a/lib/internal/crypto/scrypt.js b/lib/internal/crypto/scrypt.js index edfe522be47a74..68ae4f6f7d5385 100644 --- a/lib/internal/crypto/scrypt.js +++ b/lib/internal/crypto/scrypt.js @@ -2,8 +2,8 @@ const { AsyncWrap, Providers } = process.binding('async_wrap'); const { Buffer } = require('buffer'); -const { INT_MAX, scrypt: _scrypt } = process.binding('crypto'); -const { validateInt32 } = require('internal/validators'); +const { scrypt: _scrypt } = process.binding('crypto'); +const { validateUint32 } = require('internal/validators'); const { ERR_CRYPTO_SCRYPT_INVALID_PARAMETER, ERR_CRYPTO_SCRYPT_NOT_SUPPORTED, @@ -76,31 +76,31 @@ function check(password, salt, keylen, options, callback) { password = validateArrayBufferView(password, 'password'); salt = validateArrayBufferView(salt, 'salt'); - keylen = validateInt32(keylen, 'keylen', 0, INT_MAX); + keylen = validateUint32(keylen, 'keylen'); let { N, r, p, maxmem } = defaults; if (options && options !== defaults) { let has_N, has_r, has_p; if (has_N = (options.N !== undefined)) - N = validateInt32(options.N, 'N', 0, INT_MAX); + N = validateUint32(options.N, 'N'); if (options.cost !== undefined) { if (has_N) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - N = validateInt32(options.cost, 'cost', 0, INT_MAX); + N = validateUint32(options.cost, 'cost'); } if (has_r = (options.r !== undefined)) - r = validateInt32(options.r, 'r', 0, INT_MAX); + r = validateUint32(options.r, 'r'); if (options.blockSize !== undefined) { if (has_r) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - r = validateInt32(options.blockSize, 'blockSize', 0, INT_MAX); + r = validateUint32(options.blockSize, 'blockSize'); } if (has_p = (options.p !== undefined)) - p = validateInt32(options.p, 'p', 0, INT_MAX); + p = validateUint32(options.p, 'p'); if (options.parallelization !== undefined) { if (has_p) throw new ERR_CRYPTO_SCRYPT_INVALID_PARAMETER(); - p = validateInt32(options.parallelization, 'parallelization', 0, INT_MAX); + p = validateUint32(options.parallelization, 'parallelization'); } if (options.maxmem !== undefined) - maxmem = validateInt32(options.maxmem, 'maxmem', 0, INT_MAX); + maxmem = validateUint32(options.maxmem, 'maxmem'); if (N === 0) N = defaults.N; if (r === 0) r = defaults.r; if (p === 0) p = defaults.p; diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js index e1fa1e3d86f5fb..0f5d4618ea156c 100644 --- a/test/parallel/test-crypto-pbkdf2.js +++ b/test/parallel/test-crypto-pbkdf2.js @@ -6,8 +6,6 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { INT_MAX } = process.binding('constants').crypto; - // // Test PBKDF2 with RFC 6070 test vectors (except #4) // @@ -71,7 +69,7 @@ assert.throws( code: 'ERR_OUT_OF_RANGE', name: 'RangeError [ERR_OUT_OF_RANGE]', message: 'The value of "iterations" is out of range. ' + - 'It must be >= 0 && <= 2147483647. Received -1' + 'It must be >= 0 && < 4294967296. Received -1' } ); @@ -100,7 +98,7 @@ assert.throws( }); }); -[-1, 4073741824, INT_MAX + 1].forEach((input) => { +[-1, 4294967297].forEach((input) => { assert.throws( () => { crypto.pbkdf2('password', 'salt', 1, input, 'sha256', @@ -109,7 +107,7 @@ assert.throws( code: 'ERR_OUT_OF_RANGE', name: 'RangeError [ERR_OUT_OF_RANGE]', message: 'The value of "keylen" is out of range. It ' + - `must be >= 0 && <= 2147483647. Received ${input}` + `must be >= 0 && < 4294967296. Received ${input}` }); });