1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto)
5  common.skip('missing crypto');
6
7const assert = require('assert');
8const {
9  generateKeyPair,
10} = require('crypto');
11const {
12  assertApproximateSize,
13  testEncryptDecrypt,
14  testSignVerify,
15  pkcs1EncExp,
16} = require('../common/crypto');
17
18// Test async RSA key generation with an encrypted private key.
19{
20  generateKeyPair('rsa', {
21    publicExponent: 0x10001,
22    modulusLength: 512,
23    publicKeyEncoding: {
24      type: 'pkcs1',
25      format: 'der'
26    },
27    privateKeyEncoding: {
28      type: 'pkcs1',
29      format: 'pem',
30      cipher: 'aes-256-cbc',
31      passphrase: 'secret'
32    }
33  }, common.mustSucceed((publicKeyDER, privateKey) => {
34    assert(Buffer.isBuffer(publicKeyDER));
35    assertApproximateSize(publicKeyDER, 74);
36
37    assert.strictEqual(typeof privateKey, 'string');
38    assert.match(privateKey, pkcs1EncExp('AES-256-CBC'));
39
40    // Since the private key is encrypted, signing shouldn't work anymore.
41    const publicKey = {
42      key: publicKeyDER,
43      type: 'pkcs1',
44      format: 'der',
45    };
46    const expectedError = common.hasOpenSSL3 ? {
47      name: 'Error',
48      message: 'error:07880109:common libcrypto routines::interrupted or ' +
49               'cancelled'
50    } : {
51      name: 'TypeError',
52      code: 'ERR_MISSING_PASSPHRASE',
53      message: 'Passphrase required for encrypted key'
54    };
55    assert.throws(() => testSignVerify(publicKey, privateKey), expectedError);
56
57    const key = { key: privateKey, passphrase: 'secret' };
58    testEncryptDecrypt(publicKey, key);
59    testSignVerify(publicKey, key);
60  }));
61}
62