diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js index 826610a5fd6b8e..5dd4e44bdd06cc 100644 --- a/lib/internal/crypto/cfrg.js +++ b/lib/internal/crypto/cfrg.js @@ -242,6 +242,8 @@ async function cfrgImportKey( throw lazyDOMException('Invalid JWK keyData', 'DataError'); if (keyData.kty !== 'OKP') throw lazyDOMException('Invalid key type', 'DataError'); + if (keyData.crv !== name) + throw lazyDOMException('Subtype mismatch', 'DataError'); const isPublic = keyData.d === undefined; if (usagesSet.size > 0 && keyData.use !== undefined) { diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js index 980c0f57cb046e..809f531069bf8b 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -195,11 +195,12 @@ async function ecImportKey( break; } case 'jwk': { - let curve; if (keyData == null || typeof keyData !== 'object') throw lazyDOMException('Invalid JWK keyData', 'DataError'); if (keyData.kty !== 'EC') throw lazyDOMException('Invalid key type', 'DataError'); + if (keyData.crv !== namedCurve) + throw lazyDOMException('Named curve mismatch', 'DataError'); if (keyData.d !== undefined) { verifyAcceptableEcKeyUse(name, 'private', usagesSet); @@ -225,12 +226,13 @@ async function ecImportKey( if (algorithm.name === 'ECDSA' && keyData.alg !== undefined) { if (typeof keyData.alg !== 'string') throw lazyDOMException('Invalid alg', 'DataError'); + let algNamedCurve; switch (keyData.alg) { - case 'ES256': curve = 'P-256'; break; - case 'ES384': curve = 'P-384'; break; - case 'ES512': curve = 'P-521'; break; + case 'ES256': algNamedCurve = 'P-256'; break; + case 'ES384': algNamedCurve = 'P-384'; break; + case 'ES512': algNamedCurve = 'P-521'; break; } - if (curve !== namedCurve) + if (algNamedCurve !== namedCurve) throw lazyDOMException('Named curve mismatch', 'DataError'); } diff --git a/test/parallel/test-webcrypto-export-import-cfrg.js b/test/parallel/test-webcrypto-export-import-cfrg.js index c37c1535747917..531cb51c1b8b8c 100644 --- a/test/parallel/test-webcrypto-export-import-cfrg.js +++ b/test/parallel/test-webcrypto-export-import-cfrg.js @@ -259,6 +259,26 @@ async function testImportJwk({ name, publicUsages, privateUsages }, extractable) message: /key is not extractable/ }); } + + for (const crv of [undefined, name === 'Ed25519' ? 'Ed448' : 'Ed25519']) { + await assert.rejects( + subtle.importKey( + 'jwk', + { kty: jwk.kty, x: jwk.x, y: jwk.y, crv }, + { name }, + extractable, + publicUsages), + { message: /Subtype mismatch/ }); + + await assert.rejects( + subtle.importKey( + 'jwk', + { kty: jwk.kty, d: jwk.d, x: jwk.x, y: jwk.y, crv }, + { name }, + extractable, + publicUsages), + { message: /Subtype mismatch/ }); + } } (async function() { diff --git a/test/parallel/test-webcrypto-export-import-ec.js b/test/parallel/test-webcrypto-export-import-ec.js index 264e6691db2144..79f82a3d4adc26 100644 --- a/test/parallel/test-webcrypto-export-import-ec.js +++ b/test/parallel/test-webcrypto-export-import-ec.js @@ -260,6 +260,26 @@ async function testImportJwk( message: /key is not extractable/ }); } + + for (const crv of [undefined, namedCurve === 'P-256' ? 'P-384' : 'P-256']) { + await assert.rejects( + subtle.importKey( + 'jwk', + { kty: jwk.kty, x: jwk.x, y: jwk.y, crv }, + { name, namedCurve }, + extractable, + publicUsages), + { message: /Named curve mismatch/ }); + + await assert.rejects( + subtle.importKey( + 'jwk', + { kty: jwk.kty, d: jwk.d, x: jwk.x, y: jwk.y, crv }, + { name, namedCurve }, + extractable, + publicUsages), + { message: /Named curve mismatch/ }); + } } async function testImportRaw({ name, publicUsages }, namedCurve) {