1'use strict';
2
3// This tests early errors for invalid encodings.
4
5const common = require('../common');
6if (!common.hasCrypto)
7  common.skip('missing crypto');
8
9const assert = require('assert');
10
11const {
12  generateKeyPair,
13  generateKeyPairSync,
14} = require('crypto');
15const { inspect } = require('util');
16
17
18// Test invalid parameter encoding.
19{
20  assert.throws(() => generateKeyPairSync('ec', {
21    namedCurve: 'P-256',
22    paramEncoding: 'otherEncoding',
23    publicKeyEncoding: {
24      type: 'spki',
25      format: 'pem'
26    },
27    privateKeyEncoding: {
28      type: 'pkcs8',
29      format: 'pem',
30      cipher: 'aes-128-cbc',
31      passphrase: 'top secret'
32    }
33  }), {
34    name: 'TypeError',
35    code: 'ERR_INVALID_ARG_VALUE',
36    message: "The property 'options.paramEncoding' is invalid. " +
37      "Received 'otherEncoding'"
38  });
39}
40
41{
42  // Test invalid key types.
43  for (const type of [undefined, null, 0]) {
44    assert.throws(() => generateKeyPairSync(type, {}), {
45      name: 'TypeError',
46      code: 'ERR_INVALID_ARG_TYPE',
47      message: 'The "type" argument must be of type string.' +
48               common.invalidArgTypeHelper(type)
49    });
50  }
51
52  assert.throws(() => generateKeyPairSync('rsa2', {}), {
53    name: 'TypeError',
54    code: 'ERR_INVALID_ARG_VALUE',
55    message: "The argument 'type' must be a supported key type. Received 'rsa2'"
56  });
57}
58
59{
60  // Test keygen without options object.
61  assert.throws(() => generateKeyPair('rsa', common.mustNotCall()), {
62    name: 'TypeError',
63    code: 'ERR_INVALID_ARG_TYPE',
64    message: 'The "options" argument must be of type object. ' +
65      'Received undefined'
66  });
67
68  // Even if no options are required, it should be impossible to pass anything
69  // but an object (or undefined).
70  assert.throws(() => generateKeyPair('ed448', 0, common.mustNotCall()), {
71    name: 'TypeError',
72    code: 'ERR_INVALID_ARG_TYPE',
73    message: 'The "options" argument must be of type object. ' +
74      'Received type number (0)'
75  });
76}
77
78{
79  // Invalid publicKeyEncoding.
80  for (const enc of [0, 'a', true]) {
81    assert.throws(() => generateKeyPairSync('rsa', {
82      modulusLength: 4096,
83      publicKeyEncoding: enc,
84      privateKeyEncoding: {
85        type: 'pkcs1',
86        format: 'pem'
87      }
88    }), {
89      name: 'TypeError',
90      code: 'ERR_INVALID_ARG_VALUE',
91      message: "The property 'options.publicKeyEncoding' is invalid. " +
92        `Received ${inspect(enc)}`
93    });
94  }
95
96  // Missing publicKeyEncoding.type.
97  for (const type of [undefined, null, 0, true, {}]) {
98    assert.throws(() => generateKeyPairSync('rsa', {
99      modulusLength: 4096,
100      publicKeyEncoding: {
101        type,
102        format: 'pem'
103      },
104      privateKeyEncoding: {
105        type: 'pkcs1',
106        format: 'pem'
107      }
108    }), {
109      name: 'TypeError',
110      code: 'ERR_INVALID_ARG_VALUE',
111      message: "The property 'options.publicKeyEncoding.type' is invalid. " +
112        `Received ${inspect(type)}`
113    });
114  }
115
116  // Missing / invalid publicKeyEncoding.format.
117  for (const format of [undefined, null, 0, false, 'a', {}]) {
118    assert.throws(() => generateKeyPairSync('rsa', {
119      modulusLength: 4096,
120      publicKeyEncoding: {
121        type: 'pkcs1',
122        format
123      },
124      privateKeyEncoding: {
125        type: 'pkcs1',
126        format: 'pem'
127      }
128    }), {
129      name: 'TypeError',
130      code: 'ERR_INVALID_ARG_VALUE',
131      message: "The property 'options.publicKeyEncoding.format' is invalid. " +
132        `Received ${inspect(format)}`
133    });
134  }
135
136  // Invalid privateKeyEncoding.
137  for (const enc of [0, 'a', true]) {
138    assert.throws(() => generateKeyPairSync('rsa', {
139      modulusLength: 4096,
140      publicKeyEncoding: {
141        type: 'pkcs1',
142        format: 'pem'
143      },
144      privateKeyEncoding: enc
145    }), {
146      name: 'TypeError',
147      code: 'ERR_INVALID_ARG_VALUE',
148      message: "The property 'options.privateKeyEncoding' is invalid. " +
149        `Received ${inspect(enc)}`
150    });
151  }
152
153  // Missing / invalid privateKeyEncoding.type.
154  for (const type of [undefined, null, 0, true, {}]) {
155    assert.throws(() => generateKeyPairSync('rsa', {
156      modulusLength: 4096,
157      publicKeyEncoding: {
158        type: 'pkcs1',
159        format: 'pem'
160      },
161      privateKeyEncoding: {
162        type,
163        format: 'pem'
164      }
165    }), {
166      name: 'TypeError',
167      code: 'ERR_INVALID_ARG_VALUE',
168      message: "The property 'options.privateKeyEncoding.type' is invalid. " +
169        `Received ${inspect(type)}`
170    });
171  }
172
173  // Missing / invalid privateKeyEncoding.format.
174  for (const format of [undefined, null, 0, false, 'a', {}]) {
175    assert.throws(() => generateKeyPairSync('rsa', {
176      modulusLength: 4096,
177      publicKeyEncoding: {
178        type: 'pkcs1',
179        format: 'pem'
180      },
181      privateKeyEncoding: {
182        type: 'pkcs1',
183        format
184      }
185    }), {
186      name: 'TypeError',
187      code: 'ERR_INVALID_ARG_VALUE',
188      message: "The property 'options.privateKeyEncoding.format' is invalid. " +
189        `Received ${inspect(format)}`
190    });
191  }
192
193  // Cipher of invalid type.
194  for (const cipher of [0, true, {}]) {
195    assert.throws(() => generateKeyPairSync('rsa', {
196      modulusLength: 4096,
197      publicKeyEncoding: {
198        type: 'pkcs1',
199        format: 'pem'
200      },
201      privateKeyEncoding: {
202        type: 'pkcs1',
203        format: 'pem',
204        cipher
205      }
206    }), {
207      name: 'TypeError',
208      code: 'ERR_INVALID_ARG_VALUE',
209      message: "The property 'options.privateKeyEncoding.cipher' is invalid. " +
210        `Received ${inspect(cipher)}`
211    });
212  }
213
214  // Invalid cipher.
215  assert.throws(() => generateKeyPairSync('rsa', {
216    modulusLength: 4096,
217    publicKeyEncoding: {
218      type: 'pkcs1',
219      format: 'pem'
220    },
221    privateKeyEncoding: {
222      type: 'pkcs8',
223      format: 'pem',
224      cipher: 'foo',
225      passphrase: 'secret'
226    }
227  }), {
228    name: 'Error',
229    code: 'ERR_CRYPTO_UNKNOWN_CIPHER',
230    message: 'Unknown cipher'
231  });
232
233  // Cipher, but no valid passphrase.
234  for (const passphrase of [undefined, null, 5, false, true]) {
235    assert.throws(() => generateKeyPairSync('rsa', {
236      modulusLength: 4096,
237      publicKeyEncoding: {
238        type: 'pkcs1',
239        format: 'pem'
240      },
241      privateKeyEncoding: {
242        type: 'pkcs8',
243        format: 'pem',
244        cipher: 'aes-128-cbc',
245        passphrase
246      }
247    }), {
248      name: 'TypeError',
249      code: 'ERR_INVALID_ARG_VALUE',
250      message: "The property 'options.privateKeyEncoding.passphrase' " +
251        `is invalid. Received ${inspect(passphrase)}`
252    });
253  }
254
255  // Test invalid callbacks.
256  for (const cb of [undefined, null, 0, {}]) {
257    assert.throws(() => generateKeyPair('rsa', {
258      modulusLength: 512,
259      publicKeyEncoding: { type: 'pkcs1', format: 'pem' },
260      privateKeyEncoding: { type: 'pkcs1', format: 'pem' }
261    }, cb), {
262      name: 'TypeError',
263      code: 'ERR_INVALID_ARG_TYPE'
264    });
265  }
266}
267
268// Test RSA parameters.
269{
270  // Test invalid modulus lengths. (non-number)
271  for (const modulusLength of [undefined, null, 'a', true, {}, []]) {
272    assert.throws(() => generateKeyPair('rsa', {
273      modulusLength
274    }, common.mustNotCall()), {
275      name: 'TypeError',
276      code: 'ERR_INVALID_ARG_TYPE',
277      message:
278        'The "options.modulusLength" property must be of type number.' +
279        common.invalidArgTypeHelper(modulusLength)
280    });
281  }
282
283  // Test invalid modulus lengths. (non-integer)
284  for (const modulusLength of [512.1, 1.3, 1.1, 5000.9, 100.5]) {
285    assert.throws(() => generateKeyPair('rsa', {
286      modulusLength
287    }, common.mustNotCall()), {
288      name: 'RangeError',
289      code: 'ERR_OUT_OF_RANGE',
290      message:
291        'The value of "options.modulusLength" is out of range. ' +
292        'It must be an integer. ' +
293        `Received ${inspect(modulusLength)}`
294    });
295  }
296
297  // Test invalid modulus lengths. (out of range)
298  for (const modulusLength of [-1, -9, 4294967297]) {
299    assert.throws(() => generateKeyPair('rsa', {
300      modulusLength
301    }, common.mustNotCall()), {
302      name: 'RangeError',
303      code: 'ERR_OUT_OF_RANGE',
304    });
305  }
306
307  // Test invalid exponents. (non-number)
308  for (const publicExponent of ['a', true, {}, []]) {
309    assert.throws(() => generateKeyPair('rsa', {
310      modulusLength: 4096,
311      publicExponent
312    }, common.mustNotCall()), {
313      name: 'TypeError',
314      code: 'ERR_INVALID_ARG_TYPE',
315      message:
316        'The "options.publicExponent" property must be of type number.' +
317        common.invalidArgTypeHelper(publicExponent)
318    });
319  }
320
321  // Test invalid exponents. (non-integer)
322  for (const publicExponent of [3.5, 1.1, 50.5, 510.5]) {
323    assert.throws(() => generateKeyPair('rsa', {
324      modulusLength: 4096,
325      publicExponent
326    }, common.mustNotCall()), {
327      name: 'RangeError',
328      code: 'ERR_OUT_OF_RANGE',
329      message:
330        'The value of "options.publicExponent" is out of range. ' +
331        'It must be an integer. ' +
332        `Received ${inspect(publicExponent)}`
333    });
334  }
335
336  // Test invalid exponents. (out of range)
337  for (const publicExponent of [-5, -3, 4294967297]) {
338    assert.throws(() => generateKeyPair('rsa', {
339      modulusLength: 4096,
340      publicExponent
341    }, common.mustNotCall()), {
342      name: 'RangeError',
343      code: 'ERR_OUT_OF_RANGE',
344    });
345  }
346
347  // Test invalid exponents. (caught by OpenSSL)
348  for (const publicExponent of [1, 1 + 0x10001]) {
349    generateKeyPair('rsa', {
350      modulusLength: 4096,
351      publicExponent
352    }, common.mustCall((err) => {
353      assert.strictEqual(err.name, 'Error');
354      assert.match(err.message, common.hasOpenSSL3 ? /exponent/ : /bad e value/);
355    }));
356  }
357}
358
359// Test DSA parameters.
360{
361  // Test invalid modulus lengths. (non-number)
362  for (const modulusLength of [undefined, null, 'a', true, {}, []]) {
363    assert.throws(() => generateKeyPair('dsa', {
364      modulusLength
365    }, common.mustNotCall()), {
366      name: 'TypeError',
367      code: 'ERR_INVALID_ARG_TYPE',
368      message:
369        'The "options.modulusLength" property must be of type number.' +
370        common.invalidArgTypeHelper(modulusLength)
371    });
372  }
373
374  // Test invalid modulus lengths. (non-integer)
375  for (const modulusLength of [512.1, 1.3, 1.1, 5000.9, 100.5]) {
376    assert.throws(() => generateKeyPair('dsa', {
377      modulusLength
378    }, common.mustNotCall()), {
379      name: 'RangeError',
380      code: 'ERR_OUT_OF_RANGE',
381    });
382  }
383
384  // Test invalid modulus lengths. (out of range)
385  for (const modulusLength of [-1, -9, 4294967297]) {
386    assert.throws(() => generateKeyPair('dsa', {
387      modulusLength
388    }, common.mustNotCall()), {
389      name: 'RangeError',
390      code: 'ERR_OUT_OF_RANGE',
391    });
392  }
393
394  // Test invalid divisor lengths. (non-number)
395  for (const divisorLength of ['a', true, {}, []]) {
396    assert.throws(() => generateKeyPair('dsa', {
397      modulusLength: 2048,
398      divisorLength
399    }, common.mustNotCall()), {
400      name: 'TypeError',
401      code: 'ERR_INVALID_ARG_TYPE',
402      message:
403        'The "options.divisorLength" property must be of type number.' +
404        common.invalidArgTypeHelper(divisorLength)
405    });
406  }
407
408  // Test invalid divisor lengths. (non-integer)
409  for (const divisorLength of [4096.1, 5.1, 6.9, 9.5]) {
410    assert.throws(() => generateKeyPair('dsa', {
411      modulusLength: 2048,
412      divisorLength
413    }, common.mustNotCall()), {
414      name: 'RangeError',
415      code: 'ERR_OUT_OF_RANGE',
416      message:
417        'The value of "options.divisorLength" is out of range. ' +
418        'It must be an integer. ' +
419        `Received ${inspect(divisorLength)}`
420    });
421  }
422
423  // Test invalid divisor lengths. (out of range)
424  for (const divisorLength of [-1, -6, -9, 2147483648]) {
425    assert.throws(() => generateKeyPair('dsa', {
426      modulusLength: 2048,
427      divisorLength
428    }, common.mustNotCall()), {
429      name: 'RangeError',
430      code: 'ERR_OUT_OF_RANGE',
431      message:
432        'The value of "options.divisorLength" is out of range. ' +
433        'It must be >= 0 && <= 2147483647. ' +
434        `Received ${inspect(divisorLength)}`
435    });
436  }
437}
438
439// Test EC parameters.
440{
441  // Test invalid curves.
442  assert.throws(() => {
443    generateKeyPairSync('ec', {
444      namedCurve: 'abcdef',
445      publicKeyEncoding: { type: 'spki', format: 'pem' },
446      privateKeyEncoding: { type: 'sec1', format: 'pem' }
447    });
448  }, {
449    name: 'TypeError',
450    message: 'Invalid EC curve name'
451  });
452
453  // Test error type when curve is not a string
454  for (const namedCurve of [true, {}, [], 123]) {
455    assert.throws(() => {
456      generateKeyPairSync('ec', {
457        namedCurve,
458        publicKeyEncoding: { type: 'spki', format: 'pem' },
459        privateKeyEncoding: { type: 'sec1', format: 'pem' }
460      });
461    }, {
462      name: 'TypeError',
463      code: 'ERR_INVALID_ARG_TYPE',
464      message:
465        'The "options.namedCurve" property must be of type string.' +
466        common.invalidArgTypeHelper(namedCurve)
467    });
468  }
469
470  // It should recognize both NIST and standard curve names.
471  generateKeyPair('ec', {
472    namedCurve: 'P-256',
473  }, common.mustSucceed((publicKey, privateKey) => {
474    assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
475      namedCurve: 'prime256v1'
476    });
477    assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
478      namedCurve: 'prime256v1'
479    });
480  }));
481
482  generateKeyPair('ec', {
483    namedCurve: 'secp256k1',
484  }, common.mustSucceed((publicKey, privateKey) => {
485    assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {
486      namedCurve: 'secp256k1'
487    });
488    assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {
489      namedCurve: 'secp256k1'
490    });
491  }));
492}
493
494{
495  assert.throws(() => {
496    generateKeyPair('dh', common.mustNotCall());
497  }, {
498    name: 'TypeError',
499    code: 'ERR_INVALID_ARG_TYPE',
500    message: 'The "options" argument must be of type object. Received undefined'
501  });
502
503  assert.throws(() => {
504    generateKeyPair('dh', {}, common.mustNotCall());
505  }, {
506    name: 'TypeError',
507    code: 'ERR_MISSING_OPTION',
508    message: 'At least one of the group, prime, or primeLength options is ' +
509             'required'
510  });
511
512  assert.throws(() => {
513    generateKeyPair('dh', {
514      group: 'modp0'
515    }, common.mustNotCall());
516  }, {
517    name: 'Error',
518    code: 'ERR_CRYPTO_UNKNOWN_DH_GROUP',
519    message: 'Unknown DH group'
520  });
521
522  assert.throws(() => {
523    generateKeyPair('dh', {
524      primeLength: 2147483648
525    }, common.mustNotCall());
526  }, {
527    name: 'RangeError',
528    code: 'ERR_OUT_OF_RANGE',
529    message: 'The value of "options.primeLength" is out of range. ' +
530             'It must be >= 0 && <= 2147483647. ' +
531             'Received 2147483648',
532  });
533
534  assert.throws(() => {
535    generateKeyPair('dh', {
536      primeLength: -1
537    }, common.mustNotCall());
538  }, {
539    name: 'RangeError',
540    code: 'ERR_OUT_OF_RANGE',
541    message: 'The value of "options.primeLength" is out of range. ' +
542             'It must be >= 0 && <= 2147483647. ' +
543             'Received -1',
544  });
545
546  assert.throws(() => {
547    generateKeyPair('dh', {
548      primeLength: 2,
549      generator: 2147483648,
550    }, common.mustNotCall());
551  }, {
552    name: 'RangeError',
553    code: 'ERR_OUT_OF_RANGE',
554    message: 'The value of "options.generator" is out of range. ' +
555             'It must be >= 0 && <= 2147483647. ' +
556             'Received 2147483648',
557  });
558
559  assert.throws(() => {
560    generateKeyPair('dh', {
561      primeLength: 2,
562      generator: -1,
563    }, common.mustNotCall());
564  }, {
565    name: 'RangeError',
566    code: 'ERR_OUT_OF_RANGE',
567    message: 'The value of "options.generator" is out of range. ' +
568             'It must be >= 0 && <= 2147483647. ' +
569             'Received -1',
570  });
571
572  // Test incompatible options.
573  const allOpts = {
574    group: 'modp5',
575    prime: Buffer.alloc(0),
576    primeLength: 1024,
577    generator: 2
578  };
579  const incompatible = [
580    ['group', 'prime'],
581    ['group', 'primeLength'],
582    ['group', 'generator'],
583    ['prime', 'primeLength'],
584  ];
585  for (const [opt1, opt2] of incompatible) {
586    assert.throws(() => {
587      generateKeyPairSync('dh', {
588        [opt1]: allOpts[opt1],
589        [opt2]: allOpts[opt2]
590      });
591    }, {
592      name: 'TypeError',
593      code: 'ERR_INCOMPATIBLE_OPTION_PAIR',
594      message: `Option "${opt1}" cannot be used in combination with option ` +
595               `"${opt2}"`
596    });
597  }
598}
599
600// Test invalid key encoding types.
601{
602  // Invalid public key type.
603  for (const type of ['foo', 'pkcs8', 'sec1']) {
604    assert.throws(() => {
605      generateKeyPairSync('rsa', {
606        modulusLength: 4096,
607        publicKeyEncoding: { type, format: 'pem' },
608        privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
609      });
610    }, {
611      name: 'TypeError',
612      code: 'ERR_INVALID_ARG_VALUE',
613      message: "The property 'options.publicKeyEncoding.type' is invalid. " +
614        `Received ${inspect(type)}`
615    });
616  }
617
618  // Invalid hash value.
619  for (const hashValue of [123, true, {}, []]) {
620    assert.throws(() => {
621      generateKeyPairSync('rsa-pss', {
622        modulusLength: 4096,
623        hashAlgorithm: hashValue
624      });
625    }, {
626      name: 'TypeError',
627      code: 'ERR_INVALID_ARG_TYPE',
628      message:
629      'The "options.hashAlgorithm" property must be of type string.' +
630        common.invalidArgTypeHelper(hashValue)
631    });
632  }
633
634  // too long salt length
635  assert.throws(() => {
636    generateKeyPair('rsa-pss', {
637      modulusLength: 512,
638      saltLength: 2147483648,
639      hashAlgorithm: 'sha256',
640      mgf1HashAlgorithm: 'sha256'
641    }, common.mustNotCall());
642  }, {
643    name: 'RangeError',
644    code: 'ERR_OUT_OF_RANGE',
645    message: 'The value of "options.saltLength" is out of range. ' +
646             'It must be >= 0 && <= 2147483647. ' +
647             'Received 2147483648'
648  });
649
650  assert.throws(() => {
651    generateKeyPair('rsa-pss', {
652      modulusLength: 512,
653      saltLength: -1,
654      hashAlgorithm: 'sha256',
655      mgf1HashAlgorithm: 'sha256'
656    }, common.mustNotCall());
657  }, {
658    name: 'RangeError',
659    code: 'ERR_OUT_OF_RANGE',
660    message: 'The value of "options.saltLength" is out of range. ' +
661             'It must be >= 0 && <= 2147483647. ' +
662             'Received -1'
663  });
664
665  // Invalid private key type.
666  for (const type of ['foo', 'spki']) {
667    assert.throws(() => {
668      generateKeyPairSync('rsa', {
669        modulusLength: 4096,
670        publicKeyEncoding: { type: 'spki', format: 'pem' },
671        privateKeyEncoding: { type, format: 'pem' }
672      });
673    }, {
674      name: 'TypeError',
675      code: 'ERR_INVALID_ARG_VALUE',
676      message: "The property 'options.privateKeyEncoding.type' is invalid. " +
677        `Received ${inspect(type)}`
678    });
679  }
680
681  // Key encoding doesn't match key type.
682  for (const type of ['dsa', 'ec']) {
683    assert.throws(() => {
684      generateKeyPairSync(type, {
685        modulusLength: 4096,
686        namedCurve: 'P-256',
687        publicKeyEncoding: { type: 'pkcs1', format: 'pem' },
688        privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
689      });
690    }, {
691      name: 'Error',
692      code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS',
693      message: 'The selected key encoding pkcs1 can only be used for RSA keys.'
694    });
695
696    assert.throws(() => {
697      generateKeyPairSync(type, {
698        modulusLength: 4096,
699        namedCurve: 'P-256',
700        publicKeyEncoding: { type: 'spki', format: 'pem' },
701        privateKeyEncoding: { type: 'pkcs1', format: 'pem' }
702      });
703    }, {
704      name: 'Error',
705      code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS',
706      message: 'The selected key encoding pkcs1 can only be used for RSA keys.'
707    });
708  }
709
710  for (const type of ['rsa', 'dsa']) {
711    assert.throws(() => {
712      generateKeyPairSync(type, {
713        modulusLength: 4096,
714        publicKeyEncoding: { type: 'spki', format: 'pem' },
715        privateKeyEncoding: { type: 'sec1', format: 'pem' }
716      });
717    }, {
718      name: 'Error',
719      code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS',
720      message: 'The selected key encoding sec1 can only be used for EC keys.'
721    });
722  }
723
724  // Attempting to encrypt a DER-encoded, non-PKCS#8 key.
725  for (const type of ['pkcs1', 'sec1']) {
726    assert.throws(() => {
727      generateKeyPairSync(type === 'pkcs1' ? 'rsa' : 'ec', {
728        modulusLength: 4096,
729        namedCurve: 'P-256',
730        publicKeyEncoding: { type: 'spki', format: 'pem' },
731        privateKeyEncoding: {
732          type,
733          format: 'der',
734          cipher: 'aes-128-cbc',
735          passphrase: 'hello'
736        }
737      });
738    }, {
739      name: 'Error',
740      code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS',
741      message: `The selected key encoding ${type} does not support encryption.`
742    });
743  }
744}
745
746{
747  // Test RSA-PSS.
748  assert.throws(
749    () => {
750      generateKeyPair('rsa-pss', {
751        modulusLength: 512,
752        saltLength: 16,
753        hashAlgorithm: 'sha256',
754        mgf1HashAlgorithm: undefined
755      });
756    },
757    {
758      name: 'TypeError',
759      code: 'ERR_INVALID_ARG_TYPE',
760    }
761  );
762
763  for (const mgf1HashAlgorithm of [null, 0, false, {}, []]) {
764    assert.throws(
765      () => {
766        generateKeyPair('rsa-pss', {
767          modulusLength: 512,
768          saltLength: 16,
769          hashAlgorithm: 'sha256',
770          mgf1HashAlgorithm
771        }, common.mustNotCall());
772      },
773      {
774        name: 'TypeError',
775        code: 'ERR_INVALID_ARG_TYPE',
776        message:
777          'The "options.mgf1HashAlgorithm" property must be of type string.' +
778          common.invalidArgTypeHelper(mgf1HashAlgorithm)
779
780      }
781    );
782  }
783
784  assert.throws(() => generateKeyPair('rsa-pss', {
785    modulusLength: 512,
786    hashAlgorithm: 'sha2',
787  }, common.mustNotCall()), {
788    name: 'TypeError',
789    code: 'ERR_CRYPTO_INVALID_DIGEST',
790    message: 'Invalid digest: sha2'
791  });
792
793  assert.throws(() => generateKeyPair('rsa-pss', {
794    modulusLength: 512,
795    mgf1HashAlgorithm: 'sha2',
796  }, common.mustNotCall()), {
797    name: 'TypeError',
798    code: 'ERR_CRYPTO_INVALID_DIGEST',
799    message: 'Invalid MGF1 digest: sha2'
800  });
801}
802
803{
804  // This test makes sure deprecated and new options must
805  // be the same value.
806
807  assert.throws(() => generateKeyPair('rsa-pss', {
808    modulusLength: 512,
809    saltLength: 16,
810    mgf1Hash: 'sha256',
811    mgf1HashAlgorithm: 'sha1'
812  }, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE' });
813
814  assert.throws(() => generateKeyPair('rsa-pss', {
815    modulusLength: 512,
816    saltLength: 16,
817    hash: 'sha256',
818    hashAlgorithm: 'sha1'
819  }, common.mustNotCall()), { code: 'ERR_INVALID_ARG_VALUE' });
820}
821