crypto: resolve supports overloads by type

Convert the third argument before checking the operation, and apply
additional-algorithm checks only for that overload.

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:
Filip Skokan authored and Node.js GitHub Bot committed 2026-09-25 13:23:10 +00:00
1 parent 3ca28cb44b
commit 712a19bebf
3 files changed
+59 -49

No files matched your search

+21 -47
View File
@@ -1772,6 +1772,22 @@ class SubtleCrypto {
context: '2nd argument',
});
let length = null;
let additionalAlgorithm;
if (lengthOrAdditionalAlgorithm === null ||
typeof lengthOrAdditionalAlgorithm === 'number') {
if (lengthOrAdditionalAlgorithm !== null) {
length = webidl.converters['unsigned long'](lengthOrAdditionalAlgorithm, {
prefix,
context: '3rd argument',
enforceRange: true,
});
}
} else {
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
lengthOrAdditionalAlgorithm, { prefix, context: '3rd argument' });
}
switch (operation) {
case 'decapsulateBits':
case 'decapsulateKey':
@@ -1795,17 +1811,7 @@ class SubtleCrypto {
return false;
}
let length;
let additionalAlgorithm;
if (operation === 'deriveKey') {
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
lengthOrAdditionalAlgorithm,
{
prefix,
context: '3rd argument',
},
);
if (additionalAlgorithm !== undefined && operation === 'deriveKey') {
if (!check('importKey', additionalAlgorithm)) {
return false;
}
@@ -1817,39 +1823,14 @@ class SubtleCrypto {
}
operation = 'deriveBits';
} else if (operation === 'wrapKey') {
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
lengthOrAdditionalAlgorithm,
{
prefix,
context: '3rd argument',
},
);
} else if (additionalAlgorithm !== undefined && operation === 'wrapKey') {
if (!check('exportKey', additionalAlgorithm)) {
return false;
}
} else if (operation === 'unwrapKey') {
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
lengthOrAdditionalAlgorithm,
{
prefix,
context: '3rd argument',
},
);
} else if (additionalAlgorithm !== undefined && operation === 'unwrapKey') {
if (!check('importKey', additionalAlgorithm)) {
return false;
}
} else if (operation === 'deriveBits') {
length = lengthOrAdditionalAlgorithm;
if (length !== null) {
length = webidl.converters['unsigned long'](length, {
prefix,
context: '3rd argument',
enforceRange: true,
});
}
} else if (operation === 'getPublicKey') {
let normalizedAlgorithm;
try {
@@ -1870,15 +1851,8 @@ class SubtleCrypto {
default:
return false;
}
} else if (operation === 'encapsulateKey' || operation === 'decapsulateKey') {
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
lengthOrAdditionalAlgorithm,
{
prefix,
context: '3rd argument',
},
);
} else if (additionalAlgorithm !== undefined &&
(operation === 'encapsulateKey' || operation === 'decapsulateKey')) {
let sharedKeyLength;
let normalizedAdditionalAlgorithm;
try {
+2 -2
View File
@@ -268,12 +268,12 @@ export const vectors = {
[hasX25519, 'X25519'],
],
'wrapKey': [
[false, 'AES-KW'],
[true, 'AES-KW'],
[true, 'AES-KW', 'AES-CTR'],
[true, 'AES-KW', 'HMAC'],
],
'unwrapKey': [
[false, 'AES-KW'],
[true, 'AES-KW'],
[true, 'AES-KW', 'AES-CTR'],
],
'unsupported operation': [
@@ -0,0 +1,36 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const { supports } = SubtleCrypto;
for (const operation of ['wrapKey', 'unwrapKey']) {
for (const length of [undefined, null, 0, 128]) {
assert.strictEqual(supports(operation, 'AES-KW', length), true);
}
assert.strictEqual(supports(operation, 'AES-KW'), true);
}
for (const operation of ['digest', 'unknown', 'wrapKey', 'deriveBits']) {
for (const value of [-1, NaN, Infinity, 2 ** 32, Symbol()]) {
assert.throws(() => supports(operation, 'SHA-256', value), TypeError);
}
}
const hkdf = {
name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(), info: new Uint8Array(),
};
assert.strictEqual(supports('deriveBits', hkdf, 128), true);
for (const value of ['128', 'AES-GCM', {}, true, 128n]) {
assert.strictEqual(supports('deriveBits', hkdf, value), false);
}
assert.strictEqual(supports('deriveKey', hkdf), false);
assert.strictEqual(supports('deriveKey', hkdf, { name: 'AES-GCM', length: 128 }), true);
if (supports('encapsulateBits', 'ML-KEM-768')) {
assert.strictEqual(supports('encapsulateKey', 'ML-KEM-768'), true);
assert.strictEqual(supports('decapsulateKey', 'ML-KEM-768', 128), true);
}