mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
crypto: create key usage arrays without species
Build public usages and JWK key_ops from the native usage mask so array species cannot replace or mutate internal usage arrays. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: https://github.com/nodejs/node/pull/66237 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Aviv Keller <me@aviv.sh>
This commit is contained in:
1 parent
5af55e612c
commit
4e38081bec
4 files changed
+37
-9
No files matched your search
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
ArrayPrototypeSlice,
|
||||
BigInt,
|
||||
PromiseWithResolvers,
|
||||
SafeSet,
|
||||
@@ -24,7 +23,7 @@ const {
|
||||
getCryptoKeySeedData,
|
||||
getCryptoKeySecondaryHandle,
|
||||
getCryptoKeyType,
|
||||
getCryptoKeyUsages,
|
||||
getCryptoKeyUsagesMask,
|
||||
InternalCryptoKey,
|
||||
} = require('internal/crypto/keys');
|
||||
|
||||
@@ -51,6 +50,7 @@ const {
|
||||
const {
|
||||
getBufferSourceBytes,
|
||||
getUsagesMask,
|
||||
getUsagesFromMask,
|
||||
jobPromise,
|
||||
jobPromiseThen,
|
||||
resolveWebCryptoResult,
|
||||
@@ -860,7 +860,7 @@ function exportJwkKey(key, rawEncapsulationKey, config) {
|
||||
kty: 'AKP',
|
||||
alg: config.name,
|
||||
pub: base64urlEncode(rawEncapsulationKey),
|
||||
key_ops: ArrayPrototypeSlice(getCryptoKeyUsages(key), 0),
|
||||
key_ops: getUsagesFromMask(getCryptoKeyUsagesMask(key)),
|
||||
ext: getCryptoKeyExtractable(key),
|
||||
};
|
||||
if (getCryptoKeyType(key) === 'private')
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
const {
|
||||
ArrayPrototypeMap,
|
||||
ArrayPrototypeSlice,
|
||||
ObjectDefineProperties,
|
||||
ObjectPrototypeHasOwnProperty,
|
||||
ObjectSetPrototypeOf,
|
||||
@@ -1224,7 +1223,7 @@ const {
|
||||
type: getCryptoKeyType(this),
|
||||
extractable: getCryptoKeyExtractable(this),
|
||||
algorithm: cloneAlgorithm(getCryptoKeyAlgorithm(this)),
|
||||
usages: ArrayPrototypeSlice(getCryptoKeyUsages(this), 0),
|
||||
usages: getUsagesFromMask(getCryptoKeyUsagesMask(this)),
|
||||
}, opts)}`;
|
||||
}
|
||||
|
||||
@@ -1258,7 +1257,7 @@ const {
|
||||
const slots = getSlots(this);
|
||||
let cached = slots[kSlotClonedUsages];
|
||||
if (cached === undefined) {
|
||||
cached = ArrayPrototypeSlice(getCryptoKeyUsagesFromSlots(slots), 0);
|
||||
cached = getUsagesFromMask(slots[kSlotUsagesMask]);
|
||||
slots[kSlotClonedUsages] = cached;
|
||||
}
|
||||
return cached;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
const {
|
||||
ArrayBufferIsView,
|
||||
ArrayIsArray,
|
||||
ArrayPrototypeSlice,
|
||||
FunctionPrototypeCall,
|
||||
JSONParse,
|
||||
JSONStringify,
|
||||
@@ -52,7 +51,6 @@ const {
|
||||
getCryptoKeyExtractable,
|
||||
getCryptoKeyHandle,
|
||||
getCryptoKeyType,
|
||||
getCryptoKeyUsages,
|
||||
getCryptoKeyUsagesMask,
|
||||
hasCryptoKeyUsage,
|
||||
importGenericSecretKey,
|
||||
@@ -66,6 +64,7 @@ const {
|
||||
const {
|
||||
cleanupWebCryptoResult,
|
||||
getBlockSize,
|
||||
getUsagesFromMask,
|
||||
jobPromiseThen,
|
||||
normalizeAlgorithm,
|
||||
normalizeHashName,
|
||||
@@ -801,7 +800,7 @@ function exportKeyJWK(key) {
|
||||
// `parameters` before native export populates key material. Delete it for
|
||||
// algorithms without a JWK alg value to keep the expected shape.
|
||||
const parameters = {
|
||||
key_ops: ArrayPrototypeSlice(getCryptoKeyUsages(key), 0),
|
||||
key_ops: getUsagesFromMask(getCryptoKeyUsagesMask(key)),
|
||||
ext: getCryptoKeyExtractable(key),
|
||||
alg,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const assert = require('assert');
|
||||
const { subtle } = globalThis.crypto;
|
||||
|
||||
(async () => {
|
||||
const key = await subtle.importKey('raw', new Uint8Array(16), 'AES-GCM', true,
|
||||
['encrypt', 'decrypt']);
|
||||
const descriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'constructor');
|
||||
let usages;
|
||||
let jwk;
|
||||
try {
|
||||
Object.defineProperty(Array.prototype, 'constructor', { get: common.mustNotCall() });
|
||||
usages = key.usages;
|
||||
jwk = await subtle.exportKey('jwk', key);
|
||||
} finally {
|
||||
Object.defineProperty(Array.prototype, 'constructor', descriptor);
|
||||
}
|
||||
assert.strictEqual(Object.getPrototypeOf(usages), Array.prototype);
|
||||
assert.strictEqual(key.usages, usages);
|
||||
assert.deepStrictEqual(usages, ['encrypt', 'decrypt']);
|
||||
assert.deepStrictEqual(jwk.key_ops, usages);
|
||||
usages.push('sign');
|
||||
assert.deepStrictEqual((await subtle.exportKey('jwk', key)).key_ops,
|
||||
['encrypt', 'decrypt']);
|
||||
})().then(common.mustCall());
|
||||
Reference in new issue
Block a user