11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayFrom, 51cb0ef41Sopenharmony_ci ArrayPrototypeSlice, 61cb0ef41Sopenharmony_ci ObjectDefineProperty, 71cb0ef41Sopenharmony_ci ObjectDefineProperties, 81cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 91cb0ef41Sopenharmony_ci Symbol, 101cb0ef41Sopenharmony_ci SymbolToStringTag, 111cb0ef41Sopenharmony_ci Uint8Array, 121cb0ef41Sopenharmony_ci} = primordials; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst { 151cb0ef41Sopenharmony_ci KeyObjectHandle, 161cb0ef41Sopenharmony_ci createNativeKeyObjectClass, 171cb0ef41Sopenharmony_ci kKeyTypeSecret, 181cb0ef41Sopenharmony_ci kKeyTypePublic, 191cb0ef41Sopenharmony_ci kKeyTypePrivate, 201cb0ef41Sopenharmony_ci kKeyFormatPEM, 211cb0ef41Sopenharmony_ci kKeyFormatDER, 221cb0ef41Sopenharmony_ci kKeyFormatJWK, 231cb0ef41Sopenharmony_ci kKeyEncodingPKCS1, 241cb0ef41Sopenharmony_ci kKeyEncodingPKCS8, 251cb0ef41Sopenharmony_ci kKeyEncodingSPKI, 261cb0ef41Sopenharmony_ci kKeyEncodingSEC1, 271cb0ef41Sopenharmony_ci} = internalBinding('crypto'); 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciconst { 301cb0ef41Sopenharmony_ci validateObject, 311cb0ef41Sopenharmony_ci validateOneOf, 321cb0ef41Sopenharmony_ci validateString, 331cb0ef41Sopenharmony_ci} = require('internal/validators'); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciconst { 361cb0ef41Sopenharmony_ci codes: { 371cb0ef41Sopenharmony_ci ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, 381cb0ef41Sopenharmony_ci ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, 391cb0ef41Sopenharmony_ci ERR_CRYPTO_INVALID_JWK, 401cb0ef41Sopenharmony_ci ERR_ILLEGAL_CONSTRUCTOR, 411cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 421cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 431cb0ef41Sopenharmony_ci ERR_INVALID_THIS, 441cb0ef41Sopenharmony_ci }, 451cb0ef41Sopenharmony_ci} = require('internal/errors'); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciconst { 481cb0ef41Sopenharmony_ci kHandle, 491cb0ef41Sopenharmony_ci kKeyObject, 501cb0ef41Sopenharmony_ci getArrayBufferOrView, 511cb0ef41Sopenharmony_ci bigIntArrayToUnsignedBigInt, 521cb0ef41Sopenharmony_ci} = require('internal/crypto/util'); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ciconst { 551cb0ef41Sopenharmony_ci isAnyArrayBuffer, 561cb0ef41Sopenharmony_ci isArrayBufferView, 571cb0ef41Sopenharmony_ci} = require('internal/util/types'); 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciconst { 601cb0ef41Sopenharmony_ci makeTransferable, 611cb0ef41Sopenharmony_ci kClone, 621cb0ef41Sopenharmony_ci kDeserialize, 631cb0ef41Sopenharmony_ci} = require('internal/worker/js_transferable'); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ciconst { 661cb0ef41Sopenharmony_ci customInspectSymbol: kInspect, 671cb0ef41Sopenharmony_ci kEnumerableProperty, 681cb0ef41Sopenharmony_ci} = require('internal/util'); 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciconst { inspect } = require('internal/util/inspect'); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ciconst kAlgorithm = Symbol('kAlgorithm'); 751cb0ef41Sopenharmony_ciconst kExtractable = Symbol('kExtractable'); 761cb0ef41Sopenharmony_ciconst kKeyType = Symbol('kKeyType'); 771cb0ef41Sopenharmony_ciconst kKeyUsages = Symbol('kKeyUsages'); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci// Key input contexts. 801cb0ef41Sopenharmony_ciconst kConsumePublic = 0; 811cb0ef41Sopenharmony_ciconst kConsumePrivate = 1; 821cb0ef41Sopenharmony_ciconst kCreatePublic = 2; 831cb0ef41Sopenharmony_ciconst kCreatePrivate = 3; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ciconst encodingNames = []; 861cb0ef41Sopenharmony_cifor (const m of [[kKeyEncodingPKCS1, 'pkcs1'], [kKeyEncodingPKCS8, 'pkcs8'], 871cb0ef41Sopenharmony_ci [kKeyEncodingSPKI, 'spki'], [kKeyEncodingSEC1, 'sec1']]) 881cb0ef41Sopenharmony_ci encodingNames[m[0]] = m[1]; 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci// Creating the KeyObject class is a little complicated due to inheritance 911cb0ef41Sopenharmony_ci// and the fact that KeyObjects should be transferrable between threads, 921cb0ef41Sopenharmony_ci// which requires the KeyObject base class to be implemented in C++. 931cb0ef41Sopenharmony_ci// The creation requires a callback to make sure that the NativeKeyObject 941cb0ef41Sopenharmony_ci// base class cannot exist without the other KeyObject implementations. 951cb0ef41Sopenharmony_ciconst { 961cb0ef41Sopenharmony_ci 0: KeyObject, 971cb0ef41Sopenharmony_ci 1: SecretKeyObject, 981cb0ef41Sopenharmony_ci 2: PublicKeyObject, 991cb0ef41Sopenharmony_ci 3: PrivateKeyObject, 1001cb0ef41Sopenharmony_ci} = createNativeKeyObjectClass((NativeKeyObject) => { 1011cb0ef41Sopenharmony_ci // Publicly visible KeyObject class. 1021cb0ef41Sopenharmony_ci class KeyObject extends NativeKeyObject { 1031cb0ef41Sopenharmony_ci constructor(type, handle) { 1041cb0ef41Sopenharmony_ci if (type !== 'secret' && type !== 'public' && type !== 'private') 1051cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('type', type); 1061cb0ef41Sopenharmony_ci if (typeof handle !== 'object' || !(handle instanceof KeyObjectHandle)) 1071cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('handle', 'object', handle); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci super(handle); 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci this[kKeyType] = type; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci ObjectDefineProperty(this, kHandle, { 1141cb0ef41Sopenharmony_ci __proto__: null, 1151cb0ef41Sopenharmony_ci value: handle, 1161cb0ef41Sopenharmony_ci enumerable: false, 1171cb0ef41Sopenharmony_ci configurable: false, 1181cb0ef41Sopenharmony_ci writable: false, 1191cb0ef41Sopenharmony_ci }); 1201cb0ef41Sopenharmony_ci } 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci get type() { 1231cb0ef41Sopenharmony_ci return this[kKeyType]; 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci static from(key) { 1271cb0ef41Sopenharmony_ci if (!isCryptoKey(key)) 1281cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('key', 'CryptoKey', key); 1291cb0ef41Sopenharmony_ci return key[kKeyObject]; 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci equals(otherKeyObject) { 1331cb0ef41Sopenharmony_ci if (!isKeyObject(otherKeyObject)) { 1341cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 1351cb0ef41Sopenharmony_ci 'otherKeyObject', 'KeyObject', otherKeyObject); 1361cb0ef41Sopenharmony_ci } 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci return otherKeyObject.type === this.type && 1391cb0ef41Sopenharmony_ci this[kHandle].equals(otherKeyObject[kHandle]); 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci ObjectDefineProperties(KeyObject.prototype, { 1441cb0ef41Sopenharmony_ci [SymbolToStringTag]: { 1451cb0ef41Sopenharmony_ci __proto__: null, 1461cb0ef41Sopenharmony_ci configurable: true, 1471cb0ef41Sopenharmony_ci value: 'KeyObject', 1481cb0ef41Sopenharmony_ci }, 1491cb0ef41Sopenharmony_ci }); 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci class SecretKeyObject extends KeyObject { 1521cb0ef41Sopenharmony_ci constructor(handle) { 1531cb0ef41Sopenharmony_ci super('secret', handle); 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci get symmetricKeySize() { 1571cb0ef41Sopenharmony_ci return this[kHandle].getSymmetricKeySize(); 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci export(options) { 1611cb0ef41Sopenharmony_ci if (options !== undefined) { 1621cb0ef41Sopenharmony_ci validateObject(options, 'options'); 1631cb0ef41Sopenharmony_ci validateOneOf( 1641cb0ef41Sopenharmony_ci options.format, 'options.format', [undefined, 'buffer', 'jwk']); 1651cb0ef41Sopenharmony_ci if (options.format === 'jwk') { 1661cb0ef41Sopenharmony_ci return this[kHandle].exportJwk({}, false); 1671cb0ef41Sopenharmony_ci } 1681cb0ef41Sopenharmony_ci } 1691cb0ef41Sopenharmony_ci return this[kHandle].export(); 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci const kAsymmetricKeyType = Symbol('kAsymmetricKeyType'); 1741cb0ef41Sopenharmony_ci const kAsymmetricKeyDetails = Symbol('kAsymmetricKeyDetails'); 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci function normalizeKeyDetails(details = {}) { 1771cb0ef41Sopenharmony_ci if (details.publicExponent !== undefined) { 1781cb0ef41Sopenharmony_ci return { 1791cb0ef41Sopenharmony_ci ...details, 1801cb0ef41Sopenharmony_ci publicExponent: 1811cb0ef41Sopenharmony_ci bigIntArrayToUnsignedBigInt(new Uint8Array(details.publicExponent)), 1821cb0ef41Sopenharmony_ci }; 1831cb0ef41Sopenharmony_ci } 1841cb0ef41Sopenharmony_ci return details; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci class AsymmetricKeyObject extends KeyObject { 1881cb0ef41Sopenharmony_ci // eslint-disable-next-line no-useless-constructor 1891cb0ef41Sopenharmony_ci constructor(type, handle) { 1901cb0ef41Sopenharmony_ci super(type, handle); 1911cb0ef41Sopenharmony_ci } 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci get asymmetricKeyType() { 1941cb0ef41Sopenharmony_ci return this[kAsymmetricKeyType] || 1951cb0ef41Sopenharmony_ci (this[kAsymmetricKeyType] = this[kHandle].getAsymmetricKeyType()); 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci get asymmetricKeyDetails() { 1991cb0ef41Sopenharmony_ci switch (this.asymmetricKeyType) { 2001cb0ef41Sopenharmony_ci case 'rsa': 2011cb0ef41Sopenharmony_ci case 'rsa-pss': 2021cb0ef41Sopenharmony_ci case 'dsa': 2031cb0ef41Sopenharmony_ci case 'ec': 2041cb0ef41Sopenharmony_ci return this[kAsymmetricKeyDetails] || 2051cb0ef41Sopenharmony_ci (this[kAsymmetricKeyDetails] = normalizeKeyDetails( 2061cb0ef41Sopenharmony_ci this[kHandle].keyDetail({}), 2071cb0ef41Sopenharmony_ci )); 2081cb0ef41Sopenharmony_ci default: 2091cb0ef41Sopenharmony_ci return {}; 2101cb0ef41Sopenharmony_ci } 2111cb0ef41Sopenharmony_ci } 2121cb0ef41Sopenharmony_ci } 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci class PublicKeyObject extends AsymmetricKeyObject { 2151cb0ef41Sopenharmony_ci constructor(handle) { 2161cb0ef41Sopenharmony_ci super('public', handle); 2171cb0ef41Sopenharmony_ci } 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci export(options) { 2201cb0ef41Sopenharmony_ci if (options && options.format === 'jwk') { 2211cb0ef41Sopenharmony_ci return this[kHandle].exportJwk({}, false); 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci const { 2241cb0ef41Sopenharmony_ci format, 2251cb0ef41Sopenharmony_ci type, 2261cb0ef41Sopenharmony_ci } = parsePublicKeyEncoding(options, this.asymmetricKeyType); 2271cb0ef41Sopenharmony_ci return this[kHandle].export(format, type); 2281cb0ef41Sopenharmony_ci } 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci class PrivateKeyObject extends AsymmetricKeyObject { 2321cb0ef41Sopenharmony_ci constructor(handle) { 2331cb0ef41Sopenharmony_ci super('private', handle); 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci export(options) { 2371cb0ef41Sopenharmony_ci if (options && options.format === 'jwk') { 2381cb0ef41Sopenharmony_ci if (options.passphrase !== undefined) { 2391cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS( 2401cb0ef41Sopenharmony_ci 'jwk', 'does not support encryption'); 2411cb0ef41Sopenharmony_ci } 2421cb0ef41Sopenharmony_ci return this[kHandle].exportJwk({}, false); 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci const { 2451cb0ef41Sopenharmony_ci format, 2461cb0ef41Sopenharmony_ci type, 2471cb0ef41Sopenharmony_ci cipher, 2481cb0ef41Sopenharmony_ci passphrase, 2491cb0ef41Sopenharmony_ci } = parsePrivateKeyEncoding(options, this.asymmetricKeyType); 2501cb0ef41Sopenharmony_ci return this[kHandle].export(format, type, cipher, passphrase); 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci } 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci return [KeyObject, SecretKeyObject, PublicKeyObject, PrivateKeyObject]; 2551cb0ef41Sopenharmony_ci}); 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_cifunction parseKeyFormat(formatStr, defaultFormat, optionName) { 2581cb0ef41Sopenharmony_ci if (formatStr === undefined && defaultFormat !== undefined) 2591cb0ef41Sopenharmony_ci return defaultFormat; 2601cb0ef41Sopenharmony_ci else if (formatStr === 'pem') 2611cb0ef41Sopenharmony_ci return kKeyFormatPEM; 2621cb0ef41Sopenharmony_ci else if (formatStr === 'der') 2631cb0ef41Sopenharmony_ci return kKeyFormatDER; 2641cb0ef41Sopenharmony_ci else if (formatStr === 'jwk') 2651cb0ef41Sopenharmony_ci return kKeyFormatJWK; 2661cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(optionName, formatStr); 2671cb0ef41Sopenharmony_ci} 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_cifunction parseKeyType(typeStr, required, keyType, isPublic, optionName) { 2701cb0ef41Sopenharmony_ci if (typeStr === undefined && !required) { 2711cb0ef41Sopenharmony_ci return undefined; 2721cb0ef41Sopenharmony_ci } else if (typeStr === 'pkcs1') { 2731cb0ef41Sopenharmony_ci if (keyType !== undefined && keyType !== 'rsa') { 2741cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS( 2751cb0ef41Sopenharmony_ci typeStr, 'can only be used for RSA keys'); 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci return kKeyEncodingPKCS1; 2781cb0ef41Sopenharmony_ci } else if (typeStr === 'spki' && isPublic !== false) { 2791cb0ef41Sopenharmony_ci return kKeyEncodingSPKI; 2801cb0ef41Sopenharmony_ci } else if (typeStr === 'pkcs8' && isPublic !== true) { 2811cb0ef41Sopenharmony_ci return kKeyEncodingPKCS8; 2821cb0ef41Sopenharmony_ci } else if (typeStr === 'sec1' && isPublic !== true) { 2831cb0ef41Sopenharmony_ci if (keyType !== undefined && keyType !== 'ec') { 2841cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS( 2851cb0ef41Sopenharmony_ci typeStr, 'can only be used for EC keys'); 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci return kKeyEncodingSEC1; 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(optionName, typeStr); 2911cb0ef41Sopenharmony_ci} 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_cifunction option(name, objName) { 2941cb0ef41Sopenharmony_ci return objName === undefined ? 2951cb0ef41Sopenharmony_ci `options.${name}` : `options.${objName}.${name}`; 2961cb0ef41Sopenharmony_ci} 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_cifunction parseKeyFormatAndType(enc, keyType, isPublic, objName) { 2991cb0ef41Sopenharmony_ci const { format: formatStr, type: typeStr } = enc; 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci const isInput = keyType === undefined; 3021cb0ef41Sopenharmony_ci const format = parseKeyFormat(formatStr, 3031cb0ef41Sopenharmony_ci isInput ? kKeyFormatPEM : undefined, 3041cb0ef41Sopenharmony_ci option('format', objName)); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci const isRequired = (!isInput || 3071cb0ef41Sopenharmony_ci format === kKeyFormatDER) && 3081cb0ef41Sopenharmony_ci format !== kKeyFormatJWK; 3091cb0ef41Sopenharmony_ci const type = parseKeyType(typeStr, 3101cb0ef41Sopenharmony_ci isRequired, 3111cb0ef41Sopenharmony_ci keyType, 3121cb0ef41Sopenharmony_ci isPublic, 3131cb0ef41Sopenharmony_ci option('type', objName)); 3141cb0ef41Sopenharmony_ci return { format, type }; 3151cb0ef41Sopenharmony_ci} 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_cifunction isStringOrBuffer(val) { 3181cb0ef41Sopenharmony_ci return typeof val === 'string' || 3191cb0ef41Sopenharmony_ci isArrayBufferView(val) || 3201cb0ef41Sopenharmony_ci isAnyArrayBuffer(val); 3211cb0ef41Sopenharmony_ci} 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_cifunction parseKeyEncoding(enc, keyType, isPublic, objName) { 3241cb0ef41Sopenharmony_ci validateObject(enc, 'options'); 3251cb0ef41Sopenharmony_ci 3261cb0ef41Sopenharmony_ci const isInput = keyType === undefined; 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci const { 3291cb0ef41Sopenharmony_ci format, 3301cb0ef41Sopenharmony_ci type, 3311cb0ef41Sopenharmony_ci } = parseKeyFormatAndType(enc, keyType, isPublic, objName); 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci let cipher, passphrase, encoding; 3341cb0ef41Sopenharmony_ci if (isPublic !== true) { 3351cb0ef41Sopenharmony_ci ({ cipher, passphrase, encoding } = enc); 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci if (!isInput) { 3381cb0ef41Sopenharmony_ci if (cipher != null) { 3391cb0ef41Sopenharmony_ci if (typeof cipher !== 'string') 3401cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(option('cipher', objName), cipher); 3411cb0ef41Sopenharmony_ci if (format === kKeyFormatDER && 3421cb0ef41Sopenharmony_ci (type === kKeyEncodingPKCS1 || 3431cb0ef41Sopenharmony_ci type === kKeyEncodingSEC1)) { 3441cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS( 3451cb0ef41Sopenharmony_ci encodingNames[type], 'does not support encryption'); 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci } else if (passphrase !== undefined) { 3481cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(option('cipher', objName), cipher); 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci } 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci if ((isInput && passphrase !== undefined && 3531cb0ef41Sopenharmony_ci !isStringOrBuffer(passphrase)) || 3541cb0ef41Sopenharmony_ci (!isInput && cipher != null && !isStringOrBuffer(passphrase))) { 3551cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE(option('passphrase', objName), 3561cb0ef41Sopenharmony_ci passphrase); 3571cb0ef41Sopenharmony_ci } 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci if (passphrase !== undefined) 3611cb0ef41Sopenharmony_ci passphrase = getArrayBufferOrView(passphrase, 'key.passphrase', encoding); 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci return { format, type, cipher, passphrase }; 3641cb0ef41Sopenharmony_ci} 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci// Parses the public key encoding based on an object. keyType must be undefined 3671cb0ef41Sopenharmony_ci// when this is used to parse an input encoding and must be a valid key type if 3681cb0ef41Sopenharmony_ci// used to parse an output encoding. 3691cb0ef41Sopenharmony_cifunction parsePublicKeyEncoding(enc, keyType, objName) { 3701cb0ef41Sopenharmony_ci return parseKeyEncoding(enc, keyType, keyType ? true : undefined, objName); 3711cb0ef41Sopenharmony_ci} 3721cb0ef41Sopenharmony_ci 3731cb0ef41Sopenharmony_ci// Parses the private key encoding based on an object. keyType must be undefined 3741cb0ef41Sopenharmony_ci// when this is used to parse an input encoding and must be a valid key type if 3751cb0ef41Sopenharmony_ci// used to parse an output encoding. 3761cb0ef41Sopenharmony_cifunction parsePrivateKeyEncoding(enc, keyType, objName) { 3771cb0ef41Sopenharmony_ci return parseKeyEncoding(enc, keyType, false, objName); 3781cb0ef41Sopenharmony_ci} 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_cifunction getKeyObjectHandle(key, ctx) { 3811cb0ef41Sopenharmony_ci if (ctx === kCreatePrivate) { 3821cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 3831cb0ef41Sopenharmony_ci 'key', 3841cb0ef41Sopenharmony_ci ['string', 'ArrayBuffer', 'Buffer', 'TypedArray', 'DataView'], 3851cb0ef41Sopenharmony_ci key, 3861cb0ef41Sopenharmony_ci ); 3871cb0ef41Sopenharmony_ci } 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci if (key.type !== 'private') { 3901cb0ef41Sopenharmony_ci if (ctx === kConsumePrivate || ctx === kCreatePublic) 3911cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, 'private'); 3921cb0ef41Sopenharmony_ci if (key.type !== 'public') { 3931cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, 3941cb0ef41Sopenharmony_ci 'private or public'); 3951cb0ef41Sopenharmony_ci } 3961cb0ef41Sopenharmony_ci } 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci return key[kHandle]; 3991cb0ef41Sopenharmony_ci} 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_cifunction getKeyTypes(allowKeyObject, bufferOnly = false) { 4021cb0ef41Sopenharmony_ci const types = [ 4031cb0ef41Sopenharmony_ci 'ArrayBuffer', 4041cb0ef41Sopenharmony_ci 'Buffer', 4051cb0ef41Sopenharmony_ci 'TypedArray', 4061cb0ef41Sopenharmony_ci 'DataView', 4071cb0ef41Sopenharmony_ci 'string', // Only if bufferOnly == false 4081cb0ef41Sopenharmony_ci 'KeyObject', // Only if allowKeyObject == true && bufferOnly == false 4091cb0ef41Sopenharmony_ci 'CryptoKey', // Only if allowKeyObject == true && bufferOnly == false 4101cb0ef41Sopenharmony_ci ]; 4111cb0ef41Sopenharmony_ci if (bufferOnly) { 4121cb0ef41Sopenharmony_ci return ArrayPrototypeSlice(types, 0, 4); 4131cb0ef41Sopenharmony_ci } else if (!allowKeyObject) { 4141cb0ef41Sopenharmony_ci return ArrayPrototypeSlice(types, 0, 5); 4151cb0ef41Sopenharmony_ci } 4161cb0ef41Sopenharmony_ci return types; 4171cb0ef41Sopenharmony_ci} 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_cifunction getKeyObjectHandleFromJwk(key, ctx) { 4201cb0ef41Sopenharmony_ci validateObject(key, 'key'); 4211cb0ef41Sopenharmony_ci validateOneOf( 4221cb0ef41Sopenharmony_ci key.kty, 'key.kty', ['RSA', 'EC', 'OKP']); 4231cb0ef41Sopenharmony_ci const isPublic = ctx === kConsumePublic || ctx === kCreatePublic; 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_ci if (key.kty === 'OKP') { 4261cb0ef41Sopenharmony_ci validateString(key.crv, 'key.crv'); 4271cb0ef41Sopenharmony_ci validateOneOf( 4281cb0ef41Sopenharmony_ci key.crv, 'key.crv', ['Ed25519', 'Ed448', 'X25519', 'X448']); 4291cb0ef41Sopenharmony_ci validateString(key.x, 'key.x'); 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci if (!isPublic) 4321cb0ef41Sopenharmony_ci validateString(key.d, 'key.d'); 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci let keyData; 4351cb0ef41Sopenharmony_ci if (isPublic) 4361cb0ef41Sopenharmony_ci keyData = Buffer.from(key.x, 'base64'); 4371cb0ef41Sopenharmony_ci else 4381cb0ef41Sopenharmony_ci keyData = Buffer.from(key.d, 'base64'); 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci switch (key.crv) { 4411cb0ef41Sopenharmony_ci case 'Ed25519': 4421cb0ef41Sopenharmony_ci case 'X25519': 4431cb0ef41Sopenharmony_ci if (keyData.byteLength !== 32) { 4441cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 4451cb0ef41Sopenharmony_ci } 4461cb0ef41Sopenharmony_ci break; 4471cb0ef41Sopenharmony_ci case 'Ed448': 4481cb0ef41Sopenharmony_ci if (keyData.byteLength !== 57) { 4491cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 4501cb0ef41Sopenharmony_ci } 4511cb0ef41Sopenharmony_ci break; 4521cb0ef41Sopenharmony_ci case 'X448': 4531cb0ef41Sopenharmony_ci if (keyData.byteLength !== 56) { 4541cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 4551cb0ef41Sopenharmony_ci } 4561cb0ef41Sopenharmony_ci break; 4571cb0ef41Sopenharmony_ci } 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci const handle = new KeyObjectHandle(); 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci const keyType = isPublic ? kKeyTypePublic : kKeyTypePrivate; 4621cb0ef41Sopenharmony_ci if (!handle.initEDRaw(key.crv, keyData, keyType)) { 4631cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 4641cb0ef41Sopenharmony_ci } 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci return handle; 4671cb0ef41Sopenharmony_ci } 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci if (key.kty === 'EC') { 4701cb0ef41Sopenharmony_ci validateString(key.crv, 'key.crv'); 4711cb0ef41Sopenharmony_ci validateOneOf( 4721cb0ef41Sopenharmony_ci key.crv, 'key.crv', ['P-256', 'secp256k1', 'P-384', 'P-521']); 4731cb0ef41Sopenharmony_ci validateString(key.x, 'key.x'); 4741cb0ef41Sopenharmony_ci validateString(key.y, 'key.y'); 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci const jwk = { 4771cb0ef41Sopenharmony_ci kty: key.kty, 4781cb0ef41Sopenharmony_ci crv: key.crv, 4791cb0ef41Sopenharmony_ci x: key.x, 4801cb0ef41Sopenharmony_ci y: key.y, 4811cb0ef41Sopenharmony_ci }; 4821cb0ef41Sopenharmony_ci 4831cb0ef41Sopenharmony_ci if (!isPublic) { 4841cb0ef41Sopenharmony_ci validateString(key.d, 'key.d'); 4851cb0ef41Sopenharmony_ci jwk.d = key.d; 4861cb0ef41Sopenharmony_ci } 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ci const handle = new KeyObjectHandle(); 4891cb0ef41Sopenharmony_ci const type = handle.initJwk(jwk, jwk.crv); 4901cb0ef41Sopenharmony_ci if (type === undefined) 4911cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 4921cb0ef41Sopenharmony_ci 4931cb0ef41Sopenharmony_ci return handle; 4941cb0ef41Sopenharmony_ci } 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci // RSA 4971cb0ef41Sopenharmony_ci validateString(key.n, 'key.n'); 4981cb0ef41Sopenharmony_ci validateString(key.e, 'key.e'); 4991cb0ef41Sopenharmony_ci 5001cb0ef41Sopenharmony_ci const jwk = { 5011cb0ef41Sopenharmony_ci kty: key.kty, 5021cb0ef41Sopenharmony_ci n: key.n, 5031cb0ef41Sopenharmony_ci e: key.e, 5041cb0ef41Sopenharmony_ci }; 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci if (!isPublic) { 5071cb0ef41Sopenharmony_ci validateString(key.d, 'key.d'); 5081cb0ef41Sopenharmony_ci validateString(key.p, 'key.p'); 5091cb0ef41Sopenharmony_ci validateString(key.q, 'key.q'); 5101cb0ef41Sopenharmony_ci validateString(key.dp, 'key.dp'); 5111cb0ef41Sopenharmony_ci validateString(key.dq, 'key.dq'); 5121cb0ef41Sopenharmony_ci validateString(key.qi, 'key.qi'); 5131cb0ef41Sopenharmony_ci jwk.d = key.d; 5141cb0ef41Sopenharmony_ci jwk.p = key.p; 5151cb0ef41Sopenharmony_ci jwk.q = key.q; 5161cb0ef41Sopenharmony_ci jwk.dp = key.dp; 5171cb0ef41Sopenharmony_ci jwk.dq = key.dq; 5181cb0ef41Sopenharmony_ci jwk.qi = key.qi; 5191cb0ef41Sopenharmony_ci } 5201cb0ef41Sopenharmony_ci 5211cb0ef41Sopenharmony_ci const handle = new KeyObjectHandle(); 5221cb0ef41Sopenharmony_ci const type = handle.initJwk(jwk); 5231cb0ef41Sopenharmony_ci if (type === undefined) 5241cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_JWK(); 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_ci return handle; 5271cb0ef41Sopenharmony_ci} 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_cifunction prepareAsymmetricKey(key, ctx) { 5301cb0ef41Sopenharmony_ci if (isKeyObject(key)) { 5311cb0ef41Sopenharmony_ci // Best case: A key object, as simple as that. 5321cb0ef41Sopenharmony_ci return { data: getKeyObjectHandle(key, ctx) }; 5331cb0ef41Sopenharmony_ci } else if (isCryptoKey(key)) { 5341cb0ef41Sopenharmony_ci return { data: getKeyObjectHandle(key[kKeyObject], ctx) }; 5351cb0ef41Sopenharmony_ci } else if (isStringOrBuffer(key)) { 5361cb0ef41Sopenharmony_ci // Expect PEM by default, mostly for backward compatibility. 5371cb0ef41Sopenharmony_ci return { format: kKeyFormatPEM, data: getArrayBufferOrView(key, 'key') }; 5381cb0ef41Sopenharmony_ci } else if (typeof key === 'object') { 5391cb0ef41Sopenharmony_ci const { key: data, encoding, format } = key; 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ci // The 'key' property can be a KeyObject as well to allow specifying 5421cb0ef41Sopenharmony_ci // additional options such as padding along with the key. 5431cb0ef41Sopenharmony_ci if (isKeyObject(data)) 5441cb0ef41Sopenharmony_ci return { data: getKeyObjectHandle(data, ctx) }; 5451cb0ef41Sopenharmony_ci else if (isCryptoKey(data)) 5461cb0ef41Sopenharmony_ci return { data: getKeyObjectHandle(data[kKeyObject], ctx) }; 5471cb0ef41Sopenharmony_ci else if (format === 'jwk') { 5481cb0ef41Sopenharmony_ci validateObject(data, 'key.key'); 5491cb0ef41Sopenharmony_ci return { data: getKeyObjectHandleFromJwk(data, ctx), format: 'jwk' }; 5501cb0ef41Sopenharmony_ci } 5511cb0ef41Sopenharmony_ci 5521cb0ef41Sopenharmony_ci // Either PEM or DER using PKCS#1 or SPKI. 5531cb0ef41Sopenharmony_ci if (!isStringOrBuffer(data)) { 5541cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 5551cb0ef41Sopenharmony_ci 'key.key', 5561cb0ef41Sopenharmony_ci getKeyTypes(ctx !== kCreatePrivate), 5571cb0ef41Sopenharmony_ci data); 5581cb0ef41Sopenharmony_ci } 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci const isPublic = 5611cb0ef41Sopenharmony_ci (ctx === kConsumePrivate || ctx === kCreatePrivate) ? false : undefined; 5621cb0ef41Sopenharmony_ci return { 5631cb0ef41Sopenharmony_ci data: getArrayBufferOrView(data, 'key', encoding), 5641cb0ef41Sopenharmony_ci ...parseKeyEncoding(key, undefined, isPublic), 5651cb0ef41Sopenharmony_ci }; 5661cb0ef41Sopenharmony_ci } 5671cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 5681cb0ef41Sopenharmony_ci 'key', 5691cb0ef41Sopenharmony_ci getKeyTypes(ctx !== kCreatePrivate), 5701cb0ef41Sopenharmony_ci key); 5711cb0ef41Sopenharmony_ci} 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_cifunction preparePrivateKey(key) { 5741cb0ef41Sopenharmony_ci return prepareAsymmetricKey(key, kConsumePrivate); 5751cb0ef41Sopenharmony_ci} 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_cifunction preparePublicOrPrivateKey(key) { 5781cb0ef41Sopenharmony_ci return prepareAsymmetricKey(key, kConsumePublic); 5791cb0ef41Sopenharmony_ci} 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_cifunction prepareSecretKey(key, encoding, bufferOnly = false) { 5821cb0ef41Sopenharmony_ci if (!bufferOnly) { 5831cb0ef41Sopenharmony_ci if (isKeyObject(key)) { 5841cb0ef41Sopenharmony_ci if (key.type !== 'secret') 5851cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, 'secret'); 5861cb0ef41Sopenharmony_ci return key[kHandle]; 5871cb0ef41Sopenharmony_ci } else if (isCryptoKey(key)) { 5881cb0ef41Sopenharmony_ci if (key.type !== 'secret') 5891cb0ef41Sopenharmony_ci throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, 'secret'); 5901cb0ef41Sopenharmony_ci return key[kKeyObject][kHandle]; 5911cb0ef41Sopenharmony_ci } 5921cb0ef41Sopenharmony_ci } 5931cb0ef41Sopenharmony_ci if (typeof key !== 'string' && 5941cb0ef41Sopenharmony_ci !isArrayBufferView(key) && 5951cb0ef41Sopenharmony_ci !isAnyArrayBuffer(key)) { 5961cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 5971cb0ef41Sopenharmony_ci 'key', 5981cb0ef41Sopenharmony_ci getKeyTypes(!bufferOnly, bufferOnly), 5991cb0ef41Sopenharmony_ci key); 6001cb0ef41Sopenharmony_ci } 6011cb0ef41Sopenharmony_ci return getArrayBufferOrView(key, 'key', encoding); 6021cb0ef41Sopenharmony_ci} 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_cifunction createSecretKey(key, encoding) { 6051cb0ef41Sopenharmony_ci key = prepareSecretKey(key, encoding, true); 6061cb0ef41Sopenharmony_ci const handle = new KeyObjectHandle(); 6071cb0ef41Sopenharmony_ci handle.init(kKeyTypeSecret, key); 6081cb0ef41Sopenharmony_ci return new SecretKeyObject(handle); 6091cb0ef41Sopenharmony_ci} 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_cifunction createPublicKey(key) { 6121cb0ef41Sopenharmony_ci const { format, type, data, passphrase } = 6131cb0ef41Sopenharmony_ci prepareAsymmetricKey(key, kCreatePublic); 6141cb0ef41Sopenharmony_ci let handle; 6151cb0ef41Sopenharmony_ci if (format === 'jwk') { 6161cb0ef41Sopenharmony_ci handle = data; 6171cb0ef41Sopenharmony_ci } else { 6181cb0ef41Sopenharmony_ci handle = new KeyObjectHandle(); 6191cb0ef41Sopenharmony_ci handle.init(kKeyTypePublic, data, format, type, passphrase); 6201cb0ef41Sopenharmony_ci } 6211cb0ef41Sopenharmony_ci return new PublicKeyObject(handle); 6221cb0ef41Sopenharmony_ci} 6231cb0ef41Sopenharmony_ci 6241cb0ef41Sopenharmony_cifunction createPrivateKey(key) { 6251cb0ef41Sopenharmony_ci const { format, type, data, passphrase } = 6261cb0ef41Sopenharmony_ci prepareAsymmetricKey(key, kCreatePrivate); 6271cb0ef41Sopenharmony_ci let handle; 6281cb0ef41Sopenharmony_ci if (format === 'jwk') { 6291cb0ef41Sopenharmony_ci handle = data; 6301cb0ef41Sopenharmony_ci } else { 6311cb0ef41Sopenharmony_ci handle = new KeyObjectHandle(); 6321cb0ef41Sopenharmony_ci handle.init(kKeyTypePrivate, data, format, type, passphrase); 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci return new PrivateKeyObject(handle); 6351cb0ef41Sopenharmony_ci} 6361cb0ef41Sopenharmony_ci 6371cb0ef41Sopenharmony_cifunction isKeyObject(obj) { 6381cb0ef41Sopenharmony_ci return obj != null && obj[kKeyType] !== undefined; 6391cb0ef41Sopenharmony_ci} 6401cb0ef41Sopenharmony_ci 6411cb0ef41Sopenharmony_ci// Our implementation of CryptoKey is a simple wrapper around a KeyObject 6421cb0ef41Sopenharmony_ci// that adapts it to the standard interface. 6431cb0ef41Sopenharmony_ci// TODO(@jasnell): Embedder environments like electron may have issues 6441cb0ef41Sopenharmony_ci// here similar to other things like URL. A chromium provided CryptoKey 6451cb0ef41Sopenharmony_ci// will not be recognized as a Node.js CryptoKey, and vice versa. It 6461cb0ef41Sopenharmony_ci// would be fantastic if we could find a way of making those interop. 6471cb0ef41Sopenharmony_ciclass CryptoKey { 6481cb0ef41Sopenharmony_ci constructor() { 6491cb0ef41Sopenharmony_ci throw new ERR_ILLEGAL_CONSTRUCTOR(); 6501cb0ef41Sopenharmony_ci } 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci [kInspect](depth, options) { 6531cb0ef41Sopenharmony_ci if (depth < 0) 6541cb0ef41Sopenharmony_ci return this; 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci const opts = { 6571cb0ef41Sopenharmony_ci ...options, 6581cb0ef41Sopenharmony_ci depth: options.depth == null ? null : options.depth - 1, 6591cb0ef41Sopenharmony_ci }; 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci return `CryptoKey ${inspect({ 6621cb0ef41Sopenharmony_ci type: this.type, 6631cb0ef41Sopenharmony_ci extractable: this.extractable, 6641cb0ef41Sopenharmony_ci algorithm: this.algorithm, 6651cb0ef41Sopenharmony_ci usages: this.usages, 6661cb0ef41Sopenharmony_ci }, opts)}`; 6671cb0ef41Sopenharmony_ci } 6681cb0ef41Sopenharmony_ci 6691cb0ef41Sopenharmony_ci get type() { 6701cb0ef41Sopenharmony_ci if (!(this instanceof CryptoKey)) 6711cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('CryptoKey'); 6721cb0ef41Sopenharmony_ci return this[kKeyObject].type; 6731cb0ef41Sopenharmony_ci } 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci get extractable() { 6761cb0ef41Sopenharmony_ci if (!(this instanceof CryptoKey)) 6771cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('CryptoKey'); 6781cb0ef41Sopenharmony_ci return this[kExtractable]; 6791cb0ef41Sopenharmony_ci } 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci get algorithm() { 6821cb0ef41Sopenharmony_ci if (!(this instanceof CryptoKey)) 6831cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('CryptoKey'); 6841cb0ef41Sopenharmony_ci return this[kAlgorithm]; 6851cb0ef41Sopenharmony_ci } 6861cb0ef41Sopenharmony_ci 6871cb0ef41Sopenharmony_ci get usages() { 6881cb0ef41Sopenharmony_ci if (!(this instanceof CryptoKey)) 6891cb0ef41Sopenharmony_ci throw new ERR_INVALID_THIS('CryptoKey'); 6901cb0ef41Sopenharmony_ci return ArrayFrom(this[kKeyUsages]); 6911cb0ef41Sopenharmony_ci } 6921cb0ef41Sopenharmony_ci} 6931cb0ef41Sopenharmony_ci 6941cb0ef41Sopenharmony_ciObjectDefineProperties(CryptoKey.prototype, { 6951cb0ef41Sopenharmony_ci type: kEnumerableProperty, 6961cb0ef41Sopenharmony_ci extractable: kEnumerableProperty, 6971cb0ef41Sopenharmony_ci algorithm: kEnumerableProperty, 6981cb0ef41Sopenharmony_ci usages: kEnumerableProperty, 6991cb0ef41Sopenharmony_ci [SymbolToStringTag]: { 7001cb0ef41Sopenharmony_ci __proto__: null, 7011cb0ef41Sopenharmony_ci configurable: true, 7021cb0ef41Sopenharmony_ci value: 'CryptoKey', 7031cb0ef41Sopenharmony_ci }, 7041cb0ef41Sopenharmony_ci}); 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci// All internal code must use new InternalCryptoKey to create 7071cb0ef41Sopenharmony_ci// CryptoKey instances. The CryptoKey class is exposed to end 7081cb0ef41Sopenharmony_ci// user code but is not permitted to be constructed directly. 7091cb0ef41Sopenharmony_ci// Using makeTransferable also allows the CryptoKey to be 7101cb0ef41Sopenharmony_ci// cloned to Workers. 7111cb0ef41Sopenharmony_ciclass InternalCryptoKey { 7121cb0ef41Sopenharmony_ci constructor( 7131cb0ef41Sopenharmony_ci keyObject, 7141cb0ef41Sopenharmony_ci algorithm, 7151cb0ef41Sopenharmony_ci keyUsages, 7161cb0ef41Sopenharmony_ci extractable) { 7171cb0ef41Sopenharmony_ci // Using symbol properties here currently instead of private 7181cb0ef41Sopenharmony_ci // properties because (for now) the performance penalty of 7191cb0ef41Sopenharmony_ci // private fields is still too high. 7201cb0ef41Sopenharmony_ci this[kKeyObject] = keyObject; 7211cb0ef41Sopenharmony_ci this[kAlgorithm] = algorithm; 7221cb0ef41Sopenharmony_ci this[kExtractable] = extractable; 7231cb0ef41Sopenharmony_ci this[kKeyUsages] = keyUsages; 7241cb0ef41Sopenharmony_ci 7251cb0ef41Sopenharmony_ci // eslint-disable-next-line no-constructor-return 7261cb0ef41Sopenharmony_ci return makeTransferable(this); 7271cb0ef41Sopenharmony_ci } 7281cb0ef41Sopenharmony_ci 7291cb0ef41Sopenharmony_ci [kClone]() { 7301cb0ef41Sopenharmony_ci const keyObject = this[kKeyObject]; 7311cb0ef41Sopenharmony_ci const algorithm = this.algorithm; 7321cb0ef41Sopenharmony_ci const extractable = this.extractable; 7331cb0ef41Sopenharmony_ci const usages = this.usages; 7341cb0ef41Sopenharmony_ci 7351cb0ef41Sopenharmony_ci return { 7361cb0ef41Sopenharmony_ci data: { 7371cb0ef41Sopenharmony_ci keyObject, 7381cb0ef41Sopenharmony_ci algorithm, 7391cb0ef41Sopenharmony_ci usages, 7401cb0ef41Sopenharmony_ci extractable, 7411cb0ef41Sopenharmony_ci }, 7421cb0ef41Sopenharmony_ci deserializeInfo: 'internal/crypto/keys:InternalCryptoKey', 7431cb0ef41Sopenharmony_ci }; 7441cb0ef41Sopenharmony_ci } 7451cb0ef41Sopenharmony_ci 7461cb0ef41Sopenharmony_ci [kDeserialize]({ keyObject, algorithm, usages, extractable }) { 7471cb0ef41Sopenharmony_ci this[kKeyObject] = keyObject; 7481cb0ef41Sopenharmony_ci this[kAlgorithm] = algorithm; 7491cb0ef41Sopenharmony_ci this[kKeyUsages] = usages; 7501cb0ef41Sopenharmony_ci this[kExtractable] = extractable; 7511cb0ef41Sopenharmony_ci } 7521cb0ef41Sopenharmony_ci} 7531cb0ef41Sopenharmony_ciInternalCryptoKey.prototype.constructor = CryptoKey; 7541cb0ef41Sopenharmony_ciObjectSetPrototypeOf(InternalCryptoKey.prototype, CryptoKey.prototype); 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_cifunction isCryptoKey(obj) { 7571cb0ef41Sopenharmony_ci return obj != null && obj[kKeyObject] !== undefined; 7581cb0ef41Sopenharmony_ci} 7591cb0ef41Sopenharmony_ci 7601cb0ef41Sopenharmony_cimodule.exports = { 7611cb0ef41Sopenharmony_ci // Public API. 7621cb0ef41Sopenharmony_ci createSecretKey, 7631cb0ef41Sopenharmony_ci createPublicKey, 7641cb0ef41Sopenharmony_ci createPrivateKey, 7651cb0ef41Sopenharmony_ci KeyObject, 7661cb0ef41Sopenharmony_ci CryptoKey, 7671cb0ef41Sopenharmony_ci InternalCryptoKey, 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_ci // These are designed for internal use only and should not be exposed. 7701cb0ef41Sopenharmony_ci parsePublicKeyEncoding, 7711cb0ef41Sopenharmony_ci parsePrivateKeyEncoding, 7721cb0ef41Sopenharmony_ci parseKeyEncoding, 7731cb0ef41Sopenharmony_ci preparePrivateKey, 7741cb0ef41Sopenharmony_ci preparePublicOrPrivateKey, 7751cb0ef41Sopenharmony_ci prepareSecretKey, 7761cb0ef41Sopenharmony_ci SecretKeyObject, 7771cb0ef41Sopenharmony_ci PublicKeyObject, 7781cb0ef41Sopenharmony_ci PrivateKeyObject, 7791cb0ef41Sopenharmony_ci isKeyObject, 7801cb0ef41Sopenharmony_ci isCryptoKey, 7811cb0ef41Sopenharmony_ci}; 782