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