Skip to content

Commit ff6027d

Browse files
panvanodejs-github-bot
authored andcommitted
crypto: reject duplicate unknown key usages
Check all JWK key_ops entries for duplicates before ignoring unknown usage names. 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 7c20a5c commit ff6027d

2 files changed

Lines changed: 24 additions & 3 deletions

File tree

‎lib/internal/crypto/util.js‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,15 +1220,16 @@ function validateKeyOps(keyOps, usagesSet) {
12201220
if (keyOps === undefined) return;
12211221
validateArray(keyOps, 'keyData.key_ops');
12221222
let keyOpsMask = 0;
1223+
const seen = new SafeSet();
12231224
for (let n = 0; n < keyOps.length; n++) {
12241225
const op = keyOps[n];
1226+
if (seen.has(op))
1227+
throw lazyDOMException('Duplicate key operation', 'DataError');
1228+
seen.add(op);
12251229
const opMask = kUsageMasks[op];
12261230
// Skipping unknown key ops
12271231
if (opMask === undefined)
12281232
continue;
1229-
// Have we seen it already? if so, error
1230-
if (keyOpsMask & opMask)
1231-
throw lazyDOMException('Duplicate key operation', 'DataError');
12321233
keyOpsMask |= opMask;
12331234

12341235
// TODO(@jasnell): RFC7517 section 4.3 strong recommends validating
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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 { subtle } = globalThis.crypto;
9+
10+
(async () => {
11+
const algorithm = { name: 'HMAC', hash: 'SHA-256' };
12+
const jwk = { kty: 'oct', k: 'AAAAAAAAAAAAAAAAAAAAAA' };
13+
await subtle.importKey('jwk', { ...jwk, key_ops: ['sign', 'future'] },
14+
algorithm, false, ['sign']);
15+
for (const key_ops of [['sign', 'sign'], ['sign', 'future', 'future']]) {
16+
await assert.rejects(subtle.importKey('jwk', { ...jwk, key_ops },
17+
algorithm, false, ['sign']),
18+
{ name: 'DataError' });
19+
}
20+
})().then(common.mustCall());

0 commit comments

Comments
 (0)