tests.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. var { assert } = require('chai');
  2. var fs = require('fs');
  3. var { promisify } = require('util');
  4. var exec = promisify(require('child_process').exec);
  5. var crypto = require('crypto');
  6. describe('generate', function () {
  7. var generate = require('../index').generate;
  8. var { createPkcs7 } = require('../pkcs7');
  9. it('should work without attrs/options', async function () {
  10. var pems = await generate();
  11. assert.ok(!!pems.private, 'has a private key');
  12. assert.ok(!!pems.fingerprint, 'has fingerprint');
  13. assert.ok(!!pems.public, 'has a public key');
  14. assert.ok(!!pems.cert, 'has a certificate');
  15. assert.ok(!pems.pkcs7, 'should not include a pkcs7 by default');
  16. assert.ok(!pems.clientcert, 'should not include a client cert by default');
  17. assert.ok(!pems.clientprivate, 'should not include a client private key by default');
  18. assert.ok(!pems.clientpublic, 'should not include a client public key by default');
  19. // Verify cert can be read by Node.js crypto
  20. const cert = new crypto.X509Certificate(pems.cert);
  21. assert.ok(cert.subject, 'cert has a subject');
  22. });
  23. it('should generate client cert', async function () {
  24. var pems = await generate(null, {clientCertificate: true});
  25. assert.ok(!!pems.clientcert, 'should include a client cert when requested');
  26. assert.ok(!!pems.clientprivate, 'should include a client private key when requested');
  27. assert.ok(!!pems.clientpublic, 'should include a client public key when requested');
  28. });
  29. it('should include pkcs7', async function () {
  30. var pems = await generate([{ name: 'commonName', value: 'contoso.com' }]);
  31. var pkcs7 = createPkcs7(pems.cert);
  32. assert.ok(!!pkcs7, 'has a pkcs7');
  33. try {
  34. fs.unlinkSync('/tmp/tmp.pkcs7');
  35. } catch (er) {}
  36. fs.writeFileSync('/tmp/tmp.pkcs7', pkcs7);
  37. const { stdout, stderr } = await exec('openssl pkcs7 -print_certs -in /tmp/tmp.pkcs7');
  38. if (stderr && stderr.length) {
  39. throw new Error(stderr);
  40. }
  41. const expected = stdout.toString();
  42. let [ subjectLine,issuerLine, ...cert ] = expected.split(/\r?\n/).filter(c => c);
  43. cert = cert.filter(c => c);
  44. assert.match(subjectLine, /subject=\/?CN\s?=\s?contoso.com/i);
  45. assert.match(issuerLine, /issuer=\/?CN\s?=\s?contoso.com/i);
  46. // Normalize line endings for comparison
  47. const normalizedPemCert = pems.cert.replace(/\r\n/g, '\n').trim();
  48. const normalizedExpected = cert.join('\n').trim();
  49. assert.strictEqual(
  50. normalizedPemCert,
  51. normalizedExpected
  52. );
  53. });
  54. it('should support sha1 algorithm', async function () {
  55. var pems_sha1 = await generate(null, { algorithm: 'sha1' });
  56. const cert = new crypto.X509Certificate(pems_sha1.cert);
  57. // SHA-1 with RSA signature
  58. assert.ok(cert.publicKey, 'can generate sha1 certs');
  59. });
  60. it('should support sha256 algorithm', async function () {
  61. var pems_sha256 = await generate(null, { algorithm: 'sha256' });
  62. const cert = new crypto.X509Certificate(pems_sha256.cert);
  63. // SHA-256 with RSA signature
  64. assert.ok(cert.publicKey, 'can generate sha256 certs');
  65. });
  66. it('should default to 2048 bit keysize', async function () {
  67. var pems = await generate();
  68. const privateKey = crypto.createPrivateKey(pems.private);
  69. const keyDetails = privateKey.asymmetricKeyDetails;
  70. assert.strictEqual(keyDetails.modulusLength, 2048, 'default key size should be 2048 bits');
  71. });
  72. it('should default to 2048 bit keysize for client certificate', async function () {
  73. var pems = await generate(null, {clientCertificate: true});
  74. const clientPrivateKey = crypto.createPrivateKey(pems.clientprivate);
  75. const keyDetails = clientPrivateKey.asymmetricKeyDetails;
  76. assert.strictEqual(keyDetails.modulusLength, 2048, 'default client key size should be 2048 bits');
  77. });
  78. it('should support custom keySize', async function () {
  79. var pems = await generate(null, { keySize: 4096 });
  80. const privateKey = crypto.createPrivateKey(pems.private);
  81. const keyDetails = privateKey.asymmetricKeyDetails;
  82. assert.strictEqual(keyDetails.modulusLength, 4096, 'should support custom key size');
  83. });
  84. it('should support custom clientCertificateKeySize', async function () {
  85. var pems = await generate(null, {
  86. clientCertificate: true,
  87. clientCertificateKeySize: 4096
  88. });
  89. const clientPrivateKey = crypto.createPrivateKey(pems.clientprivate);
  90. const keyDetails = clientPrivateKey.asymmetricKeyDetails;
  91. assert.strictEqual(keyDetails.modulusLength, 4096, 'should support custom client key size');
  92. });
  93. it('should support sha384 algorithm', async function () {
  94. var pems = await generate(null, { algorithm: 'sha384' });
  95. const cert = new crypto.X509Certificate(pems.cert);
  96. assert.ok(cert.publicKey, 'can generate sha384 certs');
  97. });
  98. it('should support sha512 algorithm', async function () {
  99. var pems = await generate(null, { algorithm: 'sha512' });
  100. const cert = new crypto.X509Certificate(pems.cert);
  101. assert.ok(cert.publicKey, 'can generate sha512 certs');
  102. });
  103. it('should default to 365 days validity', async function () {
  104. var pems = await generate();
  105. const cert = new crypto.X509Certificate(pems.cert);
  106. const validFrom = new Date(cert.validFrom);
  107. const validTo = new Date(cert.validTo);
  108. const diffTime = Math.abs(validTo - validFrom);
  109. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  110. assert.approximately(diffDays, 365, 1, 'certificate should default to 365 days validity');
  111. });
  112. it('should respect notBeforeDate option', async function () {
  113. const customDate = new Date('2025-01-01T00:00:00Z');
  114. var pems = await generate(null, { notBeforeDate: customDate });
  115. const cert = new crypto.X509Certificate(pems.cert);
  116. const validFrom = new Date(cert.validFrom);
  117. // Allow small difference for processing time
  118. assert.approximately(validFrom.getTime(), customDate.getTime(), 5000, 'should use custom notBeforeDate');
  119. });
  120. it('should respect notAfterDate option', async function () {
  121. const notBefore = new Date('2025-01-01T00:00:00Z');
  122. const notAfter = new Date('2025-02-15T00:00:00Z');
  123. var pems = await generate(null, { notBeforeDate: notBefore, notAfterDate: notAfter });
  124. const cert = new crypto.X509Certificate(pems.cert);
  125. const validFrom = new Date(cert.validFrom);
  126. const validTo = new Date(cert.validTo);
  127. assert.approximately(validFrom.getTime(), notBefore.getTime(), 5000, 'should use custom notBeforeDate');
  128. assert.approximately(validTo.getTime(), notAfter.getTime(), 5000, 'should use custom notAfterDate');
  129. });
  130. it('should generate valid fingerprint format', async function () {
  131. var pems = await generate();
  132. assert.match(pems.fingerprint, /^[0-9a-f]{2}(:[0-9a-f]{2}){19}$/i, 'fingerprint should be valid SHA-1 format');
  133. });
  134. it('should support custom attributes', async function () {
  135. const attrs = [
  136. { name: 'commonName', value: 'test.example.com' },
  137. { name: 'countryName', value: 'GB' },
  138. { shortName: 'ST', value: 'London' },
  139. { name: 'localityName', value: 'Westminster' },
  140. { name: 'organizationName', value: 'Test Corp' },
  141. { shortName: 'OU', value: 'Engineering' }
  142. ];
  143. var pems = await generate(attrs);
  144. const cert = new crypto.X509Certificate(pems.cert);
  145. assert.include(cert.subject, 'CN=test.example.com', 'should include custom CN');
  146. assert.include(cert.subject, 'C=GB', 'should include custom country');
  147. assert.include(cert.subject, 'O=Test Corp', 'should include custom organization');
  148. });
  149. it('should support custom clientCertificateCN (deprecated)', async function () {
  150. var pems = await generate(null, {
  151. clientCertificate: true,
  152. clientCertificateCN: 'Custom User CN'
  153. });
  154. const clientCert = new crypto.X509Certificate(pems.clientcert);
  155. assert.include(clientCert.subject, 'CN=Custom User CN', 'should use custom client CN');
  156. });
  157. it('should support clientCertificate as options object with cn', async function () {
  158. var pems = await generate(null, {
  159. clientCertificate: {
  160. cn: 'Client Options CN'
  161. }
  162. });
  163. const clientCert = new crypto.X509Certificate(pems.clientcert);
  164. assert.include(clientCert.subject, 'CN=Client Options CN', 'should use cn from clientCertificate options');
  165. });
  166. it('should support clientCertificate.keySize', async function () {
  167. var pems = await generate(null, {
  168. clientCertificate: {
  169. keySize: 4096
  170. }
  171. });
  172. const clientPrivateKey = crypto.createPrivateKey(pems.clientprivate);
  173. const keyDetails = clientPrivateKey.asymmetricKeyDetails;
  174. assert.strictEqual(keyDetails.modulusLength, 4096, 'should use keySize from clientCertificate options');
  175. });
  176. it('should support clientCertificate.notBeforeDate and notAfterDate', async function () {
  177. const notBefore = new Date('2025-06-01T00:00:00Z');
  178. const notAfter = new Date('2025-06-30T00:00:00Z');
  179. var pems = await generate(null, {
  180. clientCertificate: {
  181. notBeforeDate: notBefore,
  182. notAfterDate: notAfter
  183. }
  184. });
  185. const clientCert = new crypto.X509Certificate(pems.clientcert);
  186. const validFrom = new Date(clientCert.validFrom);
  187. const validTo = new Date(clientCert.validTo);
  188. assert.approximately(validFrom.getTime(), notBefore.getTime(), 5000, 'should use notBeforeDate from clientCertificate options');
  189. assert.approximately(validTo.getTime(), notAfter.getTime(), 5000, 'should use notAfterDate from clientCertificate options');
  190. });
  191. it('should support clientCertificate.algorithm', async function () {
  192. var pems = await generate(null, {
  193. algorithm: 'sha1', // main cert uses sha1
  194. clientCertificate: {
  195. algorithm: 'sha256' // client cert uses sha256
  196. }
  197. });
  198. // Both certs should be valid
  199. const serverCert = new crypto.X509Certificate(pems.cert);
  200. const clientCert = new crypto.X509Certificate(pems.clientcert);
  201. assert.ok(serverCert.publicKey, 'server cert should be valid');
  202. assert.ok(clientCert.publicKey, 'client cert should be valid');
  203. });
  204. it('clientCertificate options should take precedence over deprecated options', async function () {
  205. var pems = await generate(null, {
  206. clientCertificateCN: 'Deprecated CN',
  207. clientCertificateKeySize: 2048,
  208. clientCertificate: {
  209. cn: 'New Options CN',
  210. keySize: 4096
  211. }
  212. });
  213. const clientCert = new crypto.X509Certificate(pems.clientcert);
  214. assert.include(clientCert.subject, 'CN=New Options CN', 'clientCertificate.cn should take precedence');
  215. const clientPrivateKey = crypto.createPrivateKey(pems.clientprivate);
  216. const keyDetails = clientPrivateKey.asymmetricKeyDetails;
  217. assert.strictEqual(keyDetails.modulusLength, 4096, 'clientCertificate.keySize should take precedence');
  218. });
  219. it('should generate valid key pair that work together', async function () {
  220. var pems = await generate();
  221. // Test data
  222. const testData = 'Hello, World!';
  223. // Create sign and verify objects
  224. const privateKey = crypto.createPrivateKey(pems.private);
  225. const publicKey = crypto.createPublicKey(pems.public);
  226. // Sign with private key
  227. const sign = crypto.createSign('SHA256');
  228. sign.update(testData);
  229. sign.end();
  230. const signature = sign.sign(privateKey);
  231. // Verify with public key
  232. const verify = crypto.createVerify('SHA256');
  233. verify.update(testData);
  234. verify.end();
  235. const isValid = verify.verify(publicKey, signature);
  236. assert.isTrue(isValid, 'public key should verify signature from private key');
  237. });
  238. it('should create client cert signed by server cert', async function () {
  239. var pems = await generate(null, { clientCertificate: true });
  240. const serverCert = new crypto.X509Certificate(pems.cert);
  241. const clientCert = new crypto.X509Certificate(pems.clientcert);
  242. // Client cert should have different subject than server
  243. assert.notEqual(clientCert.subject, serverCert.subject, 'client and server should have different subjects');
  244. // Both certs should be valid
  245. assert.ok(serverCert.publicKey, 'server cert should be valid');
  246. assert.ok(clientCert.publicKey, 'client cert should be valid');
  247. });
  248. it('should support using existing keyPair', async function () {
  249. // First generate a key pair
  250. const firstPems = await generate();
  251. // Reuse the key pair
  252. const secondPems = await generate(null, {
  253. keyPair: {
  254. privateKey: firstPems.private,
  255. publicKey: firstPems.public
  256. }
  257. });
  258. // Keys should be identical
  259. assert.strictEqual(firstPems.private, secondPems.private, 'should use provided private key');
  260. assert.strictEqual(firstPems.public, secondPems.public, 'should use provided public key');
  261. // Certificates will be different (different serial, dates) but keys are same
  262. const firstCert = new crypto.X509Certificate(firstPems.cert);
  263. const secondCert = new crypto.X509Certificate(secondPems.cert);
  264. assert.strictEqual(firstCert.publicKey.export({ format: 'pem', type: 'spki' }),
  265. secondCert.publicKey.export({ format: 'pem', type: 'spki' }),
  266. 'certificates should contain the same public key');
  267. });
  268. it('should create PKCS#7 for client certificate', async function () {
  269. var pems = await generate([{ name: 'commonName', value: 'server.example.com' }], {
  270. clientCertificate: true
  271. });
  272. var clientPkcs7 = createPkcs7(pems.clientcert);
  273. assert.ok(!!clientPkcs7, 'should create PKCS#7 for client cert');
  274. assert.include(clientPkcs7, 'BEGIN PKCS7', 'should be valid PKCS#7 format');
  275. // Verify with openssl
  276. try {
  277. fs.unlinkSync('/tmp/tmp-client.pkcs7');
  278. } catch (er) {}
  279. fs.writeFileSync('/tmp/tmp-client.pkcs7', clientPkcs7);
  280. const { stdout, stderr } = await exec('openssl pkcs7 -print_certs -in /tmp/tmp-client.pkcs7');
  281. if (stderr && stderr.length) {
  282. throw new Error(stderr);
  283. }
  284. assert.ok(stdout.toString().length > 0, 'openssl should be able to read client PKCS#7');
  285. });
  286. it('should generate unique serial numbers', async function () {
  287. const pems1 = await generate();
  288. const pems2 = await generate();
  289. const cert1 = new crypto.X509Certificate(pems1.cert);
  290. const cert2 = new crypto.X509Certificate(pems2.cert);
  291. assert.notEqual(cert1.serialNumber, cert2.serialNumber, 'serial numbers should be unique');
  292. });
  293. it('should handle minimal attributes', async function () {
  294. const attrs = [{ name: 'commonName', value: 'minimal.test' }];
  295. var pems = await generate(attrs);
  296. const cert = new crypto.X509Certificate(pems.cert);
  297. assert.include(cert.subject, 'CN=minimal.test', 'should work with minimal attributes');
  298. });
  299. describe('extensions', function () {
  300. it('should support custom subjectAltName with IPv6 (issue #79)', async function () {
  301. var pems = await generate(
  302. [{ name: 'commonName', value: 'localhost' }],
  303. {
  304. algorithm: 'sha256',
  305. extensions: [
  306. {
  307. name: 'basicConstraints',
  308. cA: false
  309. },
  310. {
  311. name: 'keyUsage',
  312. digitalSignature: true,
  313. keyEncipherment: true
  314. },
  315. {
  316. name: 'subjectAltName',
  317. altNames: [
  318. { type: 2, value: 'localhost' }, // DNS
  319. { type: 7, ip: '127.0.0.1' }, // IPv4
  320. { type: 7, ip: '::1' } // IPv6
  321. ]
  322. }
  323. ]
  324. }
  325. );
  326. const cert = new crypto.X509Certificate(pems.cert);
  327. assert.ok(cert.subjectAltName, 'should have subjectAltName');
  328. assert.include(cert.subjectAltName, 'localhost', 'should include DNS name');
  329. assert.include(cert.subjectAltName, '127.0.0.1', 'should include IPv4');
  330. // IPv6 ::1 may be expanded to full form 0:0:0:0:0:0:0:1
  331. const hasIPv6 = cert.subjectAltName.includes('::1') || cert.subjectAltName.includes('0:0:0:0:0:0:0:1');
  332. assert.ok(hasIPv6, 'should include IPv6');
  333. });
  334. it('should support basicConstraints with cA=true', async function () {
  335. var pems = await generate(
  336. [{ name: 'commonName', value: 'Test CA' }],
  337. {
  338. extensions: [
  339. {
  340. name: 'basicConstraints',
  341. cA: true,
  342. critical: true
  343. },
  344. {
  345. name: 'keyUsage',
  346. keyCertSign: true,
  347. cRLSign: true,
  348. critical: true
  349. }
  350. ]
  351. }
  352. );
  353. const cert = new crypto.X509Certificate(pems.cert);
  354. assert.ok(cert.ca, 'certificate should be a CA');
  355. });
  356. it('should support keyUsage extension', async function () {
  357. var pems = await generate(
  358. [{ name: 'commonName', value: 'test.example.com' }],
  359. {
  360. extensions: [
  361. {
  362. name: 'basicConstraints',
  363. cA: false
  364. },
  365. {
  366. name: 'keyUsage',
  367. digitalSignature: true,
  368. keyEncipherment: true,
  369. dataEncipherment: true
  370. }
  371. ]
  372. }
  373. );
  374. const cert = new crypto.X509Certificate(pems.cert);
  375. // Node.js X509Certificate doesn't expose keyUsage directly,
  376. // but we can verify the cert is valid and can be used
  377. assert.ok(cert.publicKey, 'should generate valid cert with keyUsage');
  378. // Verify by using openssl to check extensions
  379. const fs = require('fs');
  380. fs.writeFileSync('/tmp/test-keyusage.crt', pems.cert);
  381. const { execSync } = require('child_process');
  382. const output = execSync('openssl x509 -in /tmp/test-keyusage.crt -text -noout').toString();
  383. assert.include(output, 'Digital Signature', 'should have digitalSignature');
  384. assert.include(output, 'Key Encipherment', 'should have keyEncipherment');
  385. });
  386. it('should support extKeyUsage extension', async function () {
  387. var pems = await generate(
  388. [{ name: 'commonName', value: 'test.example.com' }],
  389. {
  390. extensions: [
  391. {
  392. name: 'basicConstraints',
  393. cA: false
  394. },
  395. {
  396. name: 'extKeyUsage',
  397. serverAuth: true,
  398. clientAuth: true,
  399. codeSigning: true
  400. }
  401. ]
  402. }
  403. );
  404. const cert = new crypto.X509Certificate(pems.cert);
  405. // Node.js crypto doesn't expose extended key usage directly, but cert should be valid
  406. assert.ok(cert.publicKey, 'should generate valid cert with extKeyUsage');
  407. });
  408. it('should support subjectAltName with DNS names', async function () {
  409. var pems = await generate(
  410. [{ name: 'commonName', value: 'example.com' }],
  411. {
  412. extensions: [
  413. {
  414. name: 'basicConstraints',
  415. cA: false
  416. },
  417. {
  418. name: 'subjectAltName',
  419. altNames: [
  420. { type: 2, value: 'example.com' },
  421. { type: 2, value: 'www.example.com' },
  422. { type: 2, value: '*.example.com' }
  423. ]
  424. }
  425. ]
  426. }
  427. );
  428. const cert = new crypto.X509Certificate(pems.cert);
  429. assert.include(cert.subjectAltName, 'example.com', 'should include example.com');
  430. assert.include(cert.subjectAltName, 'www.example.com', 'should include www.example.com');
  431. assert.include(cert.subjectAltName, '*.example.com', 'should include wildcard');
  432. });
  433. it('should support subjectAltName with email and URI', async function () {
  434. var pems = await generate(
  435. [{ name: 'commonName', value: 'test.example.com' }],
  436. {
  437. extensions: [
  438. {
  439. name: 'basicConstraints',
  440. cA: false
  441. },
  442. {
  443. name: 'subjectAltName',
  444. altNames: [
  445. { type: 2, value: 'test.example.com' },
  446. { type: 1, value: 'admin@example.com' }, // email
  447. { type: 6, value: 'http://example.com/webid#me' } // URI
  448. ]
  449. }
  450. ]
  451. }
  452. );
  453. const cert = new crypto.X509Certificate(pems.cert);
  454. assert.include(cert.subjectAltName, 'test.example.com', 'should include DNS');
  455. assert.include(cert.subjectAltName, 'admin@example.com', 'should include email');
  456. assert.include(cert.subjectAltName, 'http://example.com/webid#me', 'should include URI');
  457. });
  458. it('should use default extensions when extensions option is empty array', async function () {
  459. var pems = await generate(
  460. [{ name: 'commonName', value: 'localhost' }],
  461. {
  462. extensions: []
  463. }
  464. );
  465. const cert = new crypto.X509Certificate(pems.cert);
  466. // Default behavior includes localhost and 127.0.0.1
  467. assert.include(cert.subjectAltName, 'localhost', 'should use default SAN');
  468. assert.include(cert.subjectAltName, '127.0.0.1', 'should include default IP for localhost');
  469. });
  470. it('should use default extensions when extensions option is not provided', async function () {
  471. var pems = await generate([{ name: 'commonName', value: 'myhost.local' }]);
  472. const cert = new crypto.X509Certificate(pems.cert);
  473. assert.include(cert.subjectAltName, 'myhost.local', 'should use commonName in default SAN');
  474. });
  475. });
  476. it('should support passphrase for private key encryption', async function () {
  477. const passphrase = 'my-secret-passphrase';
  478. var pems = await generate(null, { passphrase: passphrase });
  479. assert.ok(!!pems.private, 'has a private key');
  480. assert.include(pems.private, 'ENCRYPTED', 'private key should be encrypted');
  481. // Verify the key can be decrypted with the correct passphrase
  482. const privateKey = crypto.createPrivateKey({
  483. key: pems.private,
  484. passphrase: passphrase
  485. });
  486. assert.ok(privateKey, 'should be able to decrypt private key with passphrase');
  487. // Verify signing works with decrypted key
  488. const testData = 'Hello, World!';
  489. const sign = crypto.createSign('SHA256');
  490. sign.update(testData);
  491. sign.end();
  492. const signature = sign.sign({ key: pems.private, passphrase: passphrase });
  493. const verify = crypto.createVerify('SHA256');
  494. verify.update(testData);
  495. verify.end();
  496. const isValid = verify.verify(pems.public, signature);
  497. assert.isTrue(isValid, 'encrypted key should work for signing');
  498. });
  499. it('should fail to decrypt private key with wrong passphrase', async function () {
  500. const passphrase = 'correct-passphrase';
  501. var pems = await generate(null, { passphrase: passphrase });
  502. assert.throws(() => {
  503. crypto.createPrivateKey({
  504. key: pems.private,
  505. passphrase: 'wrong-passphrase'
  506. });
  507. });
  508. });
  509. });