Skip to content

Commit 2f678ea

Browse files
panvamarco-ippolito
authored andcommitted
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 0b985ec commit 2f678ea

File tree

8 files changed

+79
-20
lines changed

8 files changed

+79
-20
lines changed

lib/internal/crypto/aes.js

Lines changed: 6 additions & 1 deletion
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);

lib/internal/crypto/cfrg.js

Lines changed: 24 additions & 14 deletions
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,
@@ -277,22 +283,26 @@ async function cfrgImportKey(
277283
isPublic,
278284
usagesSet);
279285

280-
const publicKeyObject = createCFRGRawKey(
281-
name,
282-
Buffer.from(keyData.x, 'base64'),
283-
true);
284-
285-
if (isPublic) {
286-
keyObject = publicKeyObject;
287-
} else {
288-
keyObject = createCFRGRawKey(
286+
try {
287+
const publicKeyObject = createCFRGRawKey(
289288
name,
290-
Buffer.from(keyData.d, 'base64'),
291-
false);
292-
293-
if (!createPublicKey(keyObject).equals(publicKeyObject)) {
294-
throw lazyDOMException('Invalid JWK', 'DataError');
289+
Buffer.from(keyData.x, 'base64'),
290+
true);
291+
292+
if (isPublic) {
293+
keyObject = publicKeyObject;
294+
} else {
295+
keyObject = createCFRGRawKey(
296+
name,
297+
Buffer.from(keyData.d, 'base64'),
298+
false);
299+
300+
if (!createPublicKey(keyObject).equals(publicKeyObject)) {
301+
throw new ERR_CRYPTO_INVALID_JWK();
302+
}
295303
}
304+
} catch (err) {
305+
throw lazyDOMException('Invalid keyData', { name: 'DataError', cause: err });
296306
}
297307
break;
298308
}

lib/internal/crypto/ec.js

Lines changed: 8 additions & 2 deletions
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);

lib/internal/crypto/mac.js

Lines changed: 6 additions & 1 deletion
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
}

lib/internal/crypto/rsa.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,15 @@ async function rsaImportKey(
275275
}
276276

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

282288
keyObject = type === kKeyTypePrivate ?
283289
new PrivateKeyObject(handle) :

test/parallel/test-webcrypto-export-import-cfrg.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,15 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable)
322322
extractable,
323323
[/* empty usages */]),
324324
{ name: 'SyntaxError', message: 'Usages cannot be empty when importing a private key.' });
325+
326+
await assert.rejects(
327+
subtle.importKey(
328+
'jwk',
329+
{ kty: jwk.kty, /* missing x */ crv: jwk.crv },
330+
{ name },
331+
extractable,
332+
publicUsages),
333+
{ name: 'DataError', message: 'Invalid keyData' });
325334
}
326335

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

test/parallel/test-webcrypto-export-import-ec.js

Lines changed: 9 additions & 0 deletions
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) {

test/parallel/test-webcrypto-export-import-rsa.js

Lines changed: 9 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy