From a3212380a873d2ccbad25cf2f86dad2da9fd3eed Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 21 Nov 2022 23:14:06 +0100 Subject: [PATCH] crypto: fix X25519 and X448 webcrypto public CryptoKey usages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/45569 Reviewed-By: Antoine du Hamel Reviewed-By: Tobias Nießen Backport-PR-URL: https://github.com/nodejs/node/pull/47336 --- lib/internal/crypto/cfrg.js | 9 ++++++++- test/parallel/test-webcrypto-derivebits-cfrg.js | 8 ++++---- test/parallel/test-webcrypto-derivekey-cfrg.js | 12 ++++++------ test/parallel/test-webcrypto-export-import-cfrg.js | 12 ++++++------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js index 7b825fc93e0669..37fc5c5fcf2b8e 100644 --- a/lib/internal/crypto/cfrg.js +++ b/lib/internal/crypto/cfrg.js @@ -53,7 +53,14 @@ function verifyAcceptableCfrgKeyUse(name, type, usages) { case 'X25519': // Fall through case 'X448': - checkSet = ['deriveKey', 'deriveBits']; + switch (type) { + case 'private': + checkSet = ['deriveKey', 'deriveBits']; + break; + case 'public': + checkSet = []; + break; + } break; case 'Ed25519': // Fall through diff --git a/test/parallel/test-webcrypto-derivebits-cfrg.js b/test/parallel/test-webcrypto-derivebits-cfrg.js index 2233d1a2d274c7..1324a5fecc4c87 100644 --- a/test/parallel/test-webcrypto-derivebits-cfrg.js +++ b/test/parallel/test-webcrypto-derivebits-cfrg.js @@ -52,7 +52,7 @@ async function prepareKeys() { Buffer.from(spki, 'hex'), { name }, true, - ['deriveKey', 'deriveBits']), + []), ]); keys[name] = { privateKey, @@ -180,7 +180,7 @@ async function prepareKeys() { name: 'X448', public: keys.X448.publicKey }, keys.X448.publicKey, null), { - message: /baseKey must be a private key/ + name: 'InvalidAccessError' }); } @@ -190,7 +190,7 @@ async function prepareKeys() { name: 'X448', public: keys.X448.privateKey }, keys.X448.publicKey, null), { - message: /algorithm\.public must be a public key/ + name: 'InvalidAccessError' }); } @@ -207,7 +207,7 @@ async function prepareKeys() { name: 'X448', public: key }, keys.X448.publicKey, null), { - message: /algorithm\.public must be a public key/ + name: 'InvalidAccessError' }); } })().then(common.mustCall()); diff --git a/test/parallel/test-webcrypto-derivekey-cfrg.js b/test/parallel/test-webcrypto-derivekey-cfrg.js index ddf51626a89b4b..90289c98efd5d5 100644 --- a/test/parallel/test-webcrypto-derivekey-cfrg.js +++ b/test/parallel/test-webcrypto-derivekey-cfrg.js @@ -51,7 +51,7 @@ async function prepareKeys() { Buffer.from(spki, 'hex'), { name }, true, - ['deriveKey', 'deriveBits']), + []), ]); keys[name] = { privateKey, @@ -150,20 +150,20 @@ async function prepareKeys() { }, keys.X448.publicKey, ...otherArgs), - { message: /baseKey must be a private key/ }); + { name: 'InvalidAccessError' }); } { - // Base key is not a private key + // Public is not a public key await assert.rejects( subtle.deriveKey( { name: 'X448', public: keys.X448.privateKey }, - keys.X448.publicKey, + keys.X448.privateKey, ...otherArgs), - { message: /algorithm\.public must be a public key/ }); + { name: 'InvalidAccessError' }); } { @@ -183,6 +183,6 @@ async function prepareKeys() { }, keys.X448.publicKey, ...otherArgs), - { message: /algorithm\.public must be a public key/ }); + { name: 'InvalidAccessError' }); } })().then(common.mustCall()); diff --git a/test/parallel/test-webcrypto-export-import-cfrg.js b/test/parallel/test-webcrypto-export-import-cfrg.js index 6d162ac61c2e30..af6a7956e6716a 100644 --- a/test/parallel/test-webcrypto-export-import-cfrg.js +++ b/test/parallel/test-webcrypto-export-import-cfrg.js @@ -315,19 +315,19 @@ async function testImportRaw({ name, publicUsages }) { const rsaPrivate = crypto.createPrivateKey( fixtures.readKey('rsa_private_2048.pem')); - for (const [name, [publicUsage, privateUsage]] of Object.entries({ - 'Ed25519': ['verify', 'sign'], - 'X448': ['deriveBits', 'deriveBits'], - })) { + for (const [name, publicUsages, privateUsages] of [ + ['Ed25519', ['verify'], ['sign']], + ['X448', [], ['deriveBits']], + ]) { assert.rejects(subtle.importKey( 'spki', rsaPublic.export({ format: 'der', type: 'spki' }), { name }, - true, [publicUsage]), { message: /Invalid key type/ }); + true, publicUsages), { message: /Invalid key type/ }); assert.rejects(subtle.importKey( 'pkcs8', rsaPrivate.export({ format: 'der', type: 'pkcs8' }), { name }, - true, [privateUsage]), { message: /Invalid key type/ }); + true, privateUsages), { message: /Invalid key type/ }); } }