From d51d18a6206dca5f3ee63a9960058241a1a6dd1a Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 14 Jun 2022 16:26:28 +0200 Subject: [PATCH] crypto: fix webcrypto AES-KW keys accepting encrypt/decrypt usages --- lib/internal/crypto/aes.js | 10 ++++++--- test/parallel/test-webcrypto-keygen.js | 29 ++++++++++++++------------ test/wpt/status/WebCryptoAPI.json | 1 - 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/internal/crypto/aes.js b/lib/internal/crypto/aes.js index 2c74a49139a70a..324662e1f8b1b4 100644 --- a/lib/internal/crypto/aes.js +++ b/lib/internal/crypto/aes.js @@ -230,13 +230,17 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) { validateInteger(length, 'algorithm.length'); validateOneOf(length, 'algorithm.length', kAesKeyLengths); - const usageSet = new SafeSet(keyUsages); + const checkUsages = ['wrapKey', 'unwrapKey']; + if (name !== 'AES-KW') + ArrayPrototypePush(checkUsages, 'encrypt', 'decrypt'); - if (hasAnyNotIn(usageSet, ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'])) { + const usagesSet = new SafeSet(keyUsages); + if (hasAnyNotIn(usagesSet, checkUsages)) { throw lazyDOMException( 'Unsupported key usage for an AES key', 'SyntaxError'); } + return new Promise((resolve, reject) => { generateKey('aes', { length }, (err, key) => { if (err) { @@ -249,7 +253,7 @@ async function aesGenerateKey(algorithm, extractable, keyUsages) { resolve(new InternalCryptoKey( key, { name, length }, - ArrayFrom(usageSet), + ArrayFrom(usagesSet), extractable)); }); }); diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index ec8973bd988cde..2649bf5858c8c9 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -206,11 +206,6 @@ const vectors = { // Test bad usages { async function test(name) { - const invalidUsages = []; - allUsages.forEach((usage) => { - if (!vectors[name].usages.includes(usage)) - invalidUsages.push(usage); - }); await assert.rejects( subtle.generateKey( { @@ -219,14 +214,22 @@ const vectors = { true, []), { message: /Usages cannot be empty/ }); - return assert.rejects( - subtle.generateKey( - { - name, ...vectors[name].algorithm - }, - true, - invalidUsages), - { message: /Unsupported key usage/ }); + + const invalidUsages = []; + allUsages.forEach((usage) => { + if (!vectors[name].usages.includes(usage)) + invalidUsages.push(usage); + }); + for (const invalidUsage of invalidUsages) { + await assert.rejects( + subtle.generateKey( + { + name, ...vectors[name].algorithm + }, + true, + [...vectors[name].usages, invalidUsage]), + { message: /Unsupported key usage/ }); + } } const tests = Object.keys(vectors).map(test); diff --git a/test/wpt/status/WebCryptoAPI.json b/test/wpt/status/WebCryptoAPI.json index d1cefbc1de1906..64b56e1d846089 100644 --- a/test/wpt/status/WebCryptoAPI.json +++ b/test/wpt/status/WebCryptoAPI.json @@ -48,7 +48,6 @@ "generateKey/failures_AES-KW.https.any.js": { "fail": { "unexpected": [ - "assert_unreached: Operation succeeded, but should not have Reached unreachable code", "assert_equals: Bad algorithm property not supported expected \"OperationError\" but got \"TypeError\"", "assert_equals: Bad algorithm property not supported expected \"OperationError\" but got \"SyntaxError\"" ]