11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst assert = require('assert');
81cb0ef41Sopenharmony_ciconst {
91cb0ef41Sopenharmony_ci  createCipheriv,
101cb0ef41Sopenharmony_ci  createDecipheriv,
111cb0ef41Sopenharmony_ci  createSign,
121cb0ef41Sopenharmony_ci  createVerify,
131cb0ef41Sopenharmony_ci  createSecretKey,
141cb0ef41Sopenharmony_ci  createPublicKey,
151cb0ef41Sopenharmony_ci  createPrivateKey,
161cb0ef41Sopenharmony_ci  KeyObject,
171cb0ef41Sopenharmony_ci  randomBytes,
181cb0ef41Sopenharmony_ci  publicDecrypt,
191cb0ef41Sopenharmony_ci  publicEncrypt,
201cb0ef41Sopenharmony_ci  privateDecrypt,
211cb0ef41Sopenharmony_ci  privateEncrypt,
221cb0ef41Sopenharmony_ci  getCurves,
231cb0ef41Sopenharmony_ci  generateKeySync,
241cb0ef41Sopenharmony_ci  generateKeyPairSync,
251cb0ef41Sopenharmony_ci} = require('crypto');
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciconst publicPem = fixtures.readKey('rsa_public.pem', 'ascii');
301cb0ef41Sopenharmony_ciconst privatePem = fixtures.readKey('rsa_private.pem', 'ascii');
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciconst publicDsa = fixtures.readKey('dsa_public_1025.pem', 'ascii');
331cb0ef41Sopenharmony_ciconst privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem',
341cb0ef41Sopenharmony_ci                                    'ascii');
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci{
371cb0ef41Sopenharmony_ci  // Attempting to create a key of a wrong type should throw
381cb0ef41Sopenharmony_ci  const TYPE = 'wrong_type';
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  assert.throws(() => new KeyObject(TYPE), {
411cb0ef41Sopenharmony_ci    name: 'TypeError',
421cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
431cb0ef41Sopenharmony_ci    message: `The argument 'type' is invalid. Received '${TYPE}'`
441cb0ef41Sopenharmony_ci  });
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci{
481cb0ef41Sopenharmony_ci  // Attempting to create a key with non-object handle should throw
491cb0ef41Sopenharmony_ci  assert.throws(() => new KeyObject('secret', ''), {
501cb0ef41Sopenharmony_ci    name: 'TypeError',
511cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
521cb0ef41Sopenharmony_ci    message:
531cb0ef41Sopenharmony_ci      'The "handle" argument must be of type object. Received type ' +
541cb0ef41Sopenharmony_ci      "string ('')"
551cb0ef41Sopenharmony_ci  });
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci{
591cb0ef41Sopenharmony_ci  assert.throws(() => KeyObject.from('invalid_key'), {
601cb0ef41Sopenharmony_ci    name: 'TypeError',
611cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
621cb0ef41Sopenharmony_ci    message:
631cb0ef41Sopenharmony_ci      'The "key" argument must be an instance of CryptoKey. Received type ' +
641cb0ef41Sopenharmony_ci      "string ('invalid_key')"
651cb0ef41Sopenharmony_ci  });
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci{
691cb0ef41Sopenharmony_ci  const keybuf = randomBytes(32);
701cb0ef41Sopenharmony_ci  const key = createSecretKey(keybuf);
711cb0ef41Sopenharmony_ci  assert.strictEqual(key.type, 'secret');
721cb0ef41Sopenharmony_ci  assert.strictEqual(key.toString(), '[object KeyObject]');
731cb0ef41Sopenharmony_ci  assert.strictEqual(key.symmetricKeySize, 32);
741cb0ef41Sopenharmony_ci  assert.strictEqual(key.asymmetricKeyType, undefined);
751cb0ef41Sopenharmony_ci  assert.strictEqual(key.asymmetricKeyDetails, undefined);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  const exportedKey = key.export();
781cb0ef41Sopenharmony_ci  assert(keybuf.equals(exportedKey));
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  const plaintext = Buffer.from('Hello world', 'utf8');
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  const cipher = createCipheriv('aes-256-ecb', key, null);
831cb0ef41Sopenharmony_ci  const ciphertext = Buffer.concat([
841cb0ef41Sopenharmony_ci    cipher.update(plaintext), cipher.final(),
851cb0ef41Sopenharmony_ci  ]);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  const decipher = createDecipheriv('aes-256-ecb', key, null);
881cb0ef41Sopenharmony_ci  const deciphered = Buffer.concat([
891cb0ef41Sopenharmony_ci    decipher.update(ciphertext), decipher.final(),
901cb0ef41Sopenharmony_ci  ]);
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  assert(plaintext.equals(deciphered));
931cb0ef41Sopenharmony_ci}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci{
961cb0ef41Sopenharmony_ci  // Passing an existing public key object to createPublicKey should throw.
971cb0ef41Sopenharmony_ci  const publicKey = createPublicKey(publicPem);
981cb0ef41Sopenharmony_ci  assert.throws(() => createPublicKey(publicKey), {
991cb0ef41Sopenharmony_ci    name: 'TypeError',
1001cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE',
1011cb0ef41Sopenharmony_ci    message: 'Invalid key object type public, expected private.'
1021cb0ef41Sopenharmony_ci  });
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // Constructing a private key from a public key should be impossible, even
1051cb0ef41Sopenharmony_ci  // if the public key was derived from a private key.
1061cb0ef41Sopenharmony_ci  assert.throws(() => createPrivateKey(createPublicKey(privatePem)), {
1071cb0ef41Sopenharmony_ci    name: 'TypeError',
1081cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
1091cb0ef41Sopenharmony_ci  });
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  // Similarly, passing an existing private key object to createPrivateKey
1121cb0ef41Sopenharmony_ci  // should throw.
1131cb0ef41Sopenharmony_ci  const privateKey = createPrivateKey(privatePem);
1141cb0ef41Sopenharmony_ci  assert.throws(() => createPrivateKey(privateKey), {
1151cb0ef41Sopenharmony_ci    name: 'TypeError',
1161cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
1171cb0ef41Sopenharmony_ci  });
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci{
1211cb0ef41Sopenharmony_ci  const jwk = {
1221cb0ef41Sopenharmony_ci    e: 'AQAB',
1231cb0ef41Sopenharmony_ci    n: 't9xYiIonscC3vz_A2ceR7KhZZlDu_5bye53nCVTcKnWd2seY6UAdKersX6njr83Dd5OVe' +
1241cb0ef41Sopenharmony_ci       '1BW_wJvp5EjWTAGYbFswlNmeD44edEGM939B6Lq-_8iBkrTi8mGN4YCytivE24YI0D4XZ' +
1251cb0ef41Sopenharmony_ci       'MPfkLSpab2y_Hy4DjQKBq1ThZ0UBnK-9IhX37Ju_ZoGYSlTIGIhzyaiYBh7wrZBoPczIE' +
1261cb0ef41Sopenharmony_ci       'u6et_kN2VnnbRUtkYTF97ggcv5h-hDpUQjQW0ZgOMcTc8n-RkGpIt0_iM_bTjI3Tz_gsF' +
1271cb0ef41Sopenharmony_ci       'di6hHcpZgbopPL630296iByyigQCPJVzdusFrQN5DeC-zT_nGypQkZanLb4ZspSx9Q',
1281cb0ef41Sopenharmony_ci    d: 'ktnq2LvIMqBj4txP82IEOorIRQGVsw1khbm8A-cEpuEkgM71Yi_0WzupKktucUeevQ5i0' +
1291cb0ef41Sopenharmony_ci       'Yh8w9e1SJiTLDRAlJz66kdky9uejiWWl6zR4dyNZVMFYRM43ijLC-P8rPne9Fz16IqHFW' +
1301cb0ef41Sopenharmony_ci       '5VbJqA1xCBhKmuPMsD71RNxZ4Hrsa7Kt_xglQTYsLbdGIwDmcZihId9VGXRzvmCPsDRf2' +
1311cb0ef41Sopenharmony_ci       'fCkAj7HDeRxpUdEiEDpajADc-PWikra3r3b40tVHKWm8wxJLivOIN7GiYXKQIW6RhZgH-' +
1321cb0ef41Sopenharmony_ci       'Rk45JIRNKxNagxdeXUqqyhnwhbTo1Hite0iBDexN9tgoZk0XmdYWBn6ElXHRZ7VCDQ',
1331cb0ef41Sopenharmony_ci    p: '8UovlB4nrBm7xH-u7XXBMbqxADQm5vaEZxw9eluc-tP7cIAI4sglMIvL_FMpbd2pEeP_B' +
1341cb0ef41Sopenharmony_ci       'kR76NTDzzDuPAZvUGRavgEjy0O9j2NAs_WPK4tZF-vFdunhnSh4EHAF4Ij9kbsUi90NOp' +
1351cb0ef41Sopenharmony_ci       'bGfVqPdOaHqzgHKoR23Cuusk9wFQ2XTV8',
1361cb0ef41Sopenharmony_ci    q: 'wxHdEYT9xrpfrHPqSBQPpO0dWGKJEkrWOb-76rSfuL8wGR4OBNmQdhLuU9zTIh22pog-X' +
1371cb0ef41Sopenharmony_ci       'PnLPAecC-4yu_wtJ2SPCKiKDbJBre0CKPyRfGqzvA3njXwMxXazU4kGs-2Fg-xu_iKbaI' +
1381cb0ef41Sopenharmony_ci       'jxXrclBLhkxhBtySrwAFhxxOk6fFcPLSs',
1391cb0ef41Sopenharmony_ci    dp: 'qS_Mdr5CMRGGMH0bKhPUWEtAixUGZhJaunX5wY71Xoc_Gh4cnO-b7BNJ_-5L8WZog0vr' +
1401cb0ef41Sopenharmony_ci       '6PgiLhrqBaCYm2wjpyoG2o2wDHm-NAlzN_wp3G2EFhrSxdOux-S1c0kpRcyoiAO2n29rN' +
1411cb0ef41Sopenharmony_ci       'Da-jOzwBBcU8ACEPdLOCQl0IEFFJO33tl8',
1421cb0ef41Sopenharmony_ci    dq: 'WAziKpxLKL7LnL4dzDcx8JIPIuwnTxh0plCDdCffyLaT8WJ9lXbXHFTjOvt8WfPrlDP_' +
1431cb0ef41Sopenharmony_ci       'Ylxmfkw5BbGZOP1VLGjZn2DkH9aMiwNmbDXFPdG0G3hzQovx_9fajiRV4DWghLHeT9wzJ' +
1441cb0ef41Sopenharmony_ci       'fZabRRiI0VQR472300AVEeX4vgbrDBn600',
1451cb0ef41Sopenharmony_ci    qi: 'k7czBCT9rHn_PNwCa17hlTy88C4vXkwbz83Oa-aX5L4e5gw5lhcR2ZuZHLb2r6oMt9rl' +
1461cb0ef41Sopenharmony_ci       'D7EIDItSs-u21LOXWPTAlazdnpYUyw_CzogM_PN-qNwMRXn5uXFFhmlP2mVg2EdELTahX' +
1471cb0ef41Sopenharmony_ci       'ch8kWqHaCSX53yvqCtRKu_j76V31TfQZGM',
1481cb0ef41Sopenharmony_ci    kty: 'RSA',
1491cb0ef41Sopenharmony_ci  };
1501cb0ef41Sopenharmony_ci  const publicJwk = { kty: jwk.kty, e: jwk.e, n: jwk.n };
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  const publicKey = createPublicKey(publicPem);
1531cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.type, 'public');
1541cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.toString(), '[object KeyObject]');
1551cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.asymmetricKeyType, 'rsa');
1561cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.symmetricKeySize, undefined);
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  const privateKey = createPrivateKey(privatePem);
1591cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.type, 'private');
1601cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.toString(), '[object KeyObject]');
1611cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.asymmetricKeyType, 'rsa');
1621cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.symmetricKeySize, undefined);
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci  // It should be possible to derive a public key from a private key.
1651cb0ef41Sopenharmony_ci  const derivedPublicKey = createPublicKey(privateKey);
1661cb0ef41Sopenharmony_ci  assert.strictEqual(derivedPublicKey.type, 'public');
1671cb0ef41Sopenharmony_ci  assert.strictEqual(derivedPublicKey.toString(), '[object KeyObject]');
1681cb0ef41Sopenharmony_ci  assert.strictEqual(derivedPublicKey.asymmetricKeyType, 'rsa');
1691cb0ef41Sopenharmony_ci  assert.strictEqual(derivedPublicKey.symmetricKeySize, undefined);
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  const publicKeyFromJwk = createPublicKey({ key: publicJwk, format: 'jwk' });
1721cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.type, 'public');
1731cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.toString(), '[object KeyObject]');
1741cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.asymmetricKeyType, 'rsa');
1751cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.symmetricKeySize, undefined);
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  const privateKeyFromJwk = createPrivateKey({ key: jwk, format: 'jwk' });
1781cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.type, 'private');
1791cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.toString(), '[object KeyObject]');
1801cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.asymmetricKeyType, 'rsa');
1811cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.symmetricKeySize, undefined);
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  // It should also be possible to import an encrypted private key as a public
1841cb0ef41Sopenharmony_ci  // key.
1851cb0ef41Sopenharmony_ci  const decryptedKey = createPublicKey({
1861cb0ef41Sopenharmony_ci    key: privateKey.export({
1871cb0ef41Sopenharmony_ci      type: 'pkcs8',
1881cb0ef41Sopenharmony_ci      format: 'pem',
1891cb0ef41Sopenharmony_ci      passphrase: '123',
1901cb0ef41Sopenharmony_ci      cipher: 'aes-128-cbc'
1911cb0ef41Sopenharmony_ci    }),
1921cb0ef41Sopenharmony_ci    format: 'pem',
1931cb0ef41Sopenharmony_ci    passphrase: '123'
1941cb0ef41Sopenharmony_ci  });
1951cb0ef41Sopenharmony_ci  assert.strictEqual(decryptedKey.type, 'public');
1961cb0ef41Sopenharmony_ci  assert.strictEqual(decryptedKey.asymmetricKeyType, 'rsa');
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci  // Test exporting with an invalid options object, this should throw.
1991cb0ef41Sopenharmony_ci  for (const opt of [undefined, null, 'foo', 0, NaN]) {
2001cb0ef41Sopenharmony_ci    assert.throws(() => publicKey.export(opt), {
2011cb0ef41Sopenharmony_ci      name: 'TypeError',
2021cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
2031cb0ef41Sopenharmony_ci      message: /^The "options" argument must be of type object/
2041cb0ef41Sopenharmony_ci    });
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci  for (const keyObject of [publicKey, derivedPublicKey, publicKeyFromJwk]) {
2081cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
2091cb0ef41Sopenharmony_ci      keyObject.export({ format: 'jwk' }),
2101cb0ef41Sopenharmony_ci      { kty: 'RSA', n: jwk.n, e: jwk.e }
2111cb0ef41Sopenharmony_ci    );
2121cb0ef41Sopenharmony_ci  }
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  for (const keyObject of [privateKey, privateKeyFromJwk]) {
2151cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
2161cb0ef41Sopenharmony_ci      keyObject.export({ format: 'jwk' }),
2171cb0ef41Sopenharmony_ci      jwk
2181cb0ef41Sopenharmony_ci    );
2191cb0ef41Sopenharmony_ci  }
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci  // Exporting the key using JWK should not work since this format does not
2221cb0ef41Sopenharmony_ci  // support key encryption
2231cb0ef41Sopenharmony_ci  assert.throws(() => {
2241cb0ef41Sopenharmony_ci    privateKey.export({ format: 'jwk', passphrase: 'secret' });
2251cb0ef41Sopenharmony_ci  }, {
2261cb0ef41Sopenharmony_ci    message: 'The selected key encoding jwk does not support encryption.',
2271cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS'
2281cb0ef41Sopenharmony_ci  });
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  const publicDER = publicKey.export({
2311cb0ef41Sopenharmony_ci    format: 'der',
2321cb0ef41Sopenharmony_ci    type: 'pkcs1'
2331cb0ef41Sopenharmony_ci  });
2341cb0ef41Sopenharmony_ci
2351cb0ef41Sopenharmony_ci  const privateDER = privateKey.export({
2361cb0ef41Sopenharmony_ci    format: 'der',
2371cb0ef41Sopenharmony_ci    type: 'pkcs1'
2381cb0ef41Sopenharmony_ci  });
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  assert(Buffer.isBuffer(publicDER));
2411cb0ef41Sopenharmony_ci  assert(Buffer.isBuffer(privateDER));
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  const plaintext = Buffer.from('Hello world', 'utf8');
2441cb0ef41Sopenharmony_ci  const testDecryption = (fn, ciphertexts, decryptionKeys) => {
2451cb0ef41Sopenharmony_ci    for (const ciphertext of ciphertexts) {
2461cb0ef41Sopenharmony_ci      for (const key of decryptionKeys) {
2471cb0ef41Sopenharmony_ci        const deciphered = fn(key, ciphertext);
2481cb0ef41Sopenharmony_ci        assert.deepStrictEqual(deciphered, plaintext);
2491cb0ef41Sopenharmony_ci      }
2501cb0ef41Sopenharmony_ci    }
2511cb0ef41Sopenharmony_ci  };
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ci  testDecryption(privateDecrypt, [
2541cb0ef41Sopenharmony_ci    // Encrypt using the public key.
2551cb0ef41Sopenharmony_ci    publicEncrypt(publicKey, plaintext),
2561cb0ef41Sopenharmony_ci    publicEncrypt({ key: publicKey }, plaintext),
2571cb0ef41Sopenharmony_ci    publicEncrypt({ key: publicJwk, format: 'jwk' }, plaintext),
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci    // Encrypt using the private key.
2601cb0ef41Sopenharmony_ci    publicEncrypt(privateKey, plaintext),
2611cb0ef41Sopenharmony_ci    publicEncrypt({ key: privateKey }, plaintext),
2621cb0ef41Sopenharmony_ci    publicEncrypt({ key: jwk, format: 'jwk' }, plaintext),
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci    // Encrypt using a public key derived from the private key.
2651cb0ef41Sopenharmony_ci    publicEncrypt(derivedPublicKey, plaintext),
2661cb0ef41Sopenharmony_ci    publicEncrypt({ key: derivedPublicKey }, plaintext),
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci    // Test distinguishing PKCS#1 public and private keys based on the
2691cb0ef41Sopenharmony_ci    // DER-encoded data only.
2701cb0ef41Sopenharmony_ci    publicEncrypt({ format: 'der', type: 'pkcs1', key: publicDER }, plaintext),
2711cb0ef41Sopenharmony_ci    publicEncrypt({ format: 'der', type: 'pkcs1', key: privateDER }, plaintext),
2721cb0ef41Sopenharmony_ci  ], [
2731cb0ef41Sopenharmony_ci    privateKey,
2741cb0ef41Sopenharmony_ci    { format: 'pem', key: privatePem },
2751cb0ef41Sopenharmony_ci    { format: 'der', type: 'pkcs1', key: privateDER },
2761cb0ef41Sopenharmony_ci    { key: jwk, format: 'jwk' },
2771cb0ef41Sopenharmony_ci  ]);
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  testDecryption(publicDecrypt, [
2801cb0ef41Sopenharmony_ci    privateEncrypt(privateKey, plaintext),
2811cb0ef41Sopenharmony_ci  ], [
2821cb0ef41Sopenharmony_ci    // Decrypt using the public key.
2831cb0ef41Sopenharmony_ci    publicKey,
2841cb0ef41Sopenharmony_ci    { format: 'pem', key: publicPem },
2851cb0ef41Sopenharmony_ci    { format: 'der', type: 'pkcs1', key: publicDER },
2861cb0ef41Sopenharmony_ci    { key: publicJwk, format: 'jwk' },
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci    // Decrypt using the private key.
2891cb0ef41Sopenharmony_ci    privateKey,
2901cb0ef41Sopenharmony_ci    { format: 'pem', key: privatePem },
2911cb0ef41Sopenharmony_ci    { format: 'der', type: 'pkcs1', key: privateDER },
2921cb0ef41Sopenharmony_ci    { key: jwk, format: 'jwk' },
2931cb0ef41Sopenharmony_ci  ]);
2941cb0ef41Sopenharmony_ci}
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci{
2971cb0ef41Sopenharmony_ci  // This should not cause a crash: https://github.com/nodejs/node/issues/25247
2981cb0ef41Sopenharmony_ci  assert.throws(() => {
2991cb0ef41Sopenharmony_ci    createPrivateKey({ key: '' });
3001cb0ef41Sopenharmony_ci  }, common.hasOpenSSL3 ? {
3011cb0ef41Sopenharmony_ci    message: 'error:1E08010C:DECODER routines::unsupported',
3021cb0ef41Sopenharmony_ci  } : {
3031cb0ef41Sopenharmony_ci    message: 'error:0909006C:PEM routines:get_name:no start line',
3041cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_PEM_NO_START_LINE',
3051cb0ef41Sopenharmony_ci    reason: 'no start line',
3061cb0ef41Sopenharmony_ci    library: 'PEM routines',
3071cb0ef41Sopenharmony_ci    function: 'get_name',
3081cb0ef41Sopenharmony_ci  });
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci  // This should not abort either: https://github.com/nodejs/node/issues/29904
3111cb0ef41Sopenharmony_ci  assert.throws(() => {
3121cb0ef41Sopenharmony_ci    createPrivateKey({ key: Buffer.alloc(0), format: 'der', type: 'spki' });
3131cb0ef41Sopenharmony_ci  }, {
3141cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
3151cb0ef41Sopenharmony_ci    message: "The property 'options.type' is invalid. Received 'spki'"
3161cb0ef41Sopenharmony_ci  });
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  // Unlike SPKI, PKCS#1 is a valid encoding for private keys (and public keys),
3191cb0ef41Sopenharmony_ci  // so it should be accepted by createPrivateKey, but OpenSSL won't parse it.
3201cb0ef41Sopenharmony_ci  assert.throws(() => {
3211cb0ef41Sopenharmony_ci    const key = createPublicKey(publicPem).export({
3221cb0ef41Sopenharmony_ci      format: 'der',
3231cb0ef41Sopenharmony_ci      type: 'pkcs1'
3241cb0ef41Sopenharmony_ci    });
3251cb0ef41Sopenharmony_ci    createPrivateKey({ key, format: 'der', type: 'pkcs1' });
3261cb0ef41Sopenharmony_ci  }, common.hasOpenSSL3 ? {
3271cb0ef41Sopenharmony_ci    message: /error:1E08010C:DECODER routines::unsupported/,
3281cb0ef41Sopenharmony_ci    library: 'DECODER routines'
3291cb0ef41Sopenharmony_ci  } : {
3301cb0ef41Sopenharmony_ci    message: /asn1 encoding/,
3311cb0ef41Sopenharmony_ci    library: 'asn1 encoding routines'
3321cb0ef41Sopenharmony_ci  });
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci[
3361cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ed25519_private.pem', 'ascii'),
3371cb0ef41Sopenharmony_ci    public: fixtures.readKey('ed25519_public.pem', 'ascii'),
3381cb0ef41Sopenharmony_ci    keyType: 'ed25519',
3391cb0ef41Sopenharmony_ci    jwk: {
3401cb0ef41Sopenharmony_ci      crv: 'Ed25519',
3411cb0ef41Sopenharmony_ci      x: 'K1wIouqnuiA04b3WrMa-xKIKIpfHetNZRv3h9fBf768',
3421cb0ef41Sopenharmony_ci      d: 'wVK6M3SMhQh3NK-7GRrSV-BVWQx1FO5pW8hhQeu_NdA',
3431cb0ef41Sopenharmony_ci      kty: 'OKP'
3441cb0ef41Sopenharmony_ci    } },
3451cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ed448_private.pem', 'ascii'),
3461cb0ef41Sopenharmony_ci    public: fixtures.readKey('ed448_public.pem', 'ascii'),
3471cb0ef41Sopenharmony_ci    keyType: 'ed448',
3481cb0ef41Sopenharmony_ci    jwk: {
3491cb0ef41Sopenharmony_ci      crv: 'Ed448',
3501cb0ef41Sopenharmony_ci      x: 'oX_ee5-jlcU53-BbGRsGIzly0V-SZtJ_oGXY0udf84q2hTW2RdstLktvwpkVJOoNb7o' +
3511cb0ef41Sopenharmony_ci         'Dgc2V5ZUA',
3521cb0ef41Sopenharmony_ci      d: '060Ke71sN0GpIc01nnGgMDkp0sFNQ09woVo4AM1ffax1-mjnakK0-p-S7-Xf859QewX' +
3531cb0ef41Sopenharmony_ci         'jcR9mxppY',
3541cb0ef41Sopenharmony_ci      kty: 'OKP'
3551cb0ef41Sopenharmony_ci    } },
3561cb0ef41Sopenharmony_ci  { private: fixtures.readKey('x25519_private.pem', 'ascii'),
3571cb0ef41Sopenharmony_ci    public: fixtures.readKey('x25519_public.pem', 'ascii'),
3581cb0ef41Sopenharmony_ci    keyType: 'x25519',
3591cb0ef41Sopenharmony_ci    jwk: {
3601cb0ef41Sopenharmony_ci      crv: 'X25519',
3611cb0ef41Sopenharmony_ci      x: 'aSb8Q-RndwfNnPeOYGYPDUN3uhAPnMLzXyfi-mqfhig',
3621cb0ef41Sopenharmony_ci      d: 'mL_IWm55RrALUGRfJYzw40gEYWMvtRkesP9mj8o8Omc',
3631cb0ef41Sopenharmony_ci      kty: 'OKP'
3641cb0ef41Sopenharmony_ci    } },
3651cb0ef41Sopenharmony_ci  { private: fixtures.readKey('x448_private.pem', 'ascii'),
3661cb0ef41Sopenharmony_ci    public: fixtures.readKey('x448_public.pem', 'ascii'),
3671cb0ef41Sopenharmony_ci    keyType: 'x448',
3681cb0ef41Sopenharmony_ci    jwk: {
3691cb0ef41Sopenharmony_ci      crv: 'X448',
3701cb0ef41Sopenharmony_ci      x: 'ioHSHVpTs6hMvghosEJDIR7ceFiE3-Xccxati64oOVJ7NWjfozE7ae31PXIUFq6cVYg' +
3711cb0ef41Sopenharmony_ci         'vSKsDFPA',
3721cb0ef41Sopenharmony_ci      d: 'tMNtrO_q8dlY6Y4NDeSTxNQ5CACkHiPvmukidPnNIuX_EkcryLEXt_7i6j6YZMKsrWy' +
3731cb0ef41Sopenharmony_ci         'S0jlSYJk',
3741cb0ef41Sopenharmony_ci      kty: 'OKP'
3751cb0ef41Sopenharmony_ci    } },
3761cb0ef41Sopenharmony_ci].forEach((info) => {
3771cb0ef41Sopenharmony_ci  const keyType = info.keyType;
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci  {
3801cb0ef41Sopenharmony_ci    const key = createPrivateKey(info.private);
3811cb0ef41Sopenharmony_ci    assert.strictEqual(key.type, 'private');
3821cb0ef41Sopenharmony_ci    assert.strictEqual(key.asymmetricKeyType, keyType);
3831cb0ef41Sopenharmony_ci    assert.strictEqual(key.symmetricKeySize, undefined);
3841cb0ef41Sopenharmony_ci    assert.strictEqual(
3851cb0ef41Sopenharmony_ci      key.export({ type: 'pkcs8', format: 'pem' }), info.private);
3861cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
3871cb0ef41Sopenharmony_ci      key.export({ format: 'jwk' }), info.jwk);
3881cb0ef41Sopenharmony_ci  }
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ci  {
3911cb0ef41Sopenharmony_ci    const key = createPrivateKey({ key: info.jwk, format: 'jwk' });
3921cb0ef41Sopenharmony_ci    assert.strictEqual(key.type, 'private');
3931cb0ef41Sopenharmony_ci    assert.strictEqual(key.asymmetricKeyType, keyType);
3941cb0ef41Sopenharmony_ci    assert.strictEqual(key.symmetricKeySize, undefined);
3951cb0ef41Sopenharmony_ci    assert.strictEqual(
3961cb0ef41Sopenharmony_ci      key.export({ type: 'pkcs8', format: 'pem' }), info.private);
3971cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
3981cb0ef41Sopenharmony_ci      key.export({ format: 'jwk' }), info.jwk);
3991cb0ef41Sopenharmony_ci  }
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ci  {
4021cb0ef41Sopenharmony_ci    for (const input of [
4031cb0ef41Sopenharmony_ci      info.private, info.public, { key: info.jwk, format: 'jwk' }]) {
4041cb0ef41Sopenharmony_ci      const key = createPublicKey(input);
4051cb0ef41Sopenharmony_ci      assert.strictEqual(key.type, 'public');
4061cb0ef41Sopenharmony_ci      assert.strictEqual(key.asymmetricKeyType, keyType);
4071cb0ef41Sopenharmony_ci      assert.strictEqual(key.symmetricKeySize, undefined);
4081cb0ef41Sopenharmony_ci      assert.strictEqual(
4091cb0ef41Sopenharmony_ci        key.export({ type: 'spki', format: 'pem' }), info.public);
4101cb0ef41Sopenharmony_ci      const jwk = { ...info.jwk };
4111cb0ef41Sopenharmony_ci      delete jwk.d;
4121cb0ef41Sopenharmony_ci      assert.deepStrictEqual(
4131cb0ef41Sopenharmony_ci        key.export({ format: 'jwk' }), jwk);
4141cb0ef41Sopenharmony_ci    }
4151cb0ef41Sopenharmony_ci  }
4161cb0ef41Sopenharmony_ci});
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci[
4191cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ec_p256_private.pem', 'ascii'),
4201cb0ef41Sopenharmony_ci    public: fixtures.readKey('ec_p256_public.pem', 'ascii'),
4211cb0ef41Sopenharmony_ci    keyType: 'ec',
4221cb0ef41Sopenharmony_ci    namedCurve: 'prime256v1',
4231cb0ef41Sopenharmony_ci    jwk: {
4241cb0ef41Sopenharmony_ci      crv: 'P-256',
4251cb0ef41Sopenharmony_ci      d: 'DxBsPQPIgMuMyQbxzbb9toew6Ev6e9O6ZhpxLNgmAEo',
4261cb0ef41Sopenharmony_ci      kty: 'EC',
4271cb0ef41Sopenharmony_ci      x: 'X0mMYR_uleZSIPjNztIkAS3_ud5LhNpbiIFp6fNf2Gs',
4281cb0ef41Sopenharmony_ci      y: 'UbJuPy2Xi0lW7UYTBxPK3yGgDu9EAKYIecjkHX5s2lI'
4291cb0ef41Sopenharmony_ci    } },
4301cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ec_secp256k1_private.pem', 'ascii'),
4311cb0ef41Sopenharmony_ci    public: fixtures.readKey('ec_secp256k1_public.pem', 'ascii'),
4321cb0ef41Sopenharmony_ci    keyType: 'ec',
4331cb0ef41Sopenharmony_ci    namedCurve: 'secp256k1',
4341cb0ef41Sopenharmony_ci    jwk: {
4351cb0ef41Sopenharmony_ci      crv: 'secp256k1',
4361cb0ef41Sopenharmony_ci      d: 'c34ocwTwpFa9NZZh3l88qXyrkoYSxvC0FEsU5v1v4IM',
4371cb0ef41Sopenharmony_ci      kty: 'EC',
4381cb0ef41Sopenharmony_ci      x: 'cOzhFSpWxhalCbWNdP2H_yUkdC81C9T2deDpfxK7owA',
4391cb0ef41Sopenharmony_ci      y: '-A3DAZTk9IPppN-f03JydgHaFvL1fAHaoXf4SX4NXyo'
4401cb0ef41Sopenharmony_ci    } },
4411cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ec_p384_private.pem', 'ascii'),
4421cb0ef41Sopenharmony_ci    public: fixtures.readKey('ec_p384_public.pem', 'ascii'),
4431cb0ef41Sopenharmony_ci    keyType: 'ec',
4441cb0ef41Sopenharmony_ci    namedCurve: 'secp384r1',
4451cb0ef41Sopenharmony_ci    jwk: {
4461cb0ef41Sopenharmony_ci      crv: 'P-384',
4471cb0ef41Sopenharmony_ci      d: 'dwfuHuAtTlMRn7ZBCBm_0grpc1D_4hPeNAgevgelljuC0--k_LDFosDgBlLLmZsi',
4481cb0ef41Sopenharmony_ci      kty: 'EC',
4491cb0ef41Sopenharmony_ci      x: 'hON3nzGJgv-08fdHpQxgRJFZzlK-GZDGa5f3KnvM31cvvjJmsj4UeOgIdy3rDAjV',
4501cb0ef41Sopenharmony_ci      y: 'fidHhtecNCGCfLqmrLjDena1NSzWzWH1u_oUdMKGo5XSabxzD7-8JZxjpc8sR9cl'
4511cb0ef41Sopenharmony_ci    } },
4521cb0ef41Sopenharmony_ci  { private: fixtures.readKey('ec_p521_private.pem', 'ascii'),
4531cb0ef41Sopenharmony_ci    public: fixtures.readKey('ec_p521_public.pem', 'ascii'),
4541cb0ef41Sopenharmony_ci    keyType: 'ec',
4551cb0ef41Sopenharmony_ci    namedCurve: 'secp521r1',
4561cb0ef41Sopenharmony_ci    jwk: {
4571cb0ef41Sopenharmony_ci      crv: 'P-521',
4581cb0ef41Sopenharmony_ci      d: 'ABIIbmn3Gm_Y11uIDkC3g2ijpRxIrJEBY4i_JJYo5OougzTl3BX2ifRluPJMaaHcNer' +
4591cb0ef41Sopenharmony_ci         'bQH_WdVkLLX86ShlHrRyJ',
4601cb0ef41Sopenharmony_ci      kty: 'EC',
4611cb0ef41Sopenharmony_ci      x: 'AaLFgjwZtznM3N7qsfb86awVXe6c6djUYOob1FN-kllekv0KEXV0bwcDjPGQz5f6MxL' +
4621cb0ef41Sopenharmony_ci         'CbhMeHRavUS6P10rsTtBn',
4631cb0ef41Sopenharmony_ci      y: 'Ad3flexBeAfXceNzRBH128kFbOWD6W41NjwKRqqIF26vmgW_8COldGKZjFkOSEASxPB' +
4641cb0ef41Sopenharmony_ci         'cvA2iFJRUyQ3whC00j0Np'
4651cb0ef41Sopenharmony_ci    } },
4661cb0ef41Sopenharmony_ci].forEach((info) => {
4671cb0ef41Sopenharmony_ci  const { keyType, namedCurve } = info;
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  {
4701cb0ef41Sopenharmony_ci    const key = createPrivateKey(info.private);
4711cb0ef41Sopenharmony_ci    assert.strictEqual(key.type, 'private');
4721cb0ef41Sopenharmony_ci    assert.strictEqual(key.asymmetricKeyType, keyType);
4731cb0ef41Sopenharmony_ci    assert.deepStrictEqual(key.asymmetricKeyDetails, { namedCurve });
4741cb0ef41Sopenharmony_ci    assert.strictEqual(key.symmetricKeySize, undefined);
4751cb0ef41Sopenharmony_ci    assert.strictEqual(
4761cb0ef41Sopenharmony_ci      key.export({ type: 'pkcs8', format: 'pem' }), info.private);
4771cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
4781cb0ef41Sopenharmony_ci      key.export({ format: 'jwk' }), info.jwk);
4791cb0ef41Sopenharmony_ci  }
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ci  {
4821cb0ef41Sopenharmony_ci    const key = createPrivateKey({ key: info.jwk, format: 'jwk' });
4831cb0ef41Sopenharmony_ci    assert.strictEqual(key.type, 'private');
4841cb0ef41Sopenharmony_ci    assert.strictEqual(key.asymmetricKeyType, keyType);
4851cb0ef41Sopenharmony_ci    assert.deepStrictEqual(key.asymmetricKeyDetails, { namedCurve });
4861cb0ef41Sopenharmony_ci    assert.strictEqual(key.symmetricKeySize, undefined);
4871cb0ef41Sopenharmony_ci    assert.strictEqual(
4881cb0ef41Sopenharmony_ci      key.export({ type: 'pkcs8', format: 'pem' }), info.private);
4891cb0ef41Sopenharmony_ci    assert.deepStrictEqual(
4901cb0ef41Sopenharmony_ci      key.export({ format: 'jwk' }), info.jwk);
4911cb0ef41Sopenharmony_ci  }
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  {
4941cb0ef41Sopenharmony_ci    for (const input of [
4951cb0ef41Sopenharmony_ci      info.private, info.public, { key: info.jwk, format: 'jwk' }]) {
4961cb0ef41Sopenharmony_ci      const key = createPublicKey(input);
4971cb0ef41Sopenharmony_ci      assert.strictEqual(key.type, 'public');
4981cb0ef41Sopenharmony_ci      assert.strictEqual(key.asymmetricKeyType, keyType);
4991cb0ef41Sopenharmony_ci      assert.deepStrictEqual(key.asymmetricKeyDetails, { namedCurve });
5001cb0ef41Sopenharmony_ci      assert.strictEqual(key.symmetricKeySize, undefined);
5011cb0ef41Sopenharmony_ci      assert.strictEqual(
5021cb0ef41Sopenharmony_ci        key.export({ type: 'spki', format: 'pem' }), info.public);
5031cb0ef41Sopenharmony_ci      const jwk = { ...info.jwk };
5041cb0ef41Sopenharmony_ci      delete jwk.d;
5051cb0ef41Sopenharmony_ci      assert.deepStrictEqual(
5061cb0ef41Sopenharmony_ci        key.export({ format: 'jwk' }), jwk);
5071cb0ef41Sopenharmony_ci    }
5081cb0ef41Sopenharmony_ci  }
5091cb0ef41Sopenharmony_ci});
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci{
5121cb0ef41Sopenharmony_ci  // Reading an encrypted key without a passphrase should fail.
5131cb0ef41Sopenharmony_ci  assert.throws(() => createPrivateKey(privateDsa), common.hasOpenSSL3 ? {
5141cb0ef41Sopenharmony_ci    name: 'Error',
5151cb0ef41Sopenharmony_ci    message: 'error:07880109:common libcrypto routines::interrupted or ' +
5161cb0ef41Sopenharmony_ci             'cancelled',
5171cb0ef41Sopenharmony_ci  } : {
5181cb0ef41Sopenharmony_ci    name: 'TypeError',
5191cb0ef41Sopenharmony_ci    code: 'ERR_MISSING_PASSPHRASE',
5201cb0ef41Sopenharmony_ci    message: 'Passphrase required for encrypted key'
5211cb0ef41Sopenharmony_ci  });
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  // Reading an encrypted key with a passphrase that exceeds OpenSSL's buffer
5241cb0ef41Sopenharmony_ci  // size limit should fail with an appropriate error code.
5251cb0ef41Sopenharmony_ci  assert.throws(() => createPrivateKey({
5261cb0ef41Sopenharmony_ci    key: privateDsa,
5271cb0ef41Sopenharmony_ci    format: 'pem',
5281cb0ef41Sopenharmony_ci    passphrase: Buffer.alloc(1025, 'a')
5291cb0ef41Sopenharmony_ci  }), common.hasOpenSSL3 ? { name: 'Error' } : {
5301cb0ef41Sopenharmony_ci    code: 'ERR_OSSL_PEM_BAD_PASSWORD_READ',
5311cb0ef41Sopenharmony_ci    name: 'Error'
5321cb0ef41Sopenharmony_ci  });
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci  // The buffer has a size of 1024 bytes, so this passphrase should be permitted
5351cb0ef41Sopenharmony_ci  // (but will fail decryption).
5361cb0ef41Sopenharmony_ci  assert.throws(() => createPrivateKey({
5371cb0ef41Sopenharmony_ci    key: privateDsa,
5381cb0ef41Sopenharmony_ci    format: 'pem',
5391cb0ef41Sopenharmony_ci    passphrase: Buffer.alloc(1024, 'a')
5401cb0ef41Sopenharmony_ci  }), {
5411cb0ef41Sopenharmony_ci    message: /bad decrypt/
5421cb0ef41Sopenharmony_ci  });
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci  const publicKey = createPublicKey(publicDsa);
5451cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.type, 'public');
5461cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.asymmetricKeyType, 'dsa');
5471cb0ef41Sopenharmony_ci  assert.strictEqual(publicKey.symmetricKeySize, undefined);
5481cb0ef41Sopenharmony_ci  assert.throws(
5491cb0ef41Sopenharmony_ci    () => publicKey.export({ format: 'jwk' }),
5501cb0ef41Sopenharmony_ci    { code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE' });
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci  const privateKey = createPrivateKey({
5531cb0ef41Sopenharmony_ci    key: privateDsa,
5541cb0ef41Sopenharmony_ci    format: 'pem',
5551cb0ef41Sopenharmony_ci    passphrase: 'secret'
5561cb0ef41Sopenharmony_ci  });
5571cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.type, 'private');
5581cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.asymmetricKeyType, 'dsa');
5591cb0ef41Sopenharmony_ci  assert.strictEqual(privateKey.symmetricKeySize, undefined);
5601cb0ef41Sopenharmony_ci  assert.throws(
5611cb0ef41Sopenharmony_ci    () => privateKey.export({ format: 'jwk' }),
5621cb0ef41Sopenharmony_ci    { code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE' });
5631cb0ef41Sopenharmony_ci}
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci{
5661cb0ef41Sopenharmony_ci  // Test RSA-PSS.
5671cb0ef41Sopenharmony_ci  {
5681cb0ef41Sopenharmony_ci    // This key pair does not restrict the message digest algorithm or salt
5691cb0ef41Sopenharmony_ci    // length.
5701cb0ef41Sopenharmony_ci    const publicPem = fixtures.readKey('rsa_pss_public_2048.pem');
5711cb0ef41Sopenharmony_ci    const privatePem = fixtures.readKey('rsa_pss_private_2048.pem');
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci    const publicKey = createPublicKey(publicPem);
5741cb0ef41Sopenharmony_ci    const privateKey = createPrivateKey(privatePem);
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci    // Because no RSASSA-PSS-params appears in the PEM, no defaults should be
5771cb0ef41Sopenharmony_ci    // added for the PSS parameters. This is different from an empty
5781cb0ef41Sopenharmony_ci    // RSASSA-PSS-params sequence (see test below).
5791cb0ef41Sopenharmony_ci    const expectedKeyDetails = {
5801cb0ef41Sopenharmony_ci      modulusLength: 2048,
5811cb0ef41Sopenharmony_ci      publicExponent: 65537n
5821cb0ef41Sopenharmony_ci    };
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.type, 'public');
5851cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
5861cb0ef41Sopenharmony_ci    assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails);
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.type, 'private');
5891cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
5901cb0ef41Sopenharmony_ci    assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails);
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci    assert.throws(
5931cb0ef41Sopenharmony_ci      () => publicKey.export({ format: 'jwk' }),
5941cb0ef41Sopenharmony_ci      { code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE' });
5951cb0ef41Sopenharmony_ci    assert.throws(
5961cb0ef41Sopenharmony_ci      () => privateKey.export({ format: 'jwk' }),
5971cb0ef41Sopenharmony_ci      { code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE' });
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
6001cb0ef41Sopenharmony_ci      // Any algorithm should work.
6011cb0ef41Sopenharmony_ci      for (const algo of ['sha1', 'sha256']) {
6021cb0ef41Sopenharmony_ci        // Any salt length should work.
6031cb0ef41Sopenharmony_ci        for (const saltLength of [undefined, 8, 10, 12, 16, 18, 20]) {
6041cb0ef41Sopenharmony_ci          const signature = createSign(algo)
6051cb0ef41Sopenharmony_ci                            .update('foo')
6061cb0ef41Sopenharmony_ci                            .sign({ key, saltLength });
6071cb0ef41Sopenharmony_ci
6081cb0ef41Sopenharmony_ci          for (const pkey of [key, publicKey, publicPem]) {
6091cb0ef41Sopenharmony_ci            const okay = createVerify(algo)
6101cb0ef41Sopenharmony_ci                         .update('foo')
6111cb0ef41Sopenharmony_ci                         .verify({ key: pkey, saltLength }, signature);
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci            assert.ok(okay);
6141cb0ef41Sopenharmony_ci          }
6151cb0ef41Sopenharmony_ci        }
6161cb0ef41Sopenharmony_ci      }
6171cb0ef41Sopenharmony_ci    }
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci    // Exporting the key using PKCS#1 should not work since this would discard
6201cb0ef41Sopenharmony_ci    // any algorithm restrictions.
6211cb0ef41Sopenharmony_ci    assert.throws(() => {
6221cb0ef41Sopenharmony_ci      publicKey.export({ format: 'pem', type: 'pkcs1' });
6231cb0ef41Sopenharmony_ci    }, {
6241cb0ef41Sopenharmony_ci      code: 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS'
6251cb0ef41Sopenharmony_ci    });
6261cb0ef41Sopenharmony_ci  }
6271cb0ef41Sopenharmony_ci
6281cb0ef41Sopenharmony_ci  {
6291cb0ef41Sopenharmony_ci    // This key pair enforces sha1 as the message digest and the MGF1
6301cb0ef41Sopenharmony_ci    // message digest and a salt length of 20 bytes.
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci    const publicPem = fixtures.readKey('rsa_pss_public_2048_sha1_sha1_20.pem');
6331cb0ef41Sopenharmony_ci    const privatePem =
6341cb0ef41Sopenharmony_ci        fixtures.readKey('rsa_pss_private_2048_sha1_sha1_20.pem');
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci    const publicKey = createPublicKey(publicPem);
6371cb0ef41Sopenharmony_ci    const privateKey = createPrivateKey(privatePem);
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci    // Unlike the previous key pair, this key pair contains an RSASSA-PSS-params
6401cb0ef41Sopenharmony_ci    // sequence. However, because all values in the RSASSA-PSS-params are set to
6411cb0ef41Sopenharmony_ci    // their defaults (see RFC 3447), the ASN.1 structure contains an empty
6421cb0ef41Sopenharmony_ci    // sequence. Node.js should add the default values to the key details.
6431cb0ef41Sopenharmony_ci    const expectedKeyDetails = {
6441cb0ef41Sopenharmony_ci      modulusLength: 2048,
6451cb0ef41Sopenharmony_ci      publicExponent: 65537n,
6461cb0ef41Sopenharmony_ci      hashAlgorithm: 'sha1',
6471cb0ef41Sopenharmony_ci      mgf1HashAlgorithm: 'sha1',
6481cb0ef41Sopenharmony_ci      saltLength: 20
6491cb0ef41Sopenharmony_ci    };
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.type, 'public');
6521cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
6531cb0ef41Sopenharmony_ci    assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails);
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.type, 'private');
6561cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
6571cb0ef41Sopenharmony_ci    assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails);
6581cb0ef41Sopenharmony_ci  }
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci  {
6611cb0ef41Sopenharmony_ci    // This key pair enforces sha256 as the message digest and the MGF1
6621cb0ef41Sopenharmony_ci    // message digest and a salt length of at least 16 bytes.
6631cb0ef41Sopenharmony_ci    const publicPem =
6641cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_public_2048_sha256_sha256_16.pem');
6651cb0ef41Sopenharmony_ci    const privatePem =
6661cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_private_2048_sha256_sha256_16.pem');
6671cb0ef41Sopenharmony_ci
6681cb0ef41Sopenharmony_ci    const publicKey = createPublicKey(publicPem);
6691cb0ef41Sopenharmony_ci    const privateKey = createPrivateKey(privatePem);
6701cb0ef41Sopenharmony_ci
6711cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.type, 'public');
6721cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
6731cb0ef41Sopenharmony_ci
6741cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.type, 'private');
6751cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
6781cb0ef41Sopenharmony_ci      // Signing with anything other than sha256 should fail.
6791cb0ef41Sopenharmony_ci      assert.throws(() => {
6801cb0ef41Sopenharmony_ci        createSign('sha1').sign(key);
6811cb0ef41Sopenharmony_ci      }, /digest not allowed/);
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci      // Signing with salt lengths less than 16 bytes should fail.
6841cb0ef41Sopenharmony_ci      for (const saltLength of [8, 10, 12]) {
6851cb0ef41Sopenharmony_ci        assert.throws(() => {
6861cb0ef41Sopenharmony_ci          createSign('sha1').sign({ key, saltLength });
6871cb0ef41Sopenharmony_ci        }, /pss saltlen too small/);
6881cb0ef41Sopenharmony_ci      }
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ci      // Signing with sha256 and appropriate salt lengths should work.
6911cb0ef41Sopenharmony_ci      for (const saltLength of [undefined, 16, 18, 20]) {
6921cb0ef41Sopenharmony_ci        const signature = createSign('sha256')
6931cb0ef41Sopenharmony_ci                          .update('foo')
6941cb0ef41Sopenharmony_ci                          .sign({ key, saltLength });
6951cb0ef41Sopenharmony_ci
6961cb0ef41Sopenharmony_ci        for (const pkey of [key, publicKey, publicPem]) {
6971cb0ef41Sopenharmony_ci          const okay = createVerify('sha256')
6981cb0ef41Sopenharmony_ci                       .update('foo')
6991cb0ef41Sopenharmony_ci                       .verify({ key: pkey, saltLength }, signature);
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci          assert.ok(okay);
7021cb0ef41Sopenharmony_ci        }
7031cb0ef41Sopenharmony_ci      }
7041cb0ef41Sopenharmony_ci    }
7051cb0ef41Sopenharmony_ci  }
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci  {
7081cb0ef41Sopenharmony_ci    // This key enforces sha512 as the message digest and sha256 as the MGF1
7091cb0ef41Sopenharmony_ci    // message digest.
7101cb0ef41Sopenharmony_ci    const publicPem =
7111cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_public_2048_sha512_sha256_20.pem');
7121cb0ef41Sopenharmony_ci    const privatePem =
7131cb0ef41Sopenharmony_ci      fixtures.readKey('rsa_pss_private_2048_sha512_sha256_20.pem');
7141cb0ef41Sopenharmony_ci
7151cb0ef41Sopenharmony_ci    const publicKey = createPublicKey(publicPem);
7161cb0ef41Sopenharmony_ci    const privateKey = createPrivateKey(privatePem);
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci    const expectedKeyDetails = {
7191cb0ef41Sopenharmony_ci      modulusLength: 2048,
7201cb0ef41Sopenharmony_ci      publicExponent: 65537n,
7211cb0ef41Sopenharmony_ci      hashAlgorithm: 'sha512',
7221cb0ef41Sopenharmony_ci      mgf1HashAlgorithm: 'sha256',
7231cb0ef41Sopenharmony_ci      saltLength: 20
7241cb0ef41Sopenharmony_ci    };
7251cb0ef41Sopenharmony_ci
7261cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.type, 'public');
7271cb0ef41Sopenharmony_ci    assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss');
7281cb0ef41Sopenharmony_ci    assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails);
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.type, 'private');
7311cb0ef41Sopenharmony_ci    assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss');
7321cb0ef41Sopenharmony_ci    assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails);
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ci    // Node.js usually uses the same hash function for the message and for MGF1.
7351cb0ef41Sopenharmony_ci    // However, when a different MGF1 message digest algorithm has been
7361cb0ef41Sopenharmony_ci    // specified as part of the key, it should automatically switch to that.
7371cb0ef41Sopenharmony_ci    // This behavior is required by sections 3.1 and 3.3 of RFC4055.
7381cb0ef41Sopenharmony_ci    for (const key of [privatePem, privateKey]) {
7391cb0ef41Sopenharmony_ci      // sha256 matches the MGF1 hash function and should be used internally,
7401cb0ef41Sopenharmony_ci      // but it should not be permitted as the main message digest algorithm.
7411cb0ef41Sopenharmony_ci      for (const algo of ['sha1', 'sha256']) {
7421cb0ef41Sopenharmony_ci        assert.throws(() => {
7431cb0ef41Sopenharmony_ci          createSign(algo).sign(key);
7441cb0ef41Sopenharmony_ci        }, /digest not allowed/);
7451cb0ef41Sopenharmony_ci      }
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci      // sha512 should produce a valid signature.
7481cb0ef41Sopenharmony_ci      const signature = createSign('sha512')
7491cb0ef41Sopenharmony_ci                        .update('foo')
7501cb0ef41Sopenharmony_ci                        .sign(key);
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci      for (const pkey of [key, publicKey, publicPem]) {
7531cb0ef41Sopenharmony_ci        const okay = createVerify('sha512')
7541cb0ef41Sopenharmony_ci                     .update('foo')
7551cb0ef41Sopenharmony_ci                     .verify(pkey, signature);
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ci        assert.ok(okay);
7581cb0ef41Sopenharmony_ci      }
7591cb0ef41Sopenharmony_ci    }
7601cb0ef41Sopenharmony_ci  }
7611cb0ef41Sopenharmony_ci}
7621cb0ef41Sopenharmony_ci
7631cb0ef41Sopenharmony_ci{
7641cb0ef41Sopenharmony_ci  // Exporting an encrypted private key requires a cipher
7651cb0ef41Sopenharmony_ci  const privateKey = createPrivateKey(privatePem);
7661cb0ef41Sopenharmony_ci  assert.throws(() => {
7671cb0ef41Sopenharmony_ci    privateKey.export({
7681cb0ef41Sopenharmony_ci      format: 'pem', type: 'pkcs8', passphrase: 'super-secret'
7691cb0ef41Sopenharmony_ci    });
7701cb0ef41Sopenharmony_ci  }, {
7711cb0ef41Sopenharmony_ci    name: 'TypeError',
7721cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_VALUE',
7731cb0ef41Sopenharmony_ci    message: "The property 'options.cipher' is invalid. Received undefined"
7741cb0ef41Sopenharmony_ci  });
7751cb0ef41Sopenharmony_ci}
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci{
7781cb0ef41Sopenharmony_ci  // SecretKeyObject export buffer format (default)
7791cb0ef41Sopenharmony_ci  const buffer = Buffer.from('Hello World');
7801cb0ef41Sopenharmony_ci  const keyObject = createSecretKey(buffer);
7811cb0ef41Sopenharmony_ci  assert.deepStrictEqual(keyObject.export(), buffer);
7821cb0ef41Sopenharmony_ci  assert.deepStrictEqual(keyObject.export({}), buffer);
7831cb0ef41Sopenharmony_ci  assert.deepStrictEqual(keyObject.export({ format: 'buffer' }), buffer);
7841cb0ef41Sopenharmony_ci  assert.deepStrictEqual(keyObject.export({ format: undefined }), buffer);
7851cb0ef41Sopenharmony_ci}
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci{
7881cb0ef41Sopenharmony_ci  // Exporting an "oct" JWK from a SecretKeyObject
7891cb0ef41Sopenharmony_ci  const buffer = Buffer.from('Hello World');
7901cb0ef41Sopenharmony_ci  const keyObject = createSecretKey(buffer);
7911cb0ef41Sopenharmony_ci  assert.deepStrictEqual(
7921cb0ef41Sopenharmony_ci    keyObject.export({ format: 'jwk' }),
7931cb0ef41Sopenharmony_ci    { kty: 'oct', k: 'SGVsbG8gV29ybGQ' }
7941cb0ef41Sopenharmony_ci  );
7951cb0ef41Sopenharmony_ci}
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci{
7981cb0ef41Sopenharmony_ci  // Exporting a JWK unsupported curve EC key
7991cb0ef41Sopenharmony_ci  const supported = ['prime256v1', 'secp256k1', 'secp384r1', 'secp521r1'];
8001cb0ef41Sopenharmony_ci  // Find an unsupported curve regardless of whether a FIPS compliant crypto
8011cb0ef41Sopenharmony_ci  // provider is currently in use.
8021cb0ef41Sopenharmony_ci  const namedCurve = getCurves().find((curve) => !supported.includes(curve));
8031cb0ef41Sopenharmony_ci  assert(namedCurve);
8041cb0ef41Sopenharmony_ci  const keyPair = generateKeyPairSync('ec', { namedCurve });
8051cb0ef41Sopenharmony_ci  const { publicKey, privateKey } = keyPair;
8061cb0ef41Sopenharmony_ci  assert.throws(
8071cb0ef41Sopenharmony_ci    () => publicKey.export({ format: 'jwk' }),
8081cb0ef41Sopenharmony_ci    {
8091cb0ef41Sopenharmony_ci      code: 'ERR_CRYPTO_JWK_UNSUPPORTED_CURVE',
8101cb0ef41Sopenharmony_ci      message: `Unsupported JWK EC curve: ${namedCurve}.`
8111cb0ef41Sopenharmony_ci    });
8121cb0ef41Sopenharmony_ci  assert.throws(
8131cb0ef41Sopenharmony_ci    () => privateKey.export({ format: 'jwk' }),
8141cb0ef41Sopenharmony_ci    {
8151cb0ef41Sopenharmony_ci      code: 'ERR_CRYPTO_JWK_UNSUPPORTED_CURVE',
8161cb0ef41Sopenharmony_ci      message: `Unsupported JWK EC curve: ${namedCurve}.`
8171cb0ef41Sopenharmony_ci    });
8181cb0ef41Sopenharmony_ci}
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ci{
8211cb0ef41Sopenharmony_ci  const first = Buffer.from('Hello');
8221cb0ef41Sopenharmony_ci  const second = Buffer.from('World');
8231cb0ef41Sopenharmony_ci  const keyObject = createSecretKey(first);
8241cb0ef41Sopenharmony_ci  assert(createSecretKey(first).equals(createSecretKey(first)));
8251cb0ef41Sopenharmony_ci  assert(!createSecretKey(first).equals(createSecretKey(second)));
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci  assert.throws(() => keyObject.equals(0), {
8281cb0ef41Sopenharmony_ci    name: 'TypeError',
8291cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
8301cb0ef41Sopenharmony_ci    message: 'The "otherKeyObject" argument must be an instance of KeyObject. Received type number (0)'
8311cb0ef41Sopenharmony_ci  });
8321cb0ef41Sopenharmony_ci
8331cb0ef41Sopenharmony_ci  assert(keyObject.equals(keyObject));
8341cb0ef41Sopenharmony_ci  assert(!keyObject.equals(createPublicKey(publicPem)));
8351cb0ef41Sopenharmony_ci  assert(!keyObject.equals(createPrivateKey(privatePem)));
8361cb0ef41Sopenharmony_ci}
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci{
8391cb0ef41Sopenharmony_ci  const first = generateKeyPairSync('ed25519');
8401cb0ef41Sopenharmony_ci  const second = generateKeyPairSync('ed25519');
8411cb0ef41Sopenharmony_ci  const secret = generateKeySync('aes', { length: 128 });
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ci  assert(first.publicKey.equals(first.publicKey));
8441cb0ef41Sopenharmony_ci  assert(first.publicKey.equals(createPublicKey(
8451cb0ef41Sopenharmony_ci    first.publicKey.export({ format: 'pem', type: 'spki' }))));
8461cb0ef41Sopenharmony_ci  assert(!first.publicKey.equals(second.publicKey));
8471cb0ef41Sopenharmony_ci  assert(!first.publicKey.equals(second.privateKey));
8481cb0ef41Sopenharmony_ci  assert(!first.publicKey.equals(secret));
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  assert(first.privateKey.equals(first.privateKey));
8511cb0ef41Sopenharmony_ci  assert(first.privateKey.equals(createPrivateKey(
8521cb0ef41Sopenharmony_ci    first.privateKey.export({ format: 'pem', type: 'pkcs8' }))));
8531cb0ef41Sopenharmony_ci  assert(!first.privateKey.equals(second.privateKey));
8541cb0ef41Sopenharmony_ci  assert(!first.privateKey.equals(second.publicKey));
8551cb0ef41Sopenharmony_ci  assert(!first.privateKey.equals(secret));
8561cb0ef41Sopenharmony_ci}
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci{
8591cb0ef41Sopenharmony_ci  const first = generateKeyPairSync('ed25519');
8601cb0ef41Sopenharmony_ci  const second = generateKeyPairSync('ed448');
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci  assert(!first.publicKey.equals(second.publicKey));
8631cb0ef41Sopenharmony_ci  assert(!first.publicKey.equals(second.privateKey));
8641cb0ef41Sopenharmony_ci  assert(!first.privateKey.equals(second.privateKey));
8651cb0ef41Sopenharmony_ci  assert(!first.privateKey.equals(second.publicKey));
8661cb0ef41Sopenharmony_ci}
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_ci{
8691cb0ef41Sopenharmony_ci  const first = createSecretKey(Buffer.alloc(0));
8701cb0ef41Sopenharmony_ci  const second = createSecretKey(new ArrayBuffer(0));
8711cb0ef41Sopenharmony_ci  const third = createSecretKey(Buffer.alloc(1));
8721cb0ef41Sopenharmony_ci  assert(first.equals(first));
8731cb0ef41Sopenharmony_ci  assert(first.equals(second));
8741cb0ef41Sopenharmony_ci  assert(!first.equals(third));
8751cb0ef41Sopenharmony_ci  assert(!third.equals(first));
8761cb0ef41Sopenharmony_ci}
8771cb0ef41Sopenharmony_ci
8781cb0ef41Sopenharmony_ci{
8791cb0ef41Sopenharmony_ci  // This should not cause a crash: https://github.com/nodejs/node/issues/44471
8801cb0ef41Sopenharmony_ci  for (const key of ['', 'foo', null, undefined, true, Boolean]) {
8811cb0ef41Sopenharmony_ci    assert.throws(() => {
8821cb0ef41Sopenharmony_ci      createPublicKey({ key, format: 'jwk' });
8831cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
8841cb0ef41Sopenharmony_ci    assert.throws(() => {
8851cb0ef41Sopenharmony_ci      createPrivateKey({ key, format: 'jwk' });
8861cb0ef41Sopenharmony_ci    }, { code: 'ERR_INVALID_ARG_TYPE', message: /The "key\.key" property must be of type object/ });
8871cb0ef41Sopenharmony_ci  }
8881cb0ef41Sopenharmony_ci}
889