From e5017a522e77cbfce6280c78ee8728821838ef02 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 25 Nov 2023 14:19:54 +0100 Subject: [PATCH] crypto: update CryptoKey symbol properties PR-URL: https://github.com/nodejs/node/pull/50897 Reviewed-By: Antoine du Hamel --- lib/internal/crypto/keys.js | 84 ++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/lib/internal/crypto/keys.js b/lib/internal/crypto/keys.js index 1e49bd62473a1b..fc4240ffd28864 100644 --- a/lib/internal/crypto/keys.js +++ b/lib/internal/crypto/keys.js @@ -703,32 +703,81 @@ ObjectDefineProperties(CryptoKey.prototype, { }, }); +/** + * @param {InternalCryptoKey} key + * @param {KeyObject} keyObject + * @param {object} algorithm + * @param {boolean} extractable + * @param {Set} keyUsages + */ +function defineCryptoKeyProperties( + key, + keyObject, + algorithm, + extractable, + keyUsages, +) { + // Using symbol properties here currently instead of private + // properties because (for now) the performance penalty of + // private fields is still too high. + ObjectDefineProperties(key, { + [kKeyObject]: { + __proto__: null, + value: keyObject, + enumerable: false, + configurable: false, + writable: false, + }, + [kAlgorithm]: { + __proto__: null, + value: algorithm, + enumerable: false, + configurable: false, + writable: false, + }, + [kExtractable]: { + __proto__: null, + value: extractable, + enumerable: false, + configurable: false, + writable: false, + }, + [kKeyUsages]: { + __proto__: null, + value: keyUsages, + enumerable: false, + configurable: false, + writable: false, + }, + }); +} + // All internal code must use new InternalCryptoKey to create // CryptoKey instances. The CryptoKey class is exposed to end // user code but is not permitted to be constructed directly. // Using markTransferMode also allows the CryptoKey to be // cloned to Workers. class InternalCryptoKey { - constructor( - keyObject, - algorithm, - keyUsages, - extractable) { + constructor(keyObject, algorithm, keyUsages, extractable) { markTransferMode(this, true, false); - // Using symbol properties here currently instead of private - // properties because (for now) the performance penalty of - // private fields is still too high. - this[kKeyObject] = keyObject; - this[kAlgorithm] = algorithm; - this[kExtractable] = extractable; - this[kKeyUsages] = keyUsages; + // When constructed during transfer the properties get assigned + // in the kDeserialize call. + if (keyObject) { + defineCryptoKeyProperties( + this, + keyObject, + algorithm, + extractable, + keyUsages, + ); + } } [kClone]() { const keyObject = this[kKeyObject]; - const algorithm = this.algorithm; - const extractable = this.extractable; - const usages = this.usages; + const algorithm = this[kAlgorithm]; + const extractable = this[kExtractable]; + const usages = this[kKeyUsages]; return { data: { @@ -742,10 +791,7 @@ class InternalCryptoKey { } [kDeserialize]({ keyObject, algorithm, usages, extractable }) { - this[kKeyObject] = keyObject; - this[kAlgorithm] = algorithm; - this[kKeyUsages] = usages; - this[kExtractable] = extractable; + defineCryptoKeyProperties(this, keyObject, algorithm, extractable, usages); } } InternalCryptoKey.prototype.constructor = CryptoKey;