Skip to content

Commit c50f013

Browse files
panvaaduh95
authored andcommittedNov 2, 2024
crypto: ensure invalid SubtleCrypto JWK data import results in DataError
PR-URL: #55041 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 4a18581 commit c50f013

File tree

8 files changed

+79
-20
lines changed

8 files changed

+79
-20
lines changed
 

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,12 @@ async function aesImportKey(
296296
}
297297

298298
const handle = new KeyObjectHandle();
299-
handle.initJwk(keyData);
299+
try {
300+
handle.initJwk(keyData);
301+
} catch (err) {
302+
throw lazyDOMException(
303+
'Invalid keyData', { name: 'DataError', cause: err });
304+
}
300305

301306
({ length } = handle.keyDetail({ }));
302307
validateKeyLength(length);

Diff for: ‎lib/internal/crypto/cfrg.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ const {
1717
kSignJobModeVerify,
1818
} = internalBinding('crypto');
1919

20+
const {
21+
codes: {
22+
ERR_CRYPTO_INVALID_JWK,
23+
},
24+
} = require('internal/errors');
25+
2026
const {
2127
getUsagesUnion,
2228
hasAnyNotIn,
@@ -292,22 +298,26 @@ async function cfrgImportKey(
292298
isPublic,
293299
usagesSet);
294300

295-
const publicKeyObject = createCFRGRawKey(
296-
name,
297-
Buffer.from(keyData.x, 'base64'),
298-
true);
299-
300-
if (isPublic) {
301-
keyObject = publicKeyObject;
302-
} else {
303-
keyObject = createCFRGRawKey(
301+
try {
302+
const publicKeyObject = createCFRGRawKey(
304303
name,
305-
Buffer.from(keyData.d, 'base64'),
306-
false);
307-
308-
if (!createPublicKey(keyObject).equals(publicKeyObject)) {
309-
throw lazyDOMException('Invalid JWK', 'DataError');
304+
Buffer.from(keyData.x, 'base64'),
305+
true);
306+
307+
if (isPublic) {
308+
keyObject = publicKeyObject;
309+
} else {
310+
keyObject = createCFRGRawKey(
311+
name,
312+
Buffer.from(keyData.d, 'base64'),
313+
false);
314+
315+
if (!createPublicKey(keyObject).equals(publicKeyObject)) {
316+
throw new ERR_CRYPTO_INVALID_JWK();
317+
}
310318
}
319+
} catch (err) {
320+
throw lazyDOMException('Invalid keyData', { name: 'DataError', cause: err });
311321
}
312322
break;
313323
}

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,15 @@ async function ecImportKey(
240240
}
241241

242242
const handle = new KeyObjectHandle();
243-
const type = handle.initJwk(keyData, namedCurve);
243+
let type;
244+
try {
245+
type = handle.initJwk(keyData, namedCurve);
246+
} catch (err) {
247+
throw lazyDOMException(
248+
'Invalid keyData', { name: 'DataError', cause: err });
249+
}
244250
if (type === undefined)
245-
throw lazyDOMException('Invalid JWK', 'DataError');
251+
throw lazyDOMException('Invalid keyData', 'DataError');
246252
keyObject = type === kKeyTypePrivate ?
247253
new PrivateKeyObject(handle) :
248254
new PublicKeyObject(handle);

Diff for: ‎lib/internal/crypto/mac.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,12 @@ async function hmacImportKey(
145145
}
146146

147147
const handle = new KeyObjectHandle();
148-
handle.initJwk(keyData);
148+
try {
149+
handle.initJwk(keyData);
150+
} catch (err) {
151+
throw lazyDOMException(
152+
'Invalid keyData', { name: 'DataError', cause: err });
153+
}
149154
keyObject = new SecretKeyObject(handle);
150155
break;
151156
}

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,15 @@ async function rsaImportKey(
273273
}
274274

275275
const handle = new KeyObjectHandle();
276-
const type = handle.initJwk(keyData);
276+
let type;
277+
try {
278+
type = handle.initJwk(keyData);
279+
} catch (err) {
280+
throw lazyDOMException(
281+
'Invalid keyData', { name: 'DataError', cause: err });
282+
}
277283
if (type === undefined)
278-
throw lazyDOMException('Invalid JWK', 'DataError');
284+
throw lazyDOMException('Invalid keyData', 'DataError');
279285

280286
keyObject = type === kKeyTypePrivate ?
281287
new PrivateKeyObject(handle) :

Diff for: ‎test/parallel/test-webcrypto-export-import-cfrg.js

+9
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable)
329329
extractable,
330330
[/* empty usages */]),
331331
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' });
332+
333+
await assert.rejects(
334+
subtle.importKey(
335+
'jwk',
336+
{ kty: jwk.kty, /* missing x */ crv: jwk.crv },
337+
{ name },
338+
extractable,
339+
publicUsages),
340+
{ name: 'DataError', message: 'Invalid keyData' });
332341
}
333342

334343
async function testImportRaw({ name, publicUsages }) {

Diff for: ‎test/parallel/test-webcrypto-export-import-ec.js

+9
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,15 @@ async function testImportJwk(
330330
extractable,
331331
[/* empty usages */]),
332332
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' });
333+
334+
await assert.rejects(
335+
subtle.importKey(
336+
'jwk',
337+
{ kty: jwk.kty, /* missing x */ y: jwk.y, crv: jwk.crv },
338+
{ name, namedCurve },
339+
extractable,
340+
publicUsages),
341+
{ name: 'DataError', message: 'Invalid keyData' });
333342
}
334343

335344
async function testImportRaw({ name, publicUsages }, namedCurve) {

Diff for: ‎test/parallel/test-webcrypto-export-import-rsa.js

+9
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,15 @@ async function testImportJwk(
513513
extractable,
514514
[/* empty usages */]),
515515
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' });
516+
517+
await assert.rejects(
518+
subtle.importKey(
519+
'jwk',
520+
{ kty: jwk.kty, /* missing e */ n: jwk.n },
521+
{ name, hash },
522+
extractable,
523+
publicUsages),
524+
{ name: 'DataError', message: 'Invalid keyData' });
516525
}
517526

518527
// combinations to test

0 commit comments

Comments
 (0)
Please sign in to comment.