From a5895406784cd19b54094fc8182ce7699e5a45bd Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 9 Aug 2026 00:18:21 +0000 Subject: [PATCH] test: update WPT for WebCryptoAPI to 4c2fd05ed5 --- .../wpt/WebCryptoAPI/generateKey/failures.js | 140 +++++++++--------- .../failures_bad_algorithm.https.any.js | 5 + .../wpt/WebCryptoAPI/generateKey/successes.js | 21 +++ test/fixtures/wpt/versions.json | 2 +- 4 files changed, 98 insertions(+), 70 deletions(-) create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_bad_algorithm.https.any.js diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js index 2a618ce4ab25..e4a75c065152 100644 --- a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js @@ -1,6 +1,3 @@ -function run_test(algorithmNames) { - var subtle = crypto.subtle; // Change to test prefixed implementations - // These tests check that generateKey throws an error, and that // the error is of the right type, for a wide set of incorrect parameters. // @@ -19,42 +16,83 @@ function run_test(algorithmNames) { // helper functions that generate all possible test parameters for // different situations. - var testVectors = getGenerateKeyTestVectors(algorithmNames); +function parameterString(algorithm, extractable, usages) { + if (typeof algorithm !== "object" && typeof algorithm !== "string") { + alert(algorithm); + } + var result = "(" + + objectToString(algorithm) + ", " + + objectToString(extractable) + ", " + + objectToString(usages) + + ")"; - function parameterString(algorithm, extractable, usages) { - if (typeof algorithm !== "object" && typeof algorithm !== "string") { - alert(algorithm); - } + return result; +} - var result = "(" + - objectToString(algorithm) + ", " + - objectToString(extractable) + ", " + - objectToString(usages) + - ")"; +// Test that a given combination of parameters results in an error, +// AND that it is the correct kind of error. +// +// Expected error is either a number, tested against the error code, +// or a string, tested against the error name. +function testError(algorithm, extractable, usages, expectedError, testTag) { + promise_test(function(test) { + return crypto.subtle.generateKey(algorithm, extractable, usages) + .then(function(result) { + assert_unreached("Operation succeeded, but should not have"); + }, function(err) { + if (typeof expectedError === "number") { + assert_equals(err.code, expectedError, testTag + " not supported"); + } else { + assert_equals(err.name, expectedError, testTag + " not supported"); + } + }); + }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages)); +} - return result; - } - // Test that a given combination of parameters results in an error, - // AND that it is the correct kind of error. - // - // Expected error is either a number, tested against the error code, - // or a string, tested against the error name. - function testError(algorithm, extractable, usages, expectedError, testTag) { - promise_test(function(test) { - return crypto.subtle.generateKey(algorithm, extractable, usages) - .then(function(result) { - assert_unreached("Operation succeeded, but should not have"); - }, function(err) { - if (typeof expectedError === "number") { - assert_equals(err.code, expectedError, testTag + " not supported"); - } else { - assert_equals(err.name, expectedError, testTag + " not supported"); - } +// Algorithm normalization happens before generateKey looks at any other +// argument, so these cases are independent of the algorithm under test and +// only need to run once for the whole suite. +function run_bad_algorithm_test() { + // Algorithm normalization should fail with "Not supported" + var badAlgorithmNames = [ + "AES", + {name: "AES"}, + {name: "AES", length: 128}, + {name: "AES-CMAC", length: 128}, // Removed after CR + {name: "AES-CFB", length: 128}, // Removed after CR + {name: "HMAC", hash: "MD5"}, + {name: "RSA", hash: "SHA-256", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])}, + {name: "RSA-PSS", hash: "SHA", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])}, + {name: "EC", namedCurve: "P521"} + ]; + + + // Algorithm normalization failures should be found first + // - all other parameters can be good or bad, should fail + // due to NotSupportedError. + badAlgorithmNames.forEach(function(algorithm) { + allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used + .forEach(function(usages) { + [false, true, "RED", 7].forEach(function(extractable){ + testError(algorithm, extractable, usages, "NotSupportedError", "Bad algorithm"); }); - }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages)); - } + }); + }); + + // Empty algorithm should fail with TypeError + allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used + .forEach(function(usages) { + [false, true, "RED", 7].forEach(function(extractable){ + testError({}, extractable, usages, "TypeError", "Empty algorithm"); + }); + }); +} + + +function run_test(algorithmNames) { + var testVectors = getGenerateKeyTestVectors(algorithmNames); // Given an algorithm name, create several invalid parameters. @@ -108,45 +146,9 @@ function run_test(algorithmNames) { // Now test for properly handling errors -// - Unsupported algorithm // - Bad usages for algorithm // - Bad key lengths - // Algorithm normalization should fail with "Not supported" - var badAlgorithmNames = [ - "AES", - {name: "AES"}, - {name: "AES", length: 128}, - {name: "AES-CMAC", length: 128}, // Removed after CR - {name: "AES-CFB", length: 128}, // Removed after CR - {name: "HMAC", hash: "MD5"}, - {name: "RSA", hash: "SHA-256", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])}, - {name: "RSA-PSS", hash: "SHA", modulusLength: 2048, publicExponent: new Uint8Array([1,0,1])}, - {name: "EC", namedCurve: "P521"} - ]; - - - // Algorithm normalization failures should be found first - // - all other parameters can be good or bad, should fail - // due to NotSupportedError. - badAlgorithmNames.forEach(function(algorithm) { - allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used - .forEach(function(usages) { - [false, true, "RED", 7].forEach(function(extractable){ - testError(algorithm, extractable, usages, "NotSupportedError", "Bad algorithm"); - }); - }); - }); - - // Empty algorithm should fail with TypeError - allValidUsages(["decrypt", "sign", "deriveBits"], true, []) // Small search space, shouldn't matter because should fail before used - .forEach(function(usages) { - [false, true, "RED", 7].forEach(function(extractable){ - testError({}, extractable, usages, "TypeError", "Empty algorithm"); - }); - }); - - // Algorithms normalize okay, but usages bad (though not empty). // It shouldn't matter what other extractable is. Should fail // due to SyntaxError diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_bad_algorithm.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_bad_algorithm.https.any.js new file mode 100644 index 000000000000..5fe0b15784e3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_bad_algorithm.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_bad_algorithm_test(); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js index 5006cd35ad9c..c70ecb331873 100644 --- a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js @@ -110,6 +110,27 @@ function run_test(algorithmNames, slowTest) { assert_unreached("exportKey threw an unexpected error: " + err.toString()); }) }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages)); + + // Special case for ECDH and ECDSA: check that the generated key length is consistent. + // Particularly for P-521, there is a high risk of the generated key being one byte short + // if the implementation isn't careful. + if (algorithm.namedCurve && extractable) { + promise_test(async function(test) { + // We run about 20 variants of this test, times 10 key generations below, + // so this should have a decent chance of catching issues. + await Promise.all(Array.from({ length: 10 }).map(async () => { + const { privateKey, publicKey } = await subtle.generateKey(algorithm, extractable, usages); + const [jwkPub, jwkPriv] = await Promise.all([ + subtle.exportKey('jwk', publicKey), + subtle.exportKey('jwk', privateKey), + ]); + const expectedLength = Math.ceil(Math.ceil(parseInt(algorithm.namedCurve.substring(2)) / 8) * 4/3); + assert_equals(jwkPub.x.length, expectedLength, "Public key value x has correct length"); + assert_equals(jwkPub.y.length, expectedLength, "Public key value y has correct length"); + assert_equals(jwkPriv.d.length, expectedLength, "Private key value d has correct length"); + })); + }, testTag + ": generateKey" + parameterString(algorithm, extractable, usages) + " produces consistent length key"); + } } // Test all valid sets of parameters for successful diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 4c01b3e53663..70db85e75147 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -96,7 +96,7 @@ "path": "web-locks" }, "WebCryptoAPI": { - "commit": "82c3d9069cf2e93e5528a1f428fa122bd9af651d", + "commit": "4c2fd05ed5d0b90a9e1fcdcb35f6671bd461de0d", "path": "WebCryptoAPI" }, "webidl": {