Skip to content

Commit b1e188d

Browse files
aduh95targos
authored andcommitted
crypto: refactor hasAnyNotIn to avoid unsafe array iteration
PR-URL: #37433 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
1 parent c0cdb83 commit b1e188d

File tree

8 files changed

+36
-41
lines changed

8 files changed

+36
-41
lines changed

lib/internal/crypto/aes.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const {
88
ArrayPrototypePush,
99
MathFloor,
1010
Promise,
11-
ReflectApply,
1211
SafeSet,
1312
TypedArrayPrototypeSlice,
1413
} = primordials;
@@ -223,7 +222,7 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) {
223222

224223
const usageSet = new SafeSet(keyUsages);
225224

226-
if (hasAnyNotIn(usageSet, 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey')) {
225+
if (hasAnyNotIn(usageSet, ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'])) {
227226
throw lazyDOMException(
228227
'Unsupported key usage for an AES key',
229228
'SyntaxError');
@@ -253,12 +252,12 @@ async function aesImportKey(
253252
extractable,
254253
keyUsages) {
255254
const { name } = algorithm;
256-
const usagesSet = new SafeSet(keyUsages);
257-
const checkUsages = [usagesSet, 'wrapKey', 'unwrapKey'];
255+
const checkUsages = ['wrapKey', 'unwrapKey'];
258256
if (name !== 'AES-KW')
259257
ArrayPrototypePush(checkUsages, 'encrypt', 'decrypt');
260258

261-
if (ReflectApply(hasAnyNotIn, null, checkUsages)) {
259+
const usagesSet = new SafeSet(keyUsages);
260+
if (hasAnyNotIn(usagesSet, checkUsages)) {
262261
throw lazyDOMException(
263262
'Unsupported key usage for an AES key',
264263
'SyntaxError');

lib/internal/crypto/diffiehellman.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
const {
44
ArrayBufferPrototypeSlice,
5-
ArrayPrototypePush,
65
FunctionPrototypeCall,
76
MathFloor,
87
ObjectDefineProperty,
98
Promise,
10-
ReflectApply,
119
SafeSet,
1210
} = primordials;
1311

@@ -349,15 +347,16 @@ function deriveBitsDH(publicKey, privateKey, callback) {
349347
}
350348

351349
function verifyAcceptableDhKeyUse(name, type, usages) {
352-
const args = [usages];
350+
let checkSet;
353351
switch (type) {
354352
case 'private':
355-
ArrayPrototypePush(args, 'deriveBits', 'deriveKey');
353+
checkSet = ['deriveBits', 'deriveKey'];
356354
break;
357355
case 'public':
356+
checkSet = [];
358357
break;
359358
}
360-
if (ReflectApply(hasAnyNotIn, null, args)) {
359+
if (hasAnyNotIn(usages, checkSet)) {
361360
throw lazyDOMException(
362361
`Unsupported key usage for an ${name} key`,
363362
'SyntaxError');
@@ -370,7 +369,7 @@ async function dhGenerateKey(
370369
keyUsages) {
371370
const usageSet = new SafeSet(keyUsages);
372371

373-
if (hasAnyNotIn(usageSet, 'deriveKey', 'deriveBits')) {
372+
if (hasAnyNotIn(usageSet, ['deriveKey', 'deriveBits'])) {
374373
throw lazyDOMException(
375374
'Unsupported key usage for a DH key',
376375
'SyntaxError');

lib/internal/crypto/dsa.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ const {
5151
} = require('internal/crypto/util');
5252

5353
function verifyAcceptableDsaKeyUse(name, type, usages) {
54-
let check;
54+
let checkSet;
5555
switch (type) {
5656
case 'private':
57-
check = 'sign';
57+
checkSet = ['sign'];
5858
break;
5959
case 'public':
60-
check = 'verify';
60+
checkSet = ['verify'];
6161
break;
6262
}
63-
if (hasAnyNotIn(usages, check)) {
63+
if (hasAnyNotIn(usages, checkSet)) {
6464
throw lazyDOMException(
6565
`Unsupported key usage for an ${name} key`,
6666
'SyntaxError');
@@ -84,7 +84,7 @@ async function dsaGenerateKey(
8484

8585
const usageSet = new SafeSet(keyUsages);
8686

87-
if (hasAnyNotIn(usageSet, 'sign', 'verify')) {
87+
if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
8888
throw lazyDOMException(
8989
'Unsupported key usage for a DSA key',
9090
'SyntaxError');

lib/internal/crypto/ec.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypePush,
54
ObjectKeys,
65
Promise,
7-
ReflectApply,
86
SafeSet,
97
} = primordials;
108

@@ -61,10 +59,10 @@ const {
6159
} = require('internal/crypto/keys');
6260

6361
function verifyAcceptableEcKeyUse(name, type, usages) {
64-
const args = [usages];
62+
let checkSet;
6563
switch (name) {
6664
case 'ECDH':
67-
ArrayPrototypePush(args, 'deriveKey', 'deriveBits');
65+
checkSet = ['deriveKey', 'deriveBits'];
6866
break;
6967
case 'NODE-ED25519':
7068
// Fall through
@@ -73,14 +71,14 @@ function verifyAcceptableEcKeyUse(name, type, usages) {
7371
case 'ECDSA':
7472
switch (type) {
7573
case 'private':
76-
ArrayPrototypePush(args, 'sign');
74+
checkSet = ['sign'];
7775
break;
7876
case 'public':
79-
ArrayPrototypePush(args, 'verify');
77+
checkSet = ['verify'];
8078
break;
8179
}
8280
}
83-
if (ReflectApply(hasAnyNotIn, null, args)) {
81+
if (hasAnyNotIn(usages, checkSet)) {
8482
throw lazyDOMException(
8583
`Unsupported key usage for a ${name} key`,
8684
'SyntaxError');
@@ -150,14 +148,14 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) {
150148
case 'NODE-ED25519':
151149
// Fall through
152150
case 'NODE-ED448':
153-
if (hasAnyNotIn(usageSet, 'sign', 'verify')) {
151+
if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
154152
throw lazyDOMException(
155153
'Unsupported key usage for an ECDSA key',
156154
'SyntaxError');
157155
}
158156
break;
159157
case 'ECDH':
160-
if (hasAnyNotIn(usageSet, 'deriveKey', 'deriveBits')) {
158+
if (hasAnyNotIn(usageSet, ['deriveKey', 'deriveBits'])) {
161159
throw lazyDOMException(
162160
'Unsupported key usage for an ECDH key',
163161
'SyntaxError');

lib/internal/crypto/mac.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
5656
validateBitLength(length, 'algorithm.length', true);
5757

5858
const usageSet = new SafeSet(keyUsages);
59-
if (hasAnyNotIn(usageSet, 'sign', 'verify')) {
59+
if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
6060
throw lazyDOMException(
6161
'Unsupported key usage for an HMAC key',
6262
'SyntaxError');
@@ -89,7 +89,7 @@ async function hmacImportKey(
8989
throw new ERR_MISSING_OPTION('algorithm.hash');
9090

9191
const usagesSet = new SafeSet(keyUsages);
92-
if (hasAnyNotIn(usagesSet, 'sign', 'verify')) {
92+
if (hasAnyNotIn(usagesSet, ['sign', 'verify'])) {
9393
throw lazyDOMException(
9494
'Unsupported key usage for an HMAC key',
9595
'SyntaxError');

lib/internal/crypto/rsa.js

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypePush,
54
Promise,
6-
ReflectApply,
75
SafeSet,
86
Uint8Array,
97
} = primordials;
@@ -73,29 +71,29 @@ const kRsaVariants = {
7371
};
7472

7573
function verifyAcceptableRsaKeyUse(name, type, usages) {
76-
const args = [usages];
74+
let checkSet;
7775
switch (name) {
7876
case 'RSA-OAEP':
7977
switch (type) {
8078
case 'private':
81-
ArrayPrototypePush(args, 'decrypt', 'unwrapKey');
79+
checkSet = ['decrypt', 'unwrapKey'];
8280
break;
8381
case 'public':
84-
ArrayPrototypePush(args, 'encrypt', 'wrapKey');
82+
checkSet = ['encrypt', 'wrapKey'];
8583
break;
8684
}
8785
break;
8886
default:
8987
switch (type) {
9088
case 'private':
91-
ArrayPrototypePush(args, 'sign');
89+
checkSet = ['sign'];
9290
break;
9391
case 'public':
94-
ArrayPrototypePush(args, 'verify');
92+
checkSet = ['verify'];
9593
break;
9694
}
9795
}
98-
if (ReflectApply(hasAnyNotIn, null, args)) {
96+
if (hasAnyNotIn(usages, checkSet)) {
9997
throw lazyDOMException(
10098
`Unsupported key usage for an ${name} key`,
10199
'SyntaxError');
@@ -157,14 +155,15 @@ async function rsaKeyGenerate(
157155

158156
switch (name) {
159157
case 'RSA-OAEP':
160-
if (hasAnyNotIn(usageSet, 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey')) {
158+
if (hasAnyNotIn(usageSet,
159+
['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'])) {
161160
throw lazyDOMException(
162161
'Unsupported key usage for a RSA key',
163162
'SyntaxError');
164163
}
165164
break;
166165
default:
167-
if (hasAnyNotIn(usageSet, 'sign', 'verify')) {
166+
if (hasAnyNotIn(usageSet, ['sign', 'verify'])) {
168167
throw lazyDOMException(
169168
'Unsupported key usage for a RSA key',
170169
'SyntaxError');

lib/internal/crypto/util.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,9 @@ function normalizeAlgorithm(algorithm, label = 'algorithm') {
236236
throw lazyDOMException('Unrecognized name.', 'NotSupportedError');
237237
}
238238

239-
function hasAnyNotIn(set, ...check) {
239+
function hasAnyNotIn(set, checks) {
240240
for (const s of set)
241-
if (!ArrayPrototypeIncludes(check, s))
241+
if (!ArrayPrototypeIncludes(checks, s))
242242
return true;
243243
return false;
244244
}

lib/internal/crypto/webcrypto.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ async function importGenericSecretKey(
402402
if (extractable)
403403
throw lazyDOMException(`${name} keys are not extractable`, 'SyntaxError');
404404

405-
if (hasAnyNotIn(usagesSet, 'deriveKey', 'deriveBits')) {
405+
if (hasAnyNotIn(usagesSet, ['deriveKey', 'deriveBits'])) {
406406
throw lazyDOMException(
407407
`Unsupported key usage for a ${name} key`,
408408
'SyntaxError');
@@ -419,7 +419,7 @@ async function importGenericSecretKey(
419419
break;
420420
}
421421
case 'raw':
422-
if (hasAnyNotIn(usagesSet, 'deriveKey', 'deriveBits')) {
422+
if (hasAnyNotIn(usagesSet, ['deriveKey', 'deriveBits'])) {
423423
throw lazyDOMException(
424424
`Unsupported key usage for a ${name} key`,
425425
'SyntaxError');

0 commit comments

Comments
 (0)