From 2d964d9ca48259f2f69084b65b24d996f9c95850 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Wed, 8 Jun 2022 13:38:24 +0200 Subject: [PATCH] crypto: fix webcrypto JWK EC and OKP import crv check --- lib/internal/crypto/cfrg.js | 2 ++ lib/internal/crypto/ec.js | 12 ++++++----- .../test-webcrypto-export-import-cfrg.js | 20 +++++++++++++++++++ .../test-webcrypto-export-import-ec.js | 20 +++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js index 041f2d824a79bf..e492c04dc3a317 100644 --- a/lib/internal/crypto/cfrg.js +++ b/lib/internal/crypto/cfrg.js @@ -258,6 +258,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 f7614b8f5d78d4..8c5a7b25ee0f6f 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -206,11 +206,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); @@ -236,12 +237,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 9f73701ad246e8..4c80fbc5393de8 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 682d5f54be5563..90eece2ffdfd1f 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() {