From 4e443224130ed16e507a8d051b7e68414006b5f1 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Wed, 4 Dec 2024 11:46:27 +0100 Subject: [PATCH] crypto: ensure CryptoKey usages and algorithm are cached objects PR-URL: https://github.com/nodejs/node/pull/56108 Reviewed-By: Matthew Aitken Reviewed-By: Yagiz Nizipli Reviewed-By: Luigi Pinca --- lib/internal/crypto/keys.js | 3 +-- .../test-webcrypto-export-import-cfrg.js | 10 ++++++++++ test/parallel/test-webcrypto-export-import-ec.js | 10 ++++++++++ .../parallel/test-webcrypto-export-import-rsa.js | 8 ++++++++ test/parallel/test-webcrypto-export-import.js | 6 ++++++ test/parallel/test-webcrypto-keygen.js | 16 ++++++++++++++++ 6 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/internal/crypto/keys.js b/lib/internal/crypto/keys.js index 64f8bedc48281b..96771f09c8c941 100644 --- a/lib/internal/crypto/keys.js +++ b/lib/internal/crypto/keys.js @@ -1,7 +1,6 @@ 'use strict'; const { - ArrayFrom, ArrayPrototypeSlice, ObjectDefineProperties, ObjectDefineProperty, @@ -781,7 +780,7 @@ class CryptoKey { get usages() { if (!(this instanceof CryptoKey)) throw new ERR_INVALID_THIS('CryptoKey'); - return ArrayFrom(this[kKeyUsages]); + return this[kKeyUsages]; } } diff --git a/test/parallel/test-webcrypto-export-import-cfrg.js b/test/parallel/test-webcrypto-export-import-cfrg.js index 2c2cb80a31c1bf..84d969eb1c5850 100644 --- a/test/parallel/test-webcrypto-export-import-cfrg.js +++ b/test/parallel/test-webcrypto-export-import-cfrg.js @@ -115,6 +115,8 @@ async function testImportSpki({ name, publicUsages }, extractable) { assert.strictEqual(key.extractable, extractable); assert.deepStrictEqual(key.usages, publicUsages); assert.deepStrictEqual(key.algorithm.name, name); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { // Test the roundtrip @@ -151,6 +153,8 @@ async function testImportPkcs8({ name, privateUsages }, extractable) { assert.strictEqual(key.extractable, extractable); assert.deepStrictEqual(key.usages, privateUsages); assert.deepStrictEqual(key.algorithm.name, name); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { // Test the roundtrip @@ -227,6 +231,10 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) assert.deepStrictEqual(privateKey.usages, privateUsages); assert.strictEqual(publicKey.algorithm.name, name); assert.strictEqual(privateKey.algorithm.name, name); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); if (extractable) { // Test the round trip @@ -345,6 +353,8 @@ async function testImportRaw({ name, publicUsages }) { assert.strictEqual(publicKey.type, 'public'); assert.deepStrictEqual(publicKey.usages, publicUsages); assert.strictEqual(publicKey.algorithm.name, name); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); } (async function() { diff --git a/test/parallel/test-webcrypto-export-import-ec.js b/test/parallel/test-webcrypto-export-import-ec.js index 35c657bbbf0ef1..57f1b2831e33bc 100644 --- a/test/parallel/test-webcrypto-export-import-ec.js +++ b/test/parallel/test-webcrypto-export-import-ec.js @@ -111,6 +111,8 @@ async function testImportSpki({ name, publicUsages }, namedCurve, extractable) { assert.deepStrictEqual(key.usages, publicUsages); assert.deepStrictEqual(key.algorithm.name, name); assert.deepStrictEqual(key.algorithm.namedCurve, namedCurve); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { // Test the roundtrip @@ -151,6 +153,8 @@ async function testImportPkcs8( assert.deepStrictEqual(key.usages, privateUsages); assert.deepStrictEqual(key.algorithm.name, name); assert.deepStrictEqual(key.algorithm.namedCurve, namedCurve); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { // Test the roundtrip @@ -234,6 +238,10 @@ async function testImportJwk( assert.strictEqual(privateKey.algorithm.name, name); assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve); assert.strictEqual(privateKey.algorithm.namedCurve, namedCurve); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); if (extractable) { // Test the round trip @@ -368,6 +376,8 @@ async function testImportRaw({ name, publicUsages }, namedCurve) { assert.deepStrictEqual(publicKey.usages, publicUsages); assert.strictEqual(publicKey.algorithm.name, name); assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); } (async function() { diff --git a/test/parallel/test-webcrypto-export-import-rsa.js b/test/parallel/test-webcrypto-export-import-rsa.js index 303efef7bb8f84..62734c69d5ed77 100644 --- a/test/parallel/test-webcrypto-export-import-rsa.js +++ b/test/parallel/test-webcrypto-export-import-rsa.js @@ -315,6 +315,8 @@ async function testImportSpki({ name, publicUsages }, size, hash, extractable) { assert.deepStrictEqual(key.algorithm.publicExponent, new Uint8Array([1, 0, 1])); assert.strictEqual(key.algorithm.hash.name, hash); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { const spki = await subtle.exportKey('spki', key); @@ -349,6 +351,8 @@ async function testImportPkcs8( assert.deepStrictEqual(key.algorithm.publicExponent, new Uint8Array([1, 0, 1])); assert.strictEqual(key.algorithm.hash.name, hash); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); if (extractable) { const pkcs8 = await subtle.exportKey('pkcs8', key); @@ -415,6 +419,10 @@ async function testImportJwk( new Uint8Array([1, 0, 1])); assert.deepStrictEqual(publicKey.algorithm.publicExponent, privateKey.algorithm.publicExponent); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); if (extractable) { const [ diff --git a/test/parallel/test-webcrypto-export-import.js b/test/parallel/test-webcrypto-export-import.js index 21a8d16edbea0e..02eb33dfa4cdf7 100644 --- a/test/parallel/test-webcrypto-export-import.js +++ b/test/parallel/test-webcrypto-export-import.js @@ -86,6 +86,10 @@ const { subtle } = globalThis.crypto; hash: 'SHA-256' }, true, ['sign', 'verify']); + + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); + const raw = await subtle.exportKey('raw', key); assert.deepStrictEqual( @@ -127,6 +131,8 @@ const { subtle } = globalThis.crypto; name: 'AES-CTR', length: 256, }, true, ['encrypt', 'decrypt']); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); const raw = await subtle.exportKey('raw', key); diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index dceb3348528911..5d36aa3e16a6ca 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -298,6 +298,10 @@ const vectors = { KeyObject.from(privateKey).asymmetricKeyDetails.publicExponent, bigIntArrayToUnsignedBigInt(publicExponent)); assert.strictEqual(privateKey.algorithm.hash.name, hash); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); // Missing parameters await assert.rejects( @@ -442,6 +446,10 @@ const vectors = { assert.strictEqual(privateKey.algorithm.name, name); assert.strictEqual(publicKey.algorithm.namedCurve, namedCurve); assert.strictEqual(privateKey.algorithm.namedCurve, namedCurve); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); // Invalid parameters [1, true, {}, [], null].forEach(async (namedCurve) => { @@ -508,6 +516,8 @@ const vectors = { assert.deepStrictEqual(key.usages, usages); assert.strictEqual(key.algorithm.name, name); assert.strictEqual(key.algorithm.length, length); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); // Invalid parameters [1, 100, 257, '', false, null].forEach(async (length) => { @@ -568,6 +578,8 @@ const vectors = { assert.strictEqual(key.algorithm.name, 'HMAC'); assert.strictEqual(key.algorithm.length, length); assert.strictEqual(key.algorithm.hash.name, hash); + assert.strictEqual(key.algorithm, key.algorithm); + assert.strictEqual(key.usages, key.usages); [1, false, null].forEach(async (hash) => { await assert.rejects( @@ -632,6 +644,10 @@ assert.throws(() => new CryptoKey(), { code: 'ERR_ILLEGAL_CONSTRUCTOR' }); assert.deepStrictEqual(privateKey.usages, privateUsages); assert.strictEqual(publicKey.algorithm.name, name); assert.strictEqual(privateKey.algorithm.name, name); + assert.strictEqual(privateKey.algorithm, privateKey.algorithm); + assert.strictEqual(privateKey.usages, privateKey.usages); + assert.strictEqual(publicKey.algorithm, publicKey.algorithm); + assert.strictEqual(publicKey.usages, publicKey.usages); } const kTests = [