Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fb226ff

Browse filesBrowse files
panvarichardlau
authored andcommitted
crypto: add rsa-pss keygen parameters
PR-URL: #39927 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 22a78a7 commit fb226ff
Copy full SHA for fb226ff

File tree

Expand file treeCollapse file tree

5 files changed

+184
-22
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+184
-22
lines changed
Open diff view settings
Collapse file

‎doc/api/crypto.md‎

Copy file name to clipboardExpand all lines: doc/api/crypto.md
+16Lines changed: 16 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -3375,6 +3375,10 @@ generateKey('hmac', { length: 64 }, (err, key) => {
33753375
<!-- YAML
33763376
added: v10.12.0
33773377
changes:
3378+
- version: REPLACEME
3379+
pr-url: https://github.com/nodejs/node/pull/39927
3380+
description: Add ability to define `RSASSA-PSS-params` sequence parameters
3381+
for RSA-PSS keys pairs.
33783382
- version:
33793383
- v13.9.0
33803384
- v12.17.0
@@ -3400,6 +3404,10 @@ changes:
34003404
* `options`: {Object}
34013405
* `modulusLength`: {number} Key size in bits (RSA, DSA).
34023406
* `publicExponent`: {number} Public exponent (RSA). **Default:** `0x10001`.
3407+
* `hashAlgorithm`: {string} Name of the message digest (RSA-PSS).
3408+
* `mgf1HashAlgorithm`: {string} Name of the message digest used by
3409+
MGF1 (RSA-PSS).
3410+
* `saltLength`: {number} Minimal salt length in bytes (RSA-PSS).
34033411
* `divisorLength`: {number} Size of `q` in bits (DSA).
34043412
* `namedCurve`: {string} Name of the curve to use (EC).
34053413
* `prime`: {Buffer} The prime parameter (DH).
@@ -3478,6 +3486,10 @@ a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
34783486
<!-- YAML
34793487
added: v10.12.0
34803488
changes:
3489+
- version: REPLACEME
3490+
pr-url: https://github.com/nodejs/node/pull/39927
3491+
description: Add ability to define `RSASSA-PSS-params` sequence parameters
3492+
for RSA-PSS keys pairs.
34813493
- version:
34823494
- v13.9.0
34833495
- v12.17.0
@@ -3503,6 +3515,10 @@ changes:
35033515
* `options`: {Object}
35043516
* `modulusLength`: {number} Key size in bits (RSA, DSA).
35053517
* `publicExponent`: {number} Public exponent (RSA). **Default:** `0x10001`.
3518+
* `hashAlgorithm`: {string} Name of the message digest (RSA-PSS).
3519+
* `mgf1HashAlgorithm`: {string} Name of the message digest used by
3520+
MGF1 (RSA-PSS).
3521+
* `saltLength`: {number} Minimal salt length in bytes (RSA-PSS).
35063522
* `divisorLength`: {number} Size of `q` in bits (DSA).
35073523
* `namedCurve`: {string} Name of the curve to use (EC).
35083524
* `prime`: {Buffer} The prime parameter (DH).
Collapse file

‎doc/api/deprecations.md‎

Copy file name to clipboardExpand all lines: doc/api/deprecations.md
+13Lines changed: 13 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -2799,6 +2799,19 @@ non-number value for `hints` option, a non-nullish non-boolean value for `all`
27992799
option, or a non-nullish non-boolean value for `verbatim` option in
28002800
[`dns.lookup()`][] and [`dnsPromises.lookup()`][] is deprecated.
28012801

2802+
### DEP0154: RSA-PSS generate key pair options
2803+
<!-- YAML
2804+
changes:
2805+
- version: REPLACEME
2806+
pr-url: https://github.com/nodejs/node/pull/39927
2807+
description: Documentation-only deprecation.
2808+
-->
2809+
2810+
Type: Documentation-only (supports [`--pending-deprecation`][])
2811+
2812+
The `'hash'` and `'mgf1Hash'` options are replaced with `'hashAlgorithm'`
2813+
and `'mgf1HashAlgorithm'`.
2814+
28022815
[Legacy URL API]: url.md#url_legacy_url_api
28032816
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
28042817
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3
Collapse file

‎lib/internal/crypto/keygen.js‎

Copy file name to clipboardExpand all lines: lib/internal/crypto/keygen.js
+36-7Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ const {
6060

6161
const { isArrayBufferView } = require('internal/util/types');
6262

63+
const { getOptionValue } = require('internal/options');
64+
const pendingDeprecation = getOptionValue('--pending-deprecation');
65+
6366
function wrapKey(key, ctor) {
6467
if (typeof key === 'string' ||
6568
isArrayBufferView(key) ||
@@ -193,21 +196,47 @@ function createJob(mode, type, options) {
193196
...encoding);
194197
}
195198

196-
const { hash, mgf1Hash, saltLength } = options;
197-
if (hash !== undefined && typeof hash !== 'string')
198-
throw new ERR_INVALID_ARG_VALUE('options.hash', hash);
199-
if (mgf1Hash !== undefined && typeof mgf1Hash !== 'string')
200-
throw new ERR_INVALID_ARG_VALUE('options.mgf1Hash', mgf1Hash);
199+
const {
200+
hash, mgf1Hash, hashAlgorithm, mgf1HashAlgorithm, saltLength
201+
} = options;
201202
if (saltLength !== undefined && (!isInt32(saltLength) || saltLength < 0))
202203
throw new ERR_INVALID_ARG_VALUE('options.saltLength', saltLength);
204+
if (hashAlgorithm !== undefined && typeof hashAlgorithm !== 'string')
205+
throw new ERR_INVALID_ARG_VALUE('options.hashAlgorithm', hashAlgorithm);
206+
if (mgf1HashAlgorithm !== undefined &&
207+
typeof mgf1HashAlgorithm !== 'string')
208+
throw new ERR_INVALID_ARG_VALUE('options.mgf1HashAlgorithm',
209+
mgf1HashAlgorithm);
210+
if (hash !== undefined) {
211+
pendingDeprecation && process.emitWarning(
212+
'"options.hash" is deprecated, ' +
213+
'use "options.hashAlgorithm" instead.',
214+
'DeprecationWarning',
215+
'DEP0154');
216+
if (typeof hash !== 'string' ||
217+
(hashAlgorithm && hash !== hashAlgorithm)) {
218+
throw new ERR_INVALID_ARG_VALUE('options.hash', hash);
219+
}
220+
}
221+
if (mgf1Hash !== undefined) {
222+
pendingDeprecation && process.emitWarning(
223+
'"options.mgf1Hash" is deprecated, ' +
224+
'use "options.mgf1HashAlgorithm" instead.',
225+
'DeprecationWarning',
226+
'DEP0154');
227+
if (typeof mgf1Hash !== 'string' ||
228+
(mgf1HashAlgorithm && mgf1Hash !== mgf1HashAlgorithm)) {
229+
throw new ERR_INVALID_ARG_VALUE('options.mgf1Hash', mgf1Hash);
230+
}
231+
}
203232

204233
return new RsaKeyPairGenJob(
205234
mode,
206235
kKeyVariantRSA_PSS,
207236
modulusLength,
208237
publicExponent,
209-
hash,
210-
mgf1Hash,
238+
hashAlgorithm || hash,
239+
mgf1HashAlgorithm || mgf1Hash,
211240
saltLength,
212241
...encoding);
213242
}
Collapse file
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Flags: --pending-deprecation
2+
3+
'use strict';
4+
5+
const common = require('../common');
6+
if (!common.hasCrypto)
7+
common.skip('missing crypto');
8+
9+
const DeprecationWarning = [];
10+
DeprecationWarning.push([
11+
'"options.hash" is deprecated, use "options.hashAlgorithm" instead.',
12+
'DEP0154']);
13+
DeprecationWarning.push([
14+
'"options.mgf1Hash" is deprecated, use "options.mgf1HashAlgorithm" instead.',
15+
'DEP0154']);
16+
17+
common.expectWarning({ DeprecationWarning });
18+
19+
const assert = require('assert');
20+
const { generateKeyPair } = require('crypto');
21+
22+
{
23+
// This test makes sure deprecated options still work as intended
24+
25+
generateKeyPair('rsa-pss', {
26+
modulusLength: 512,
27+
saltLength: 16,
28+
hash: 'sha256',
29+
mgf1Hash: 'sha256'
30+
}, common.mustSucceed((publicKey, privateKey) => {
31+
assert.strictEqual(publicKey.type, 'public');
32+
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
33+
assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
34+
modulusLength: 512,
35+
publicExponent: 65537n,
36+
hashAlgorithm: 'sha256',
37+
mgf1HashAlgorithm: 'sha256',
38+
saltLength: 16
39+
});
40+
41+
assert.strictEqual(privateKey.type, 'private');
42+
assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
43+
assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
44+
modulusLength: 512,
45+
publicExponent: 65537n,
46+
hashAlgorithm: 'sha256',
47+
mgf1HashAlgorithm: 'sha256',
48+
saltLength: 16
49+
});
50+
}));
51+
}
Collapse file

‎test/parallel/test-crypto-keygen.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-crypto-keygen.js
+68-15Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
302302
generateKeyPair('rsa-pss', {
303303
modulusLength: 512,
304304
saltLength: 16,
305-
hash: 'sha256',
306-
mgf1Hash: 'sha256'
305+
hashAlgorithm: 'sha256',
306+
mgf1HashAlgorithm: 'sha256'
307307
}, common.mustSucceed((publicKey, privateKey) => {
308308
assert.strictEqual(publicKey.type, 'public');
309309
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
@@ -1324,12 +1324,12 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
13241324
assert.throws(() => {
13251325
generateKeyPairSync('rsa-pss', {
13261326
modulusLength: 4096,
1327-
hash: hashValue
1327+
hashAlgorithm: hashValue
13281328
});
13291329
}, {
13301330
name: 'TypeError',
13311331
code: 'ERR_INVALID_ARG_VALUE',
1332-
message: "The property 'options.hash' is invalid. " +
1332+
message: "The property 'options.hashAlgorithm' is invalid. " +
13331333
`Received ${inspect(hashValue)}`
13341334
});
13351335
}
@@ -1339,8 +1339,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
13391339
generateKeyPair('rsa-pss', {
13401340
modulusLength: 512,
13411341
saltLength: 2147483648,
1342-
hash: 'sha256',
1343-
mgf1Hash: 'sha256'
1342+
hashAlgorithm: 'sha256',
1343+
mgf1HashAlgorithm: 'sha256'
13441344
}, common.mustNotCall());
13451345
}, {
13461346
name: 'TypeError',
@@ -1353,8 +1353,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
13531353
generateKeyPair('rsa-pss', {
13541354
modulusLength: 512,
13551355
saltLength: -1,
1356-
hash: 'sha256',
1357-
mgf1Hash: 'sha256'
1356+
hashAlgorithm: 'sha256',
1357+
mgf1HashAlgorithm: 'sha256'
13581358
}, common.mustNotCall());
13591359
}, {
13601360
name: 'TypeError',
@@ -1451,8 +1451,8 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
14511451
generateKeyPair('rsa-pss', {
14521452
modulusLength: 512,
14531453
saltLength: 16,
1454-
hash: 'sha256',
1455-
mgf1Hash: undefined
1454+
hashAlgorithm: 'sha256',
1455+
mgf1HashAlgorithm: undefined
14561456
});
14571457
},
14581458
{
@@ -1462,21 +1462,21 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
14621462
}
14631463
);
14641464

1465-
for (const mgf1Hash of [null, 0, false, {}, []]) {
1465+
for (const mgf1HashAlgorithm of [null, 0, false, {}, []]) {
14661466
assert.throws(
14671467
() => {
14681468
generateKeyPair('rsa-pss', {
14691469
modulusLength: 512,
14701470
saltLength: 16,
1471-
hash: 'sha256',
1472-
mgf1Hash
1471+
hashAlgorithm: 'sha256',
1472+
mgf1HashAlgorithm
14731473
}, common.mustNotCall());
14741474
},
14751475
{
14761476
name: 'TypeError',
14771477
code: 'ERR_INVALID_ARG_VALUE',
1478-
message: "The property 'options.mgf1Hash' is invalid. " +
1479-
`Received ${inspect(mgf1Hash)}`
1478+
message: "The property 'options.mgf1HashAlgorithm' is invalid. " +
1479+
`Received ${inspect(mgf1HashAlgorithm)}`
14801480

14811481
}
14821482
);
@@ -1568,3 +1568,56 @@ if (!common.hasOpenSSL3) {
15681568
}
15691569
}
15701570
}
1571+
1572+
{
1573+
// This test makes sure deprecated and new options may be used
1574+
// simultaneously so long as they're identical values.
1575+
1576+
generateKeyPair('rsa-pss', {
1577+
modulusLength: 512,
1578+
saltLength: 16,
1579+
hash: 'sha256',
1580+
hashAlgorithm: 'sha256',
1581+
mgf1Hash: 'sha256',
1582+
mgf1HashAlgorithm: 'sha256'
1583+
}, common.mustSucceed((publicKey, privateKey) => {
1584+
assert.strictEqual(publicKey.type, 'public');
1585+
assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
1586+
assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
1587+
modulusLength: 512,
1588+
publicExponent: 65537n,
1589+
hashAlgorithm: 'sha256',
1590+
mgf1HashAlgorithm: 'sha256',
1591+
saltLength: 16
1592+
});
1593+
1594+
assert.strictEqual(privateKey.type, 'private');
1595+
assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
1596+
assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
1597+
modulusLength: 512,
1598+
publicExponent: 65537n,
1599+
hashAlgorithm: 'sha256',
1600+
mgf1HashAlgorithm: 'sha256',
1601+
saltLength: 16
1602+
});
1603+
}));
1604+
}
1605+
1606+
{
1607+
// This test makes sure deprecated and new options must
1608+
// be the same value.
1609+
1610+
assert.throws(() => generateKeyPair('rsa-pss', {
1611+
modulusLength: 512,
1612+
saltLength: 16,
1613+
mgf1Hash: 'sha256',
1614+
mgf1HashAlgorithm: 'sha1'
1615+
}, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE' });
1616+
1617+
assert.throws(() => generateKeyPair('rsa-pss', {
1618+
modulusLength: 512,
1619+
saltLength: 16,
1620+
hash: 'sha256',
1621+
hashAlgorithm: 'sha1'
1622+
}, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE' });
1623+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.