Skip to content

Commit 8752b60

Browse files
panvaaduh95
authored andcommitted
crypto: deduplicate and canonicalize CryptoKey usages
Fixes: #62899 Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: #62902 Backport-PR-URL: #63173 Fixes: #62899 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent aa1e0bc commit 8752b60

12 files changed

Lines changed: 599 additions & 25 deletions

File tree

lib/internal/crypto/aes.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
ArrayFrom,
54
ArrayPrototypePush,
65
SafeSet,
76
} = primordials;
@@ -205,7 +204,7 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) {
205204
return new InternalCryptoKey(
206205
key,
207206
{ name, length },
208-
ArrayFrom(usagesSet),
207+
usagesSet,
209208
extractable);
210209
}
211210

@@ -300,7 +299,7 @@ function aesImportKey(
300299
return new InternalCryptoKey(
301300
keyObject,
302301
{ name, length },
303-
keyUsages,
302+
usagesSet,
304303
extractable);
305304
}
306305

lib/internal/crypto/cfrg.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ async function cfrgGenerateKey(algorithm, extractable, keyUsages) {
171171
case 'X25519':
172172
// Fall through
173173
case 'X448':
174-
publicUsages = [];
174+
publicUsages = new SafeSet();
175175
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
176176
break;
177177
}
@@ -340,7 +340,7 @@ function cfrgImportKey(
340340
return new InternalCryptoKey(
341341
keyObject,
342342
{ name },
343-
keyUsages,
343+
usagesSet,
344344
extractable);
345345
}
346346

lib/internal/crypto/chacha20_poly1305.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
ArrayFrom,
54
SafeSet,
65
} = primordials;
76

@@ -76,7 +75,7 @@ async function c20pGenerateKey(algorithm, extractable, keyUsages) {
7675
return new InternalCryptoKey(
7776
createSecretKey(keyData),
7877
{ name },
79-
ArrayFrom(usagesSet),
78+
usagesSet,
8079
extractable);
8180
}
8281

@@ -155,7 +154,7 @@ function c20pImportKey(
155154
return new InternalCryptoKey(
156155
keyObject,
157156
{ name },
158-
keyUsages,
157+
usagesSet,
159158
extractable);
160159
}
161160

lib/internal/crypto/ec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) {
114114
privateUsages = getUsagesUnion(usageSet, 'sign');
115115
break;
116116
case 'ECDH':
117-
publicUsages = [];
117+
publicUsages = new SafeSet();
118118
privateUsages = getUsagesUnion(usageSet, 'deriveKey', 'deriveBits');
119119
break;
120120
}
@@ -280,7 +280,7 @@ function ecImportKey(
280280
return new InternalCryptoKey(
281281
keyObject,
282282
{ name, namedCurve },
283-
keyUsages,
283+
usagesSet,
284284
extractable);
285285
}
286286

lib/internal/crypto/keys.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const {
6262
bigIntArrayToUnsignedBigInt,
6363
normalizeAlgorithm,
6464
hasAnyNotIn,
65+
getSortedUsages,
6566
} = require('internal/crypto/util');
6667

6768
const {
@@ -1094,7 +1095,7 @@ class InternalCryptoKey {
10941095
keyObject,
10951096
algorithm,
10961097
extractable,
1097-
keyUsages,
1098+
getSortedUsages(new SafeSet(keyUsages)),
10981099
);
10991100
}
11001101
}
@@ -1160,7 +1161,7 @@ function importGenericSecretKey(
11601161
return undefined;
11611162
}
11621163

1163-
return new InternalCryptoKey(keyObject, { name }, keyUsages, false);
1164+
return new InternalCryptoKey(keyObject, { name }, usagesSet, false);
11641165
}
11651166

11661167
module.exports = {

lib/internal/crypto/mac.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const {
4-
ArrayFrom,
54
SafeSet,
65
StringPrototypeSubstring,
76
} = primordials;
@@ -76,7 +75,7 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
7675
return new InternalCryptoKey(
7776
key,
7877
{ name, length, hash },
79-
ArrayFrom(usageSet),
78+
usageSet,
8079
extractable);
8180
}
8281

@@ -110,7 +109,7 @@ async function kmacGenerateKey(algorithm, extractable, keyUsages) {
110109
return new InternalCryptoKey(
111110
createSecretKey(keyData),
112111
{ name, length },
113-
ArrayFrom(usageSet),
112+
usageSet,
114113
extractable);
115114
}
116115

@@ -211,7 +210,7 @@ function macImportKey(
211210
return new InternalCryptoKey(
212211
keyObject,
213212
algorithmObject,
214-
keyUsages,
213+
usagesSet,
215214
extractable);
216215
}
217216

lib/internal/crypto/ml_dsa.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ function mlDsaImportKey(
297297
return new InternalCryptoKey(
298298
keyObject,
299299
{ name },
300-
keyUsages,
300+
usagesSet,
301301
extractable);
302302
}
303303

lib/internal/crypto/ml_kem.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ async function mlKemGenerateKey(algorithm, extractable, keyUsages) {
6969
{ name: 'OperationError', cause: err });
7070
}
7171

72-
const publicUsages = getUsagesUnion(usageSet, 'encapsulateBits', 'encapsulateKey');
73-
const privateUsages = getUsagesUnion(usageSet, 'decapsulateBits', 'decapsulateKey');
72+
const publicUsages = getUsagesUnion(usageSet, 'encapsulateKey', 'encapsulateBits');
73+
const privateUsages = getUsagesUnion(usageSet, 'decapsulateKey', 'decapsulateBits');
7474

7575
const keyAlgorithm = { name };
7676

@@ -230,7 +230,7 @@ function mlKemImportKey(
230230
return new InternalCryptoKey(
231231
keyObject,
232232
{ name },
233-
keyUsages,
233+
usagesSet,
234234
extractable);
235235
}
236236

lib/internal/crypto/rsa.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ function rsaImportKey(
327327
modulusLength,
328328
publicExponent: new Uint8Array(publicExponent),
329329
hash: algorithm.hash,
330-
}, keyUsages, extractable);
330+
}, usagesSet, extractable);
331331
}
332332

333333
async function rsaSignVerify(key, data, { saltLength }, signature) {

lib/internal/crypto/util.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const {
44
ArrayBufferIsView,
55
ArrayBufferPrototypeGetByteLength,
6+
ArrayFrom,
67
ArrayPrototypeIncludes,
78
ArrayPrototypePush,
89
BigInt,
@@ -16,6 +17,7 @@ const {
1617
ObjectKeys,
1718
ObjectPrototypeHasOwnProperty,
1819
PromiseWithResolvers,
20+
SafeSet,
1921
StringPrototypeToUpperCase,
2022
Symbol,
2123
TypedArrayPrototypeGetBuffer,
@@ -706,14 +708,40 @@ function getStringOption(options, key) {
706708
}
707709

708710
function getUsagesUnion(usageSet, ...usages) {
709-
const newset = [];
711+
const newset = new SafeSet();
710712
for (let n = 0; n < usages.length; n++) {
711713
if (usageSet.has(usages[n]))
712-
ArrayPrototypePush(newset, usages[n]);
714+
newset.add(usages[n]);
713715
}
714716
return newset;
715717
}
716718

719+
const kCanonicalUsageOrder = new SafeSet([
720+
'encrypt', 'decrypt',
721+
'sign', 'verify',
722+
'deriveKey', 'deriveBits',
723+
'wrapKey', 'unwrapKey',
724+
'encapsulateKey', 'encapsulateBits',
725+
'decapsulateKey', 'decapsulateBits',
726+
]);
727+
728+
/**
729+
* Returns the usages from `usageSet` as an array in the canonical order
730+
* defined by {@link kCanonicalUsageOrder}.
731+
* @param {SafeSet<string>} usageSet
732+
* @returns {string[]}
733+
*/
734+
function getSortedUsages(usageSet) {
735+
if (usageSet.size <= 1) {
736+
return ArrayFrom(usageSet);
737+
}
738+
const result = [];
739+
for (const usage of kCanonicalUsageOrder) {
740+
if (usageSet.has(usage)) ArrayPrototypePush(result, usage);
741+
}
742+
return result;
743+
}
744+
717745
function getBlockSize(name) {
718746
switch (name) {
719747
case 'SHA-1':
@@ -830,6 +858,7 @@ module.exports = {
830858
getDigestSizeInBytes,
831859
getStringOption,
832860
getUsagesUnion,
861+
getSortedUsages,
833862
secureHeapUsed,
834863
getCachedHashId,
835864
getHashCache,

0 commit comments

Comments
 (0)