Skip to content

Commit b634469

Browse files
aduh95targos
authored andcommitted
crypto: refactor to avoid unsafe array iteration
PR-URL: #37364 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Zijian Liu <[email protected]>
1 parent d2e5529 commit b634469

File tree

11 files changed

+57
-36
lines changed

11 files changed

+57
-36
lines changed

Diff for: lib/internal/crypto/aes.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
ArrayPrototypePush,
99
MathFloor,
1010
Promise,
11+
ReflectApply,
1112
SafeSet,
1213
TypedArrayPrototypeSlice,
1314
} = primordials;
@@ -252,12 +253,12 @@ async function aesImportKey(
252253
extractable,
253254
keyUsages) {
254255
const { name } = algorithm;
255-
const checkUsages = ['wrapKey', 'unwrapKey'];
256+
const usagesSet = new SafeSet(keyUsages);
257+
const checkUsages = [usagesSet, 'wrapKey', 'unwrapKey'];
256258
if (name !== 'AES-KW')
257259
ArrayPrototypePush(checkUsages, 'encrypt', 'decrypt');
258260

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

Diff for: lib/internal/crypto/diffiehellman.js

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

33
const {
44
ArrayBufferPrototypeSlice,
5+
ArrayPrototypePush,
56
FunctionPrototypeCall,
67
MathFloor,
78
ObjectDefineProperty,
89
Promise,
10+
ReflectApply,
911
SafeSet,
1012
} = primordials;
1113

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

349351
function verifyAcceptableDhKeyUse(name, type, usages) {
350-
let checkSet;
352+
const args = [usages];
351353
switch (type) {
352354
case 'private':
353-
checkSet = ['deriveBits', 'deriveKey'];
355+
ArrayPrototypePush(args, 'deriveBits', 'deriveKey');
354356
break;
355357
case 'public':
356-
checkSet = [];
357358
break;
358359
}
359-
if (hasAnyNotIn(usages, ...checkSet)) {
360+
if (ReflectApply(hasAnyNotIn, null, args)) {
360361
throw lazyDOMException(
361362
`Unsupported key usage for an ${name} key`,
362363
'SyntaxError');

Diff for: lib/internal/crypto/dsa.js

+4-4
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 checkSet;
54+
let check;
5555
switch (type) {
5656
case 'private':
57-
checkSet = ['sign'];
57+
check = 'sign';
5858
break;
5959
case 'public':
60-
checkSet = ['verify'];
60+
check = 'verify';
6161
break;
6262
}
63-
if (hasAnyNotIn(usages, ...checkSet)) {
63+
if (hasAnyNotIn(usages, check)) {
6464
throw lazyDOMException(
6565
`Unsupported key usage for an ${name} key`,
6666
'SyntaxError');

Diff for: lib/internal/crypto/ec.js

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

33
const {
4+
ArrayPrototypePush,
45
ObjectKeys,
56
Promise,
7+
ReflectApply,
68
SafeSet,
79
} = primordials;
810

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

6163
function verifyAcceptableEcKeyUse(name, type, usages) {
62-
let checkSet;
64+
const args = [usages];
6365
switch (name) {
6466
case 'ECDH':
65-
checkSet = ['deriveKey', 'deriveBits'];
67+
ArrayPrototypePush(args, 'deriveKey', 'deriveBits');
6668
break;
6769
case 'NODE-ED25519':
6870
// Fall through
@@ -71,14 +73,14 @@ function verifyAcceptableEcKeyUse(name, type, usages) {
7173
case 'ECDSA':
7274
switch (type) {
7375
case 'private':
74-
checkSet = ['sign'];
76+
ArrayPrototypePush(args, 'sign');
7577
break;
7678
case 'public':
77-
checkSet = ['verify'];
79+
ArrayPrototypePush(args, 'verify');
7880
break;
7981
}
8082
}
81-
if (hasAnyNotIn(usages, ...checkSet)) {
83+
if (ReflectApply(hasAnyNotIn, null, args)) {
8284
throw lazyDOMException(
8385
`Unsupported key usage for a ${name} key`,
8486
'SyntaxError');

Diff for: lib/internal/crypto/hkdf.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function hkdfSync(hash, key, salt, info, length) {
134134
} = validateParameters(hash, key, salt, info, length));
135135

136136
const job = new HKDFJob(kCryptoJobSync, hash, key, salt, info, length);
137-
const [err, bits] = job.run();
137+
const { 0: err, 1: bits } = job.run();
138138
if (err !== undefined)
139139
throw err;
140140

Diff for: lib/internal/crypto/keygen.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const {
44
FunctionPrototypeCall,
55
ObjectDefineProperty,
6+
SafeArrayIterator,
67
} = primordials;
78

89
const {
@@ -75,7 +76,7 @@ function generateKeyPair(type, options, callback) {
7576
job.ondone = (error, result) => {
7677
if (error) return FunctionPrototypeCall(callback, job, error);
7778
// If no encoding was chosen, return key objects instead.
78-
let [pubkey, privkey] = result;
79+
let { 0: pubkey, 1: privkey } = result;
7980
pubkey = wrapKey(pubkey, PublicKeyObject);
8081
privkey = wrapKey(privkey, PrivateKeyObject);
8182
FunctionPrototypeCall(callback, job, null, pubkey, privkey);
@@ -97,11 +98,11 @@ function handleError(ret) {
9798
if (ret == null)
9899
return; // async
99100

100-
const [err, keys] = ret;
101+
const { 0: err, 1: keys } = ret;
101102
if (err !== undefined)
102103
throw err;
103104

104-
const [publicKey, privateKey] = keys;
105+
const { 0: publicKey, 1: privateKey } = keys;
105106

106107
// If no encoding was chosen, return key objects instead.
107108
return {
@@ -156,7 +157,7 @@ function parseKeyEncoding(keyType, options = {}) {
156157
function createJob(mode, type, options) {
157158
validateString(type, 'type');
158159

159-
const encoding = parseKeyEncoding(type, options);
160+
const encoding = new SafeArrayIterator(parseKeyEncoding(type, options));
160161

161162
if (options !== undefined)
162163
validateObject(options, 'options');
@@ -341,7 +342,7 @@ function handleGenerateKeyError(ret) {
341342
if (ret === undefined)
342343
return; // async
343344

344-
const [err, key] = ret;
345+
const { 0: err, 1: key } = ret;
345346
if (err !== undefined)
346347
throw err;
347348

Diff for: lib/internal/crypto/keys.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const {
44
ArrayFrom,
5+
ArrayPrototypeSlice,
56
ObjectDefineProperty,
67
ObjectSetPrototypeOf,
78
Symbol,
@@ -160,6 +161,11 @@ const [
160161
}
161162

162163
class AsymmetricKeyObject extends KeyObject {
164+
// eslint-disable-next-line no-useless-constructor
165+
constructor(type, handle) {
166+
super(type, handle);
167+
}
168+
163169
get asymmetricKeyType() {
164170
return this[kAsymmetricKeyType] ||
165171
(this[kAsymmetricKeyType] = this[kHandle].getAsymmetricKeyType());
@@ -390,13 +396,21 @@ function getKeyObjectHandle(key, ctx) {
390396
}
391397

392398
function getKeyTypes(allowKeyObject, bufferOnly = false) {
393-
return [
399+
const types = [
394400
'ArrayBuffer',
395401
'Buffer',
396402
'TypedArray',
397403
'DataView',
398-
...(!bufferOnly ? ['string'] : []),
399-
...(!bufferOnly && allowKeyObject ? ['KeyObject', 'CryptoKey'] : [])];
404+
'string', // Only if bufferOnly == false
405+
'KeyObject', // Only if allowKeyObject == true && bufferOnly == false
406+
'CryptoKey', // Only if allowKeyObject == true && bufferOnly == false
407+
];
408+
if (bufferOnly) {
409+
return ArrayPrototypeSlice(types, 0, 4);
410+
} else if (!allowKeyObject) {
411+
return ArrayPrototypeSlice(types, 0, 5);
412+
}
413+
return types;
400414
}
401415

402416
function prepareAsymmetricKey(key, ctx) {

Diff for: lib/internal/crypto/pbkdf2.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function pbkdf2Sync(password, salt, iterations, keylen, digest) {
7474
keylen,
7575
digest);
7676

77-
const [err, result] = job.run();
77+
const { 0: err, 1: result } = job.run();
7878
if (err !== undefined)
7979
throw err;
8080

Diff for: lib/internal/crypto/random.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function randomFillSync(buf, offset = 0, size) {
128128
offset,
129129
size);
130130

131-
const [ err ] = job.run();
131+
const err = job.run()[0];
132132
if (err)
133133
throw err;
134134

@@ -471,7 +471,7 @@ function generatePrimeSync(size, options = {}) {
471471
validateUint32(size, 'size', true);
472472

473473
const job = createRandomPrimeJob(kCryptoJobSync, size, options);
474-
const [err, prime] = job.run();
474+
const { 0: err, 1: prime } = job.run();
475475
if (err)
476476
throw err;
477477
return job.result(prime);
@@ -548,7 +548,7 @@ function checkPrimeSync(candidate, options = {}) {
548548
validateUint32(checks, 'options.checks');
549549

550550
const job = new CheckPrimeJob(kCryptoJobSync, candidate, checks);
551-
const [err, result] = job.run();
551+
const { 0: err, 1: result } = job.run();
552552
if (err)
553553
throw err;
554554

Diff for: lib/internal/crypto/rsa.js

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

33
const {
4+
ArrayPrototypePush,
45
Promise,
6+
ReflectApply,
57
SafeSet,
68
Uint8Array,
79
} = primordials;
@@ -71,29 +73,29 @@ const kRsaVariants = {
7173
};
7274

7375
function verifyAcceptableRsaKeyUse(name, type, usages) {
74-
let checkSet;
76+
const args = [usages];
7577
switch (name) {
7678
case 'RSA-OAEP':
7779
switch (type) {
7880
case 'private':
79-
checkSet = ['decrypt', 'unwrapKey'];
81+
ArrayPrototypePush(args, 'decrypt', 'unwrapKey');
8082
break;
8183
case 'public':
82-
checkSet = ['encrypt', 'wrapKey'];
84+
ArrayPrototypePush(args, 'encrypt', 'wrapKey');
8385
break;
8486
}
8587
break;
8688
default:
8789
switch (type) {
8890
case 'private':
89-
checkSet = ['sign'];
91+
ArrayPrototypePush(args, 'sign');
9092
break;
9193
case 'public':
92-
checkSet = ['verify'];
94+
ArrayPrototypePush(args, 'verify');
9395
break;
9496
}
9597
}
96-
if (hasAnyNotIn(usages, ...checkSet)) {
98+
if (ReflectApply(hasAnyNotIn, null, args)) {
9799
throw lazyDOMException(
98100
`Unsupported key usage for an ${name} key`,
99101
'SyntaxError');

Diff for: lib/internal/crypto/scrypt.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function scryptSync(password, salt, keylen, options = defaults) {
7474
({ password, salt, keylen } = options);
7575
const job = new ScryptJob(
7676
kCryptoJobSync, password, salt, N, r, p, maxmem, keylen);
77-
const [err, result] = job.run();
77+
const { 0: err, 1: result } = job.run();
7878

7979
if (err !== undefined)
8080
throw err;

0 commit comments

Comments
 (0)