From 0e187e4a21d40323dce65fc9697c986481d46f23 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 22 Sep 2024 15:52:56 +0200 Subject: [PATCH] test,crypto: update WebCryptoAPI WPT PR-URL: https://github.com/nodejs/node/pull/55029 Reviewed-By: Luigi Pinca Reviewed-By: Jake Yuesong Li Reviewed-By: James M Snell --- test/fixtures/wpt/README.md | 2 +- .../derive_bits_keys/cfrg_curves_bits.js | 48 +-- .../cfrg_curves_bits_curve25519.https.any.js | 10 + ...=> cfrg_curves_bits_curve448.https.any.js} | 4 +- .../cfrg_curves_bits_fixtures.js | 3 + .../derive_bits_keys/cfrg_curves_keys.js | 51 ++-- .../cfrg_curves_keys_curve25519.https.any.js | 10 + ...=> cfrg_curves_keys_curve448.https.any.js} | 2 +- .../import_export/okp_importKey.https.any.js | 280 ------------------ .../import_export/okp_importKey.js | 209 +++++++++++++ .../okp_importKey_Ed25519.https.any.js | 9 + .../okp_importKey_Ed448.https.any.js | 9 + .../okp_importKey_X25519.https.any.js | 9 + .../okp_importKey_X448.https.any.js | 9 + .../import_export/okp_importKey_fixtures.js | 58 ++++ .../wpt/WebCryptoAPI/sign_verify/eddsa.js | 4 +- .../sign_verify/eddsa_curve25519.https.any.js | 6 + ...tps.any.js => eddsa_curve448.https.any.js} | 2 +- .../WebCryptoAPI/sign_verify/eddsa_vectors.js | 6 +- test/fixtures/wpt/versions.json | 2 +- 20 files changed, 405 insertions(+), 328 deletions(-) create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js rename test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/{cfrg_curves_bits.https.any.js => cfrg_curves_bits_curve448.https.any.js} (75%) create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js rename test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/{cfrg_curves_keys.https.any.js => cfrg_curves_keys_curve448.https.any.js} (89%) delete mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_Ed25519.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_Ed448.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_X25519.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_X448.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey_fixtures.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/eddsa_curve25519.https.any.js rename test/fixtures/wpt/WebCryptoAPI/sign_verify/{eddsa.https.any.js => eddsa_curve448.https.any.js} (88%) diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index ad9d401380b..eacd81cd69f 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -32,7 +32,7 @@ Last update: - user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/272064ebf9/WebCryptoAPI +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/203d2ac459/WebCryptoAPI - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions - webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/e97fac4791/webmessaging/broadcastchannel - webstorage: https://github.com/web-platform-tests/wpt/tree/9dafa89214/webstorage diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js index da809278a87..8ab9db7bf71 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.js @@ -1,12 +1,19 @@ +function define_tests_25519() { + return define_tests("X25519"); +} -function define_tests() { +function define_tests_448() { + return define_tests("X448"); +} + +function define_tests(algorithmName) { // May want to test prefixed implementations. var subtle = self.crypto.subtle; // Verify the derive functions perform checks against the all-zero value results, // ensuring small-order points are rejected. // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 - Object.keys(kSmallOrderPoint).forEach(function(algorithmName) { + { kSmallOrderPoint[algorithmName].forEach(function(test) { promise_test(async() => { let derived; @@ -28,15 +35,16 @@ function define_tests() { assert_equals(derived, undefined, "Operation succeeded, but should not have."); }, algorithmName + " key derivation checks for all-zero value result with a key of order " + test.order); }); - }); + } return importKeys(pkcs8, spki, sizes) .then(function(results) { publicKeys = results.publicKeys; privateKeys = results.privateKeys; noDeriveBitsKeys = results.noDeriveBitsKeys; + ecdhKeys = results.ecdhKeys; - Object.keys(sizes).forEach(function(algorithmName) { + { // Basic success case promise_test(function(test) { return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) @@ -101,11 +109,7 @@ function define_tests() { // - wrong algorithm promise_test(function(test) { - publicKey = publicKeys["X25519"]; - if (algorithmName === "X25519") { - publicKey = publicKeys["X448"]; - } - return subtle.deriveBits({name: algorithmName, public: publicKey}, privateKeys[algorithmName], 8 * sizes[algorithmName]) + return subtle.deriveBits({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) .then(function(derivation) { assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); }, function(err) { @@ -165,16 +169,17 @@ function define_tests() { assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message); }); }, algorithmName + " asking for too many bits"); - }); + } }); function importKeys(pkcs8, spki, sizes) { var privateKeys = {}; var publicKeys = {}; var noDeriveBitsKeys = {}; + var ecdhPublicKeys = {}; var promises = []; - Object.keys(pkcs8).forEach(function(algorithmName) { + { var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], {name: algorithmName}, false, ["deriveBits", "deriveKey"]) @@ -184,8 +189,8 @@ function define_tests() { privateKeys[algorithmName] = null; }); promises.push(operation); - }); - Object.keys(pkcs8).forEach(function(algorithmName) { + } + { var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], {name: algorithmName}, false, ["deriveKey"]) @@ -195,8 +200,8 @@ function define_tests() { noDeriveBitsKeys[algorithmName] = null; }); promises.push(operation); - }); - Object.keys(spki).forEach(function(algorithmName) { + } + { var operation = subtle.importKey("spki", spki[algorithmName], {name: algorithmName}, false, []) @@ -206,10 +211,17 @@ function define_tests() { publicKeys[algorithmName] = null; }); promises.push(operation); - }); - + } + { + var operation = subtle.importKey("spki", ecSPKI, + {name: "ECDH", namedCurve: "P-256"}, + false, []) + .then(function(key) { + ecdhPublicKeys[algorithmName] = key; + }); + } return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys}}); + .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys, ecdhKeys: ecdhPublicKeys}}); } // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js new file mode 100644 index 00000000000..866192e0193 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve25519.https.any.js @@ -0,0 +1,10 @@ +// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=cfrg_curves_bits_fixtures.js +// META: script=cfrg_curves_bits.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests_25519, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.https.any.js similarity index 75% rename from test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js rename to test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.https.any.js index c1837591ee8..32485c68107 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_curve448.https.any.js @@ -1,4 +1,4 @@ -// META: title=WebCryptoAPI: deriveBits() Using ECDH with CFRG Elliptic Curves +// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves // META: script=cfrg_curves_bits_fixtures.js // META: script=cfrg_curves_bits.js @@ -7,4 +7,4 @@ // for this purpose because the global `done` function is automatically invoked // by the WPT infrastructure in dedicated worker tests defined using the // "multi-global" pattern. -promise_test(define_tests, 'setup - define tests'); +promise_test(define_tests_448, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js index ffdeb51eab9..c376c75bfe6 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_bits_fixtures.js @@ -35,3 +35,6 @@ var kSmallOrderPoint = { { order: "p+1 (=1, order 1)", vector : new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]) }, ] }; + +// "P-256": +var ecSPKI = new Uint8Array([48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 154, 116, 32, 120, 126, 95, 77, 105, 211, 232, 34, 114, 115, 1, 109, 56, 224, 71, 129, 133, 223, 127, 238, 156, 142, 103, 60, 202, 211, 79, 126, 128, 254, 49, 141, 182, 221, 107, 119, 218, 99, 32, 165, 246, 151, 89, 9, 68, 23, 177, 52, 239, 138, 139, 116, 193, 101, 4, 57, 198, 115, 0, 90, 61]); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js index 81244ba05a8..62f9e00aa33 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.js @@ -1,5 +1,12 @@ +function define_tests_25519() { + return define_tests("X25519"); +} -function define_tests() { +function define_tests_448() { + return define_tests("X448"); +} + +function define_tests(algorithmName) { // May want to test prefixed implementations. var subtle = self.crypto.subtle; @@ -8,7 +15,7 @@ function define_tests() { // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 // TODO: The spec states that the check must be done on use, but there is discussion about doing it on import. // https://github.com/WICG/webcrypto-secure-curves/pull/13 - Object.keys(kSmallOrderPoint).forEach(function(algorithmName) { + { kSmallOrderPoint[algorithmName].forEach(function(test) { promise_test(async() => { let derived; @@ -32,10 +39,10 @@ function define_tests() { assert_equals(derived, undefined, "Operation succeeded, but should not have."); }, algorithmName + " deriveBits checks for all-zero value result with a key of order " + test.order); }); - }); + } // Ensure the keys generated by each algorithm are valid for key derivation. - Object.keys(sizes).forEach(function(algorithmName) { + { promise_test(async() => { let derived; try { @@ -46,15 +53,16 @@ function define_tests() { } assert_false (derived === undefined, "Key derivation failed."); }, "Key derivation using a " + algorithmName + " generated keys."); - }); + } return importKeys(pkcs8, spki, sizes) .then(function(results) { publicKeys = results.publicKeys; privateKeys = results.privateKeys; noDeriveKeyKeys = results.noDeriveKeyKeys; + ecdhKeys = results.ecdhKeys; - Object.keys(sizes).forEach(function(algorithmName) { + { // Basic success case promise_test(function(test) { return subtle.deriveKey({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) @@ -102,11 +110,7 @@ function define_tests() { // - wrong algorithm promise_test(function(test) { - publicKey = publicKeys["X25519"]; - if (algorithmName === "X25519") { - publicKey = publicKeys["X448"]; - } - return subtle.deriveKey({name: algorithmName, public: publicKey}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) + return subtle.deriveKey({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], {name: "HMAC", hash: "SHA-256", length: 256}, true, ["sign", "verify"]) .then(function(key) {return crypto.subtle.exportKey("raw", key);}) .then(function(exportedKey) { assert_unreached("deriveKey succeeded but should have failed with InvalidAccessError"); @@ -161,16 +165,17 @@ function define_tests() { }); }); }, algorithmName + " public property value is a secret key"); - }); + } }); function importKeys(pkcs8, spki, sizes) { var privateKeys = {}; var publicKeys = {}; var noDeriveKeyKeys = {}; + var ecdhPublicKeys = {}; var promises = []; - Object.keys(pkcs8).forEach(function(algorithmName) { + { var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], {name: algorithmName}, false, ["deriveBits", "deriveKey"]) @@ -180,8 +185,8 @@ function define_tests() { privateKeys[algorithmName] = null; }); promises.push(operation); - }); - Object.keys(pkcs8).forEach(function(algorithmName) { + } + { var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], {name: algorithmName}, false, ["deriveBits"]) @@ -191,8 +196,8 @@ function define_tests() { noDeriveKeyKeys[algorithmName] = null; }); promises.push(operation); - }); - Object.keys(spki).forEach(function(algorithmName) { + } + { var operation = subtle.importKey("spki", spki[algorithmName], {name: algorithmName}, false, []) @@ -202,10 +207,18 @@ function define_tests() { publicKeys[algorithmName] = null; }); promises.push(operation); - }); + } + { + var operation = subtle.importKey("spki", ecSPKI, + {name: "ECDH", namedCurve: "P-256"}, + false, []) + .then(function(key) { + ecdhPublicKeys[algorithmName] = key; + }); + } return Promise.all(promises) - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys}}); + .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveKeyKeys: noDeriveKeyKeys, ecdhKeys: ecdhPublicKeys}}); } // Compares two ArrayBuffer or ArrayBufferView objects. If bitCount is diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js new file mode 100644 index 00000000000..91390ba5c2a --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve25519.https.any.js @@ -0,0 +1,10 @@ +// META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves +// META: script=cfrg_curves_bits_fixtures.js +// META: script=cfrg_curves_keys.js + +// Define subtests from a `promise_test` to ensure the harness does not +// complete before the subtests are available. `explicit_done` cannot be used +// for this purpose because the global `done` function is automatically invoked +// by the WPT infrastructure in dedicated worker tests defined using the +// "multi-global" pattern. +promise_test(define_tests_25519, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.https.any.js similarity index 89% rename from test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js rename to test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.https.any.js index 96658a56e81..b34e366376a 100644 --- a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/cfrg_curves_keys_curve448.https.any.js @@ -7,4 +7,4 @@ // for this purpose because the global `done` function is automatically invoked // by the WPT infrastructure in dedicated worker tests defined using the // "multi-global" pattern. -promise_test(define_tests, 'setup - define tests'); +promise_test(define_tests_448, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.https.any.js deleted file mode 100644 index a56bd31cbe1..00000000000 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/okp_importKey.https.any.js +++ /dev/null @@ -1,280 +0,0 @@ -// META: title=WebCryptoAPI: importKey() for OKP keys -// META: timeout=long -// META: script=../util/helpers.js - -// Test importKey and exportKey for OKP algorithms. Only "happy paths" are -// currently tested - those where the operation should succeed. - - var subtle = crypto.subtle; - - var keyData = { - "Ed25519": { - spki: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0, 216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]), - raw: new Uint8Array([216, 225, 137, 99, 216, 9, 212, 135, 217, 84, 154, 204, 174, 198, 116, 46, 126, 235, 162, 77, 138, 13, 59, 20, 183, 227, 202, 234, 6, 137, 61, 204]), - pkcs8: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 243, 200, 244, 196, 141, 248, 120, 20, 110, 140, 211, 191, 109, 244, 229, 14, 56, 155, 167, 7, 78, 21, 194, 53, 45, 205, 93, 48, 141, 76, 168, 31]), - jwk: { - crv: "Ed25519", - d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", - x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", - kty: "OKP" - } - }, - - "Ed448": { - spki: new Uint8Array([48, 67, 48, 5, 6, 3, 43, 101, 113, 3, 58, 0, 171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - raw: new Uint8Array([171, 75, 184, 133, 253, 125, 44, 90, 242, 78, 131, 113, 12, 255, 160, 199, 74, 87, 226, 116, 128, 29, 178, 5, 123, 11, 220, 94, 160, 50, 182, 254, 107, 199, 139, 128, 69, 54, 90, 235, 38, 232, 110, 31, 20, 253, 52, 157, 7, 196, 132, 149, 245, 164, 106, 90, 128]), - pkcs8: new Uint8Array([48, 71, 2, 1, 0, 48, 5, 6, 3, 43, 101, 113, 4, 59, 4, 57, 14, 255, 3, 69, 140, 40, 224, 23, 156, 82, 29, 227, 18, 201, 105, 183, 131, 67, 72, 236, 171, 153, 26, 96, 227, 178, 233, 167, 158, 76, 217, 228, 128, 239, 41, 23, 18, 210, 200, 61, 4, 114, 114, 213, 201, 244, 40, 102, 79, 105, 109, 38, 112, 69, 143, 29, 46]), - jwk: { - crv: "Ed448", - d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", - x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", - kty: "OKP" - } - }, - - "X25519": { - spki: new Uint8Array([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0, 28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - raw: new Uint8Array([28, 242, 177, 230, 2, 46, 197, 55, 55, 30, 215, 245, 62, 84, 250, 17, 84, 216, 62, 152, 235, 100, 234, 81, 250, 229, 179, 48, 124, 254, 151, 6]), - pkcs8: new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32, 200, 131, 142, 118, 208, 87, 223, 183, 216, 201, 90, 105, 225, 56, 22, 10, 221, 99, 115, 253, 113, 164, 210, 118, 187, 86, 227, 168, 27, 100, 255, 97]), - jwk: { - crv: "X25519", - d: "yIOOdtBX37fYyVpp4TgWCt1jc_1xpNJ2u1bjqBtk_2E", - x: "HPKx5gIuxTc3Htf1PlT6EVTYPpjrZOpR-uWzMHz-lwY", - kty: "OKP" - } - }, - - "X448": { - spki: new Uint8Array([48, 66, 48, 5, 6, 3, 43, 101, 111, 3, 57, 0, 182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - raw: new Uint8Array([182, 4, 161, 209, 165, 205, 29, 148, 38, 213, 97, 239, 99, 10, 158, 177, 108, 190, 105, 213, 185, 202, 97, 94, 220, 83, 99, 62, 251, 82, 234, 49, 230, 230, 160, 161, 219, 172, 198, 231, 108, 188, 230, 72, 45, 126, 75, 163, 213, 93, 158, 128, 39, 101, 206, 111]), - pkcs8: new Uint8Array([48, 70, 2, 1, 0, 48, 5, 6, 3, 43, 101, 111, 4, 58, 4, 56, 88, 199, 210, 154, 62, 181, 25, 178, 157, 0, 207, 177, 145, 187, 100, 252, 109, 138, 66, 216, 241, 113, 118, 39, 43, 137, 242, 39, 45, 24, 25, 41, 92, 101, 37, 192, 130, 150, 113, 176, 82, 239, 7, 39, 83, 15, 24, 142, 49, 208, 204, 83, 191, 38, 146, 158]), - jwk: { - crv: "X448", - d: "WMfSmj61GbKdAM-xkbtk_G2KQtjxcXYnK4nyJy0YGSlcZSXAgpZxsFLvBydTDxiOMdDMU78mkp4", - x: "tgSh0aXNHZQm1WHvYwqesWy-adW5ymFe3FNjPvtS6jHm5qCh26zG52y85kgtfkuj1V2egCdlzm8", - kty: "OKP" - } - }, - - }; - - // combinations to test - var testVectors = [ - {name: "Ed25519", privateUsages: ["sign"], publicUsages: ["verify"]}, - {name: "Ed448", privateUsages: ["sign"], publicUsages: ["verify"]}, - {name: "X25519", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []}, - {name: "X448", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []}, - ]; - - // TESTS ARE HERE: - // Test every test vector, along with all available key data - testVectors.forEach(function(vector) { - [true, false].forEach(function(extractable) { - - // Test public keys first - allValidUsages(vector.publicUsages, true).forEach(function(usages) { - ['spki', 'jwk', 'raw'].forEach(function(format) { - var algorithm = {name: vector.name}; - var data = keyData[vector.name]; - if (format === "jwk") { // Not all fields used for public keys - data = {jwk: {kty: keyData[vector.name].jwk.kty, crv: keyData[vector.name].jwk.crv, x: keyData[vector.name].jwk.x}}; - } - - testFormat(format, algorithm, data, vector.name, usages, extractable); - - // Test for https://github.com/WICG/webcrypto-secure-curves/pull/24 - if (format === "jwk" && extractable) { - testJwkAlgBehaviours(algorithm, data.jwk, vector.name, usages); - } - }); - - }); - - // Next, test private keys - allValidUsages(vector.privateUsages).forEach(function(usages) { - ['pkcs8', 'jwk'].forEach(function(format) { - var algorithm = {name: vector.name}; - var data = keyData[vector.name]; - - testFormat(format, algorithm, data, vector.name, usages, extractable); - - // Test for https://github.com/WICG/webcrypto-secure-curves/pull/24 - if (format === "jwk" && extractable) { - testJwkAlgBehaviours(algorithm, data.jwk, vector.name, usages); - } - }); - }); - }); - }); - - - // Test importKey with a given key format and other parameters. If - // extrable is true, export the key and verify that it matches the input. - function testFormat(format, algorithm, keyData, keySize, usages, extractable) { - promise_test(function(test) { - return subtle.importKey(format, keyData[format], algorithm, extractable, usages). - then(function(key) { - assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); - assert_goodCryptoKey(key, algorithm, extractable, usages, (format === 'pkcs8' || (format === 'jwk' && keyData[format].d)) ? 'private' : 'public'); - if (!extractable) { - return; - } - - return subtle.exportKey(format, key). - then(function(result) { - if (format !== "jwk") { - assert_true(equalBuffers(keyData[format], result), "Round trip works"); - } else { - assert_true(equalJwk(keyData[format], result), "Round trip works"); - } - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData[format], algorithm, extractable, usages)); - } - - // Test importKey/exportKey "alg" behaviours, alg is ignored upon import and alg is missing for Ed25519 and Ed448 JWK export - // https://github.com/WICG/webcrypto-secure-curves/pull/24 - function testJwkAlgBehaviours(algorithm, keyData, crv, usages) { - promise_test(function(test) { - return subtle.importKey('jwk', { ...keyData, alg: 'this is ignored' }, algorithm, true, usages). - then(function(key) { - assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); - - return subtle.exportKey('jwk', key). - then(function(result) { - assert_equals(Object.keys(result).length, keyData.d ? 6 : 5, "Correct number of JWK members"); - assert_equals(result.alg, undefined, 'No JWK "alg" member is present'); - assert_true(equalJwk(keyData, result), "Round trip works"); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, "Good parameters with ignored JWK alg: " + crv.toString() + " " + parameterString('jwk', keyData, algorithm, true, usages)); - } - - - - // Helper methods follow: - - // Are two array buffers the same? - function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i=0; i