From 314cd8015f9394f8c099fd06006378c13f36295d Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 16 Sep 2021 22:03:15 +0200 Subject: [PATCH] crypto: fix webcrypto ed(25519|448) spki/pkcs8 import --- lib/internal/crypto/ec.js | 30 ++++++-------- test/parallel/test-webcrypto-ed25519-ed448.js | 14 +++++++ test/parallel/test-webcrypto-x25519-x448.js | 39 ++++++++++++++----- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js index 1ebceadf50f399..8843ed0976789a 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -269,14 +269,12 @@ async function ecImportKey( case 'NODE-X25519': // Fall through case 'NODE-X448': - checkNamedCurve = false; if (algorithm.name !== 'ECDH') throw lazyDOMException('Invalid algorithm name.', 'DataError'); break; case 'NODE-ED25519': // Fall through case 'NODE-ED448': - checkNamedCurve = false; if (algorithm.name !== namedCurve) throw lazyDOMException('Invalid algorithm name.', 'DataError'); break; @@ -310,7 +308,6 @@ async function ecImportKey( throw lazyDOMException('Invalid JWK keyData', 'DataError'); switch (keyData.kty) { case 'OKP': { - checkNamedCurve = false; const isPublic = keyData.d === undefined; let type; @@ -395,7 +392,6 @@ async function ecImportKey( case 'NODE-X25519': // Fall through case 'NODE-X448': - checkNamedCurve = false; if (algorithm.public !== undefined) validateBoolean(algorithm.public, 'algorithm.public'); if (algorithm.name !== 'ECDH') @@ -409,7 +405,6 @@ async function ecImportKey( case 'NODE-ED25519': // Fall through case 'NODE-ED448': - checkNamedCurve = false; if (algorithm.public !== undefined) validateBoolean(algorithm.public, 'algorithm.public'); if (algorithm.name !== namedCurve) @@ -436,30 +431,27 @@ async function ecImportKey( throw lazyDOMException('Invalid key type', 'DataError'); break; case 'ECDH': - if ( - algorithm.namedCurve === 'NODE-X25519' && - keyObject.asymmetricKeyType !== 'x25519' - ) { - throw lazyDOMException('Invalid key type', 'DataError'); - } else if ( - algorithm.namedCurve === 'NODE-X448' && - keyObject.asymmetricKeyType !== 'x448' - ) { - throw lazyDOMException('Invalid key type', 'DataError'); - } else if ( - algorithm.namedCurve.startsWith('P') && - keyObject.asymmetricKeyType !== 'ec' - ) { + if (algorithm.namedCurve === 'NODE-X25519') { + if (keyObject.asymmetricKeyType !== 'x25519') + throw lazyDOMException('Invalid key type', 'DataError'); + checkNamedCurve = false + } else if (algorithm.namedCurve === 'NODE-X448') { + if (keyObject.asymmetricKeyType !== 'x448') + throw lazyDOMException('Invalid key type', 'DataError'); + checkNamedCurve = false + } else if (keyObject.asymmetricKeyType !== 'ec') { throw lazyDOMException('Invalid key type', 'DataError'); } break; case 'NODE-ED25519': if (keyObject.asymmetricKeyType !== 'ed25519') throw lazyDOMException('Invalid key type', 'DataError'); + checkNamedCurve = false; break; case 'NODE-ED448': if (keyObject.asymmetricKeyType !== 'ed448') throw lazyDOMException('Invalid key type', 'DataError'); + checkNamedCurve = false; break; } diff --git a/test/parallel/test-webcrypto-ed25519-ed448.js b/test/parallel/test-webcrypto-ed25519-ed448.js index 9c60ceff64b1b4..f03cec9183efa8 100644 --- a/test/parallel/test-webcrypto-ed25519-ed448.js +++ b/test/parallel/test-webcrypto-ed25519-ed448.js @@ -382,6 +382,20 @@ assert.rejects( assert.strictEqual(cryptoKey.algorithm.name, namedCurve); }, common.mustNotCall()); + subtle.importKey( + keyObject.type === 'private' ? 'pkcs8' : 'spki', + keyObject.export({ + format: 'der', + type: keyObject.type === 'private' ? 'pkcs8' : 'spki', + }), + { name: namedCurve, namedCurve }, + true, + keyObject.type === 'private' ? ['sign'] : ['verify'], + ).then((cryptoKey) => { + assert.strictEqual(cryptoKey.type, keyObject.type); + assert.strictEqual(cryptoKey.algorithm.name, namedCurve); + }, common.mustNotCall()); + assert.rejects( subtle.importKey( 'node.keyObject', diff --git a/test/parallel/test-webcrypto-x25519-x448.js b/test/parallel/test-webcrypto-x25519-x448.js index cd079b5fb80a5e..101767ed194735 100644 --- a/test/parallel/test-webcrypto-x25519-x448.js +++ b/test/parallel/test-webcrypto-x25519-x448.js @@ -285,16 +285,35 @@ assert.rejects( const { publicKey, privateKey } = generateKeyPairSync(asymmetricKeyType); for (const keyObject of [publicKey, privateKey]) { const namedCurve = `NODE-${asymmetricKeyType.toUpperCase()}`; - subtle.importKey( - 'node.keyObject', - keyObject, - { name: 'ECDH', namedCurve }, - true, - keyObject.type === 'private' ? ['deriveBits', 'deriveKey'] : [], - ).then((cryptoKey) => { - assert.strictEqual(cryptoKey.type, keyObject.type); - assert.strictEqual(cryptoKey.algorithm.name, 'ECDH'); - }, common.mustNotCall()); + { + subtle.importKey( + 'node.keyObject', + keyObject, + { name: 'ECDH', namedCurve }, + true, + keyObject.type === 'private' ? ['deriveBits', 'deriveKey'] : [], + ).then((cryptoKey) => { + assert.strictEqual(cryptoKey.type, keyObject.type); + assert.strictEqual(cryptoKey.algorithm.name, 'ECDH'); + }, common.mustNotCall()); + } + + { + subtle.importKey( + keyObject.type === 'private' ? 'pkcs8' : 'spki', + keyObject.export({ + format: 'der', + type: keyObject.type === 'private' ? 'pkcs8' : 'spki', + }), + { name: namedCurve, namedCurve }, + true, + keyObject.type === 'private' ? ['deriveBits'] : [], + ).then((cryptoKey) => { + assert.strictEqual(cryptoKey.type, keyObject.type); + assert.strictEqual(cryptoKey.algorithm.name, 'ECDH'); + assert.strictEqual(cryptoKey.algorithm.namedCurve, namedCurve); + }, common.mustNotCall()); + } } } }