crypto: fix raw key export error for wrong key type · nodejs/node@53cde9d · GitHub
Skip to content

Commit 53cde9d

Browse files
koreahghgaduh95
authored andcommitted
crypto: fix raw key export error for wrong key type
Exporting a key in 'raw', 'raw-public' or 'raw-seed' format when the key type does not match (e.g. an ECDSA private key as 'raw', or an ML-KEM public key as 'raw-seed') fell through to the generic NotSupportedError. The Web Crypto and modern-algos export key steps require an InvalidAccessError in these cases. Mirror exportKeySpki() and exportKeyPkcs8(): select the exporter per algorithm first, then check the key type, and drop the type guards around the call sites in exportKeySync(). Formats an algorithm does not support (e.g. 'raw' for ML-DSA) still throw NotSupportedError. This also fixes wrapKey(), which uses the same export path. Assisted-by: a closed-source coding agent Signed-off-by: koreahghg <koreahghg@gmail.com> PR-URL: #66217 Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent cd16dcb commit 53cde9d

6 files changed

Lines changed: 84 additions & 29 deletions

‎lib/internal/crypto/webcrypto.js‎

Lines changed: 38 additions & 29 deletions

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ async function testImportPkcs8({ name, privateUsages }, extractable) {
172172
assert.strictEqual(
173173
Buffer.from(pkcs8).toString('hex'),
174174
keyData[name].pkcs8.toString('hex'));
175+
176+
for (const format of ['raw', 'raw-public']) {
177+
await assert.rejects(
178+
subtle.exportKey(format, key), {
179+
message: 'Key must be a public key',
180+
name: 'InvalidAccessError',
181+
});
182+
}
175183
} else {
176184
await assert.rejects(
177185
subtle.exportKey('pkcs8', key), {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ async function testImportPkcs8(
175175
message: 'Key must be a public key',
176176
name: 'InvalidAccessError',
177177
});
178+
179+
for (const format of ['raw', 'raw-public']) {
180+
await assert.rejects(
181+
subtle.exportKey(format, key), {
182+
message: 'Key must be a public key',
183+
name: 'InvalidAccessError',
184+
});
185+
}
178186
} else {
179187
await assert.rejects(
180188
subtle.exportKey('pkcs8', key), {

‎test/parallel/test-webcrypto-export-import-ml-dsa.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,11 @@ async function testImportRawPublic({ name, publicUsages }, extractable) {
414414
name: 'NotSupportedError',
415415
message: `Unable to export ${publicKey.algorithm.name} public key using raw format`,
416416
});
417+
418+
await assert.rejects(subtle.exportKey('raw-seed', publicKey), {
419+
name: 'InvalidAccessError',
420+
message: 'Key must be a private key',
421+
});
417422
}
418423

419424
await assert.rejects(
@@ -453,6 +458,11 @@ async function testImportRawSeed({ name, privateUsages }, extractable) {
453458
if (extractable) {
454459
const value = await subtle.exportKey('raw-seed', privateKey);
455460
assert.deepStrictEqual(Buffer.from(value), seed);
461+
462+
await assert.rejects(subtle.exportKey('raw-public', privateKey), {
463+
name: 'InvalidAccessError',
464+
message: 'Key must be a public key',
465+
});
456466
}
457467

458468
await assert.rejects(

‎test/parallel/test-webcrypto-export-import-ml-kem.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ async function testImportRawPublic({ name, publicUsages }, extractable) {
237237
name: 'NotSupportedError',
238238
message: `Unable to export ${publicKey.algorithm.name} public key using raw format`,
239239
});
240+
241+
await assert.rejects(subtle.exportKey('raw-seed', publicKey), {
242+
name: 'InvalidAccessError',
243+
message: 'Key must be a private key',
244+
});
240245
}
241246

242247
await assert.rejects(
@@ -276,6 +281,11 @@ async function testImportRawSeed({ name, privateUsages }, extractable) {
276281
if (extractable) {
277282
const value = await subtle.exportKey('raw-seed', privateKey);
278283
assert.deepStrictEqual(Buffer.from(value), seed);
284+
285+
await assert.rejects(subtle.exportKey('raw-public', privateKey), {
286+
name: 'InvalidAccessError',
287+
message: 'Key must be a public key',
288+
});
279289
}
280290

281291
await assert.rejects(

‎test/parallel/test-webcrypto-wrap-unwrap.js‎

Lines changed: 10 additions & 0 deletions

0 commit comments

Comments
 (0)