Skip to content

Commit 1314d27

Browse files
panvaaduh95
authored andcommitted
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: #66237 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent a855a46 commit 1314d27

3 files changed

Lines changed: 59 additions & 49 deletions

File tree

‎lib/internal/crypto/webcrypto.js‎

Lines changed: 21 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,22 @@ class SubtleCrypto {
17721772
context: '2nd argument',
17731773
});
17741774

1775+
let length = null;
1776+
let additionalAlgorithm;
1777+
if (lengthOrAdditionalAlgorithm === null ||
1778+
typeof lengthOrAdditionalAlgorithm === 'number') {
1779+
if (lengthOrAdditionalAlgorithm !== null) {
1780+
length = webidl.converters['unsigned long'](lengthOrAdditionalAlgorithm, {
1781+
prefix,
1782+
context: '3rd argument',
1783+
enforceRange: true,
1784+
});
1785+
}
1786+
} else {
1787+
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
1788+
lengthOrAdditionalAlgorithm, { prefix, context: '3rd argument' });
1789+
}
1790+
17751791
switch (operation) {
17761792
case 'decapsulateBits':
17771793
case 'decapsulateKey':
@@ -1795,17 +1811,7 @@ class SubtleCrypto {
17951811
return false;
17961812
}
17971813

1798-
let length;
1799-
let additionalAlgorithm;
1800-
if (operation === 'deriveKey') {
1801-
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
1802-
lengthOrAdditionalAlgorithm,
1803-
{
1804-
prefix,
1805-
context: '3rd argument',
1806-
},
1807-
);
1808-
1814+
if (additionalAlgorithm !== undefined && operation === 'deriveKey') {
18091815
if (!check('importKey', additionalAlgorithm)) {
18101816
return false;
18111817
}
@@ -1817,39 +1823,14 @@ class SubtleCrypto {
18171823
}
18181824

18191825
operation = 'deriveBits';
1820-
} else if (operation === 'wrapKey') {
1821-
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
1822-
lengthOrAdditionalAlgorithm,
1823-
{
1824-
prefix,
1825-
context: '3rd argument',
1826-
},
1827-
);
1828-
1826+
} else if (additionalAlgorithm !== undefined && operation === 'wrapKey') {
18291827
if (!check('exportKey', additionalAlgorithm)) {
18301828
return false;
18311829
}
1832-
} else if (operation === 'unwrapKey') {
1833-
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
1834-
lengthOrAdditionalAlgorithm,
1835-
{
1836-
prefix,
1837-
context: '3rd argument',
1838-
},
1839-
);
1840-
1830+
} else if (additionalAlgorithm !== undefined && operation === 'unwrapKey') {
18411831
if (!check('importKey', additionalAlgorithm)) {
18421832
return false;
18431833
}
1844-
} else if (operation === 'deriveBits') {
1845-
length = lengthOrAdditionalAlgorithm;
1846-
if (length !== null) {
1847-
length = webidl.converters['unsigned long'](length, {
1848-
prefix,
1849-
context: '3rd argument',
1850-
enforceRange: true,
1851-
});
1852-
}
18531834
} else if (operation === 'getPublicKey') {
18541835
let normalizedAlgorithm;
18551836
try {
@@ -1870,15 +1851,8 @@ class SubtleCrypto {
18701851
default:
18711852
return false;
18721853
}
1873-
} else if (operation === 'encapsulateKey' || operation === 'decapsulateKey') {
1874-
additionalAlgorithm = webidl.converters.AlgorithmIdentifier(
1875-
lengthOrAdditionalAlgorithm,
1876-
{
1877-
prefix,
1878-
context: '3rd argument',
1879-
},
1880-
);
1881-
1854+
} else if (additionalAlgorithm !== undefined &&
1855+
(operation === 'encapsulateKey' || operation === 'decapsulateKey')) {
18821856
let sharedKeyLength;
18831857
let normalizedAdditionalAlgorithm;
18841858
try {

‎test/fixtures/webcrypto/supports-level-2.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,12 @@ export const vectors = {
268268
[hasX25519, 'X25519'],
269269
],
270270
'wrapKey': [
271-
[false, 'AES-KW'],
271+
[true, 'AES-KW'],
272272
[true, 'AES-KW', 'AES-CTR'],
273273
[true, 'AES-KW', 'HMAC'],
274274
],
275275
'unwrapKey': [
276-
[false, 'AES-KW'],
276+
[true, 'AES-KW'],
277277
[true, 'AES-KW', 'AES-CTR'],
278278
],
279279
'unsupported operation': [
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const assert = require('assert');
8+
const { supports } = SubtleCrypto;
9+
10+
for (const operation of ['wrapKey', 'unwrapKey']) {
11+
for (const length of [undefined, null, 0, 128]) {
12+
assert.strictEqual(supports(operation, 'AES-KW', length), true);
13+
}
14+
assert.strictEqual(supports(operation, 'AES-KW'), true);
15+
}
16+
17+
for (const operation of ['digest', 'unknown', 'wrapKey', 'deriveBits']) {
18+
for (const value of [-1, NaN, Infinity, 2 ** 32, Symbol()]) {
19+
assert.throws(() => supports(operation, 'SHA-256', value), TypeError);
20+
}
21+
}
22+
23+
const hkdf = {
24+
name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(), info: new Uint8Array(),
25+
};
26+
assert.strictEqual(supports('deriveBits', hkdf, 128), true);
27+
for (const value of ['128', 'AES-GCM', {}, true, 128n]) {
28+
assert.strictEqual(supports('deriveBits', hkdf, value), false);
29+
}
30+
assert.strictEqual(supports('deriveKey', hkdf), false);
31+
assert.strictEqual(supports('deriveKey', hkdf, { name: 'AES-GCM', length: 128 }), true);
32+
33+
if (supports('encapsulateBits', 'ML-KEM-768')) {
34+
assert.strictEqual(supports('encapsulateKey', 'ML-KEM-768'), true);
35+
assert.strictEqual(supports('decapsulateKey', 'ML-KEM-768', 128), true);
36+
}

0 commit comments

Comments
 (0)