From 18c2c498653baf860af587f48209890ea59313a3 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 29 Aug 2021 10:09:48 +0200 Subject: [PATCH] crypto: add rsa-pss keygen parameters --- doc/api/crypto.md | 16 ++++++++++++ doc/api/deprecations.md | 13 ++++++++++ lib/internal/crypto/keygen.js | 40 ++++++++++++++++++++++++----- test/parallel/test-crypto-keygen.js | 30 +++++++++++----------- 4 files changed, 77 insertions(+), 22 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index c1836cf634cf0a..7c67cbe6d856c9 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3375,6 +3375,10 @@ generateKey('hmac', { length: 64 }, (err, key) => { + +Type: Runtime + +The `'hash'` and `'mgf1Hash'` options are replaced with `'hashAlgorithm'` +and `'mgf1HashAlgorithm'`. + [Legacy URL API]: url.md#legacy-url-api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js index 49a7f044cb66cd..7db6233cc47b06 100644 --- a/lib/internal/crypto/keygen.js +++ b/lib/internal/crypto/keygen.js @@ -193,21 +193,47 @@ function createJob(mode, type, options) { ...encoding); } - const { hash, mgf1Hash, saltLength } = options; - if (hash !== undefined && typeof hash !== 'string') - throw new ERR_INVALID_ARG_VALUE('options.hash', hash); - if (mgf1Hash !== undefined && typeof mgf1Hash !== 'string') - throw new ERR_INVALID_ARG_VALUE('options.mgf1Hash', mgf1Hash); + const { + hash, mgf1Hash, hashAlgorithm, mgf1HashAlgorithm, saltLength + } = options; if (saltLength !== undefined && (!isInt32(saltLength) || saltLength < 0)) throw new ERR_INVALID_ARG_VALUE('options.saltLength', saltLength); + if (hashAlgorithm !== undefined && typeof hashAlgorithm !== 'string') + throw new ERR_INVALID_ARG_VALUE('options.hashAlgorithm', hashAlgorithm); + if (mgf1HashAlgorithm !== undefined && + typeof mgf1HashAlgorithm !== 'string') + throw new ERR_INVALID_ARG_VALUE('options.mgf1HashAlgorithm', + mgf1HashAlgorithm); + if (hash !== undefined) { + process.emitWarning( + '"options.hash" is deprecated, ' + + 'use "options.hashAlgorithm" instead.', + 'DeprecationWarning', + 'DEP0XXX'); + if (typeof hash !== 'string' || + (hashAlgorithm && hash !== hashAlgorithm)) { + throw new ERR_INVALID_ARG_VALUE('options.hash', hash); + } + } + if (mgf1Hash !== undefined) { + process.emitWarning( + '"options.mgf1Hash" is deprecated, ' + + 'use "options.mgf1HashAlgorithm" instead.', + 'DeprecationWarning', + 'DEP0XXX'); + if (typeof mgf1Hash !== 'string' || + (mgf1HashAlgorithm && mgf1Hash !== mgf1HashAlgorithm)) { + throw new ERR_INVALID_ARG_VALUE('options.mgf1Hash', mgf1Hash); + } + } return new RsaKeyPairGenJob( mode, kKeyVariantRSA_PSS, modulusLength, publicExponent, - hash, - mgf1Hash, + hashAlgorithm || hash, + mgf1HashAlgorithm || mgf1Hash, saltLength, ...encoding); } diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index fc778614cc68ed..b932d1b5f7d5e8 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -302,8 +302,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); generateKeyPair('rsa-pss', { modulusLength: 512, saltLength: 16, - hash: 'sha256', - mgf1Hash: 'sha256' + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256' }, common.mustSucceed((publicKey, privateKey) => { assert.strictEqual(publicKey.type, 'public'); assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); @@ -1301,12 +1301,12 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); assert.throws(() => { generateKeyPairSync('rsa-pss', { modulusLength: 4096, - hash: hashValue + hashAlgorithm: hashValue }); }, { name: 'TypeError', code: 'ERR_INVALID_ARG_VALUE', - message: "The property 'options.hash' is invalid. " + + message: "The property 'options.hashAlgorithm' is invalid. " + `Received ${inspect(hashValue)}` }); } @@ -1316,8 +1316,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); generateKeyPair('rsa-pss', { modulusLength: 512, saltLength: 2147483648, - hash: 'sha256', - mgf1Hash: 'sha256' + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256' }, common.mustNotCall()); }, { name: 'TypeError', @@ -1330,8 +1330,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); generateKeyPair('rsa-pss', { modulusLength: 512, saltLength: -1, - hash: 'sha256', - mgf1Hash: 'sha256' + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256' }, common.mustNotCall()); }, { name: 'TypeError', @@ -1428,8 +1428,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); generateKeyPair('rsa-pss', { modulusLength: 512, saltLength: 16, - hash: 'sha256', - mgf1Hash: undefined + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: undefined }); }, { @@ -1439,21 +1439,21 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); } ); - for (const mgf1Hash of [null, 0, false, {}, []]) { + for (const mgf1HashAlgorithm of [null, 0, false, {}, []]) { assert.throws( () => { generateKeyPair('rsa-pss', { modulusLength: 512, saltLength: 16, - hash: 'sha256', - mgf1Hash + hashAlgorithm: 'sha256', + mgf1HashAlgorithm }, common.mustNotCall()); }, { name: 'TypeError', code: 'ERR_INVALID_ARG_VALUE', - message: "The property 'options.mgf1Hash' is invalid. " + - `Received ${inspect(mgf1Hash)}` + message: "The property 'options.mgf1HashAlgorithm' is invalid. " + + `Received ${inspect(mgf1HashAlgorithm)}` } );