GeezerVison is showing github.com — test,crypto: update WebCryptoAPI WPT · nodejs/node@a2e5126
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: test/fixtures/wpt/README.md +1-1Lines changed: 1 addition & 1 deletion - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -31,7 +31,7 @@ Last update: | 31 | 31 | - user-timing: https://github.com/web-platform-tests/wpt/tree/df24fb604e/user-timing | 32 | 32 | - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/d8dbe6990b/wasm/jsapi | 33 | 33 | - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi | 34 | | -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/0042d42ee6/WebCryptoAPI | | 34 | +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/21ccdcd814/WebCryptoAPI | 35 | 35 | - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions | 36 | 36 |
| 37 | 37 | [Web Platform Tests]: https://github.com/web-platform-tests/wpt | |
Collapse file Copy file name to clipboard +176Lines changed: 176 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +function run_test(algorithmNames) { | | 2 | + var subtle = crypto.subtle; // Change to test prefixed implementations | | 3 | + | | 4 | + setup({explicit_timeout: true}); | | 5 | + | | 6 | +// These tests check that importKey and exportKey throw an error, and that | | 7 | +// the error is of the right type, for a wide set of incorrect parameters. | | 8 | + | | 9 | +// Error testing occurs by setting the parameter that should trigger the | | 10 | +// error to an invalid value, then combining that with all valid | | 11 | +// parameters that should be checked earlier by importKey, and all | | 12 | +// valid and invalid parameters that should be checked later by | | 13 | +// importKey. | | 14 | +// | | 15 | +// There are a lot of combinations of possible parameters for both | | 16 | +// success and failure modes, resulting in a very large number of tests | | 17 | +// performed. | | 18 | + | | 19 | + | | 20 | + var allTestVectors = [ // Parameters that should work for importKey / exportKey | | 21 | + {name: "Ed25519", privateUsages: ["sign"], publicUsages: ["verify"]}, | | 22 | + {name: "Ed448", privateUsages: ["sign"], publicUsages: ["verify"]}, | | 23 | + {name: "X25519", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []}, | | 24 | + {name: "X448", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []}, | | 25 | + ]; | | 26 | + | | 27 | + var testVectors = []; | | 28 | + if (algorithmNames && !Array.isArray(algorithmNames)) { | | 29 | + algorithmNames = [algorithmNames]; | | 30 | + }; | | 31 | + allTestVectors.forEach(function(vector) { | | 32 | + if (!algorithmNames || algorithmNames.includes(vector.name)) { | | 33 | + testVectors.push(vector); | | 34 | + } | | 35 | + }); | | 36 | + | | 37 | + function parameterString(format, algorithm, extractable, usages, data) { | | 38 | + if (typeof algorithm !== "object" && typeof algorithm !== "string") { | | 39 | + alert(algorithm); | | 40 | + } | | 41 | + | | 42 | + var jwk_label = ""; | | 43 | + if (format === "jwk") | | 44 | + jwk_label = data.d === undefined ? " (public) " : "(private)"; | | 45 | + | | 46 | + var result = "(" + | | 47 | + objectToString(format) + jwk_label + ", " + | | 48 | + objectToString(algorithm) + ", " + | | 49 | + objectToString(extractable) + ", " + | | 50 | + objectToString(usages) + | | 51 | + ")"; | | 52 | + | | 53 | + return result; | | 54 | + } | | 55 | + | | 56 | + // Test that a given combination of parameters results in an error, | | 57 | + // AND that it is the correct kind of error. | | 58 | + // | | 59 | + // Expected error is either a number, tested against the error code, | | 60 | + // or a string, tested against the error name. | | 61 | + function testError(format, algorithm, keyData, keySize, usages, extractable, expectedError, testTag) { | | 62 | + promise_test(async() => { | | 63 | + let key; | | 64 | + try { | | 65 | + key = await subtle.importKey(format, keyData, algorithm, extractable, usages); | | 66 | + } catch(err) { | | 67 | + let actualError = typeof expectedError === "number" ? err.code : err.name; | | 68 | + assert_equals(actualError, expectedError, testTag + " not supported."); | | 69 | + } | | 70 | + assert_equals(key, undefined, "Operation succeeded, but should not have."); | | 71 | + }, testTag + ": importKey" + parameterString(format, algorithm, extractable, usages, keyData)); | | 72 | + } | | 73 | + | | 74 | + // Don't create an exhaustive list of all invalid usages, | | 75 | + // because there would usually be nearly 2**8 of them, | | 76 | + // way too many to test. Instead, create every singleton | | 77 | + // of an illegal usage, and "poison" every valid usage | | 78 | + // with an illegal one. | | 79 | + function invalidUsages(validUsages, mandatoryUsages) { | | 80 | + var results = []; | | 81 | + | | 82 | + var illegalUsages = []; | | 83 | + ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) { | | 84 | + if (!validUsages.includes(usage)) { | | 85 | + illegalUsages.push(usage); | | 86 | + } | | 87 | + }); | | 88 | + | | 89 | + var goodUsageCombinations = validUsages.length === 0 ? [] : allValidUsages(validUsages, false, mandatoryUsages); | | 90 | + | | 91 | + illegalUsages.forEach(function(illegalUsage) { | | 92 | + results.push([illegalUsage]); | | 93 | + goodUsageCombinations.forEach(function(usageCombination) { | | 94 | + results.push(usageCombination.concat([illegalUsage])); | | 95 | + }); | | 96 | + }); | | 97 | + | | 98 | + return results; | | 99 | + } | | 100 | + | | 101 | + function validUsages(usages, format, data) { | | 102 | + if (format === 'spki') return usages.publicUsages | | 103 | + if (format === 'pkcs8') return usages.privateUsages | | 104 | + if (format === 'jwk') { | | 105 | + if (data === undefined) | | 106 | + return []; | | 107 | + return data.d === undefined ? usages.publicUsages : usages.privateUsages; | | 108 | + } | | 109 | + return []; | | 110 | + } | | 111 | + | | 112 | +// Now test for properly handling errors | | 113 | +// - Unsupported algorithm | | 114 | +// - Bad usages for algorithm | | 115 | +// - Bad key lengths | | 116 | +// - Lack of a mandatory format field | | 117 | +// - Incompatible keys pair | | 118 | + | | 119 | + // Algorithms normalize okay, but usages bad (though not empty). | | 120 | + // It shouldn't matter what other extractable is. Should fail | | 121 | + // due to SyntaxError | | 122 | + testVectors.forEach(function(vector) { | | 123 | + var name = vector.name; | | 124 | + validKeyData.forEach(function(test) { | | 125 | + allAlgorithmSpecifiersFor(name).forEach(function(algorithm) { | | 126 | + invalidUsages(validUsages(vector, test.format, test.data)).forEach(function(usages) { | | 127 | + [true, false].forEach(function(extractable) { | | 128 | + testError(test.format, algorithm, test.data, name, usages, extractable, "SyntaxError", "Bad usages"); | | 129 | + }); | | 130 | + }); | | 131 | + }); | | 132 | + }); | | 133 | + }); | | 134 | + | | 135 | + // Algorithms normalize okay, usages ok. The length of the key must thouw a DataError exception. | | 136 | + testVectors.forEach(function(vector) { | | 137 | + var name = vector.name; | | 138 | + badKeyLengthData.forEach(function(test) { | | 139 | + allAlgorithmSpecifiersFor(name).forEach(function(algorithm) { | | 140 | + allValidUsages(validUsages(vector, test.format, test.data)).forEach(function(usages) { | | 141 | + [true, false].forEach(function(extractable) { | | 142 | + testError(test.format, algorithm, test.data, name, usages, extractable, "DataError", "Bad key length"); | | 143 | + }); | | 144 | + }); | | 145 | + }); | | 146 | + }); | | 147 | + }); | | 148 | + | | 149 | + // Algorithms normalize okay, usages ok and valid key. The lack of the mandatory JWK parameter must throw a syntax error. | | 150 | + testVectors.forEach(function(vector) { | | 151 | + var name = vector.name; | | 152 | + missingJWKFieldKeyData.forEach(function(test) { | | 153 | + allAlgorithmSpecifiersFor(name).forEach(function(algorithm) { | | 154 | + allValidUsages(validUsages(vector, 'jwk', test.data)).forEach(function(usages) { | | 155 | + [true, false].forEach(function(extractable) { | | 156 | + testError('jwk', algorithm, test.data, name, usages, extractable, "DataError", "Missing JWK '" + test.param + "' parameter"); | | 157 | + }); | | 158 | + }); | | 159 | + }); | | 160 | + }); | | 161 | + }); | | 162 | + | | 163 | + // Algorithms normalize okay, usages ok and valid key. The public key is not compatible with the private key. | | 164 | + testVectors.forEach(function(vector) { | | 165 | + var name = vector.name; | | 166 | + invalidJWKKeyData.forEach(function(data) { | | 167 | + allAlgorithmSpecifiersFor(name).forEach(function(algorithm) { | | 168 | + allValidUsages(vector.privateUsages).forEach(function(usages) { | | 169 | + [true].forEach(function(extractable) { | | 170 | + testError('jwk', algorithm, data, name, usages, extractable, "DataError", "Invalid key pair"); | | 171 | + }); | | 172 | + }); | | 173 | + }); | | 174 | + }); | | 175 | + }); | | 176 | +} |
Collapse file Copy file name to clipboard +102Lines changed: 102 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// META: title=WebCryptoAPI: importKey() for Failures | | 2 | +// META: timeout=long | | 3 | +// META: script=../util/helpers.js | | 4 | +// META: script=okp_importKey_failures.js | | 5 | + | | 6 | +// Setup: define the correct behaviors that should be sought, and create | | 7 | +// helper functions that generate all possible test parameters for | | 8 | +// different situations. | | 9 | +var validKeyData = [ | | 10 | + { | | 11 | + format: "spki", | | 12 | + data: 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]) | | 13 | + }, | | 14 | + { | | 15 | + format: "pkcs8", | | 16 | + data: 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]) | | 17 | + }, | | 18 | + { | | 19 | + format: "jwk", | | 20 | + data: { | | 21 | + crv: "Ed25519", | | 22 | + d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", | | 23 | + x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", | | 24 | + kty: "OKP" | | 25 | + }, | | 26 | + }, | | 27 | + { | | 28 | + format: "jwk", | | 29 | + data: { | | 30 | + crv: "Ed25519", | | 31 | + x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", | | 32 | + kty: "OKP" | | 33 | + }, | | 34 | + }, | | 35 | +]; | | 36 | + | | 37 | +// Removed just the last byte. | | 38 | +var badKeyLengthData = [ | | 39 | + { | | 40 | + format: "spki", | | 41 | + data: 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]) | | 42 | + }, | | 43 | + { | | 44 | + format: "pkcs8", | | 45 | + data: 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]) | | 46 | + }, | | 47 | + { | | 48 | + format: "jwk", | | 49 | + data: { | | 50 | + crv: "Ed25519", | | 51 | + d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB", | | 52 | + x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPcw", | | 53 | + kty: "OKP" | | 54 | + } | | 55 | + }, | | 56 | + { | | 57 | + format: "jwk", | | 58 | + data: { | | 59 | + crv: "Ed25519", | | 60 | + x: "2OGJY9gJ1IfZVJrMrsZ0Ln7rok2KDTsUt-PK6gaJPc", | | 61 | + kty: "OKP" | | 62 | + } | | 63 | + }, | | 64 | +]; | | 65 | + | | 66 | +var missingJWKFieldKeyData = [ | | 67 | + { | | 68 | + param: "x", | | 69 | + data: { | | 70 | + crv: "Ed25519", | | 71 | + d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", | | 72 | + kty: "OKP" | | 73 | + }, | | 74 | + }, | | 75 | + { | | 76 | + param: "kty", | | 77 | + data: { | | 78 | + crv: "Ed25519", | | 79 | + x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", | | 80 | + d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", | | 81 | + }, | | 82 | + }, | | 83 | + { | | 84 | + param: "crv", | | 85 | + data: { | | 86 | + x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", | | 87 | + kty: "OKP" | | 88 | + }, | | 89 | + } | | 90 | +]; | | 91 | + | | 92 | +// The public key doesn't match the private key. | | 93 | +var invalidJWKKeyData = [ | | 94 | + { | | 95 | + crv: "Ed25519", | | 96 | + d: "88j0xI34eBRujNO_bfTlDjibpwdOFcI1Lc1dMI1MqB8", | | 97 | + x: "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", | | 98 | + kty: "OKP" | | 99 | + }, | | 100 | +]; | | 101 | + | | 102 | +run_test(["Ed25519"]); |
Collapse file Copy file name to clipboard +103Lines changed: 103 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// META: title=WebCryptoAPI: importKey() for Failures | | 2 | +// META: timeout=long | | 3 | +// META: script=../util/helpers.js | | 4 | +// META: script=okp_importKey_failures.js | | 5 | + | | 6 | +// Setup: define the correct behaviors that should be sought, and create | | 7 | +// helper functions that generate all possible test parameters for | | 8 | +// different situations. | | 9 | +var validKeyData = [ | | 10 | + { | | 11 | + format: "spki", | | 12 | + data: 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]), | | 13 | + }, | | 14 | + { | | 15 | + format: "pkcs8", | | 16 | + data: 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]), | | 17 | + }, | | 18 | + { | | 19 | + format: "jwk", | | 20 | + data: { | | 21 | + crv: "Ed448", | | 22 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", | | 23 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", | | 24 | + kty: "OKP" | | 25 | + }, | | 26 | + }, | | 27 | + { | | 28 | + format: "jwk", | | 29 | + data: { | | 30 | + crv: "Ed448", | | 31 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", | | 32 | + kty: "OKP" | | 33 | + }, | | 34 | + }, | | 35 | +]; | | 36 | + | | 37 | +// Removed just the last byte. | | 38 | +var badKeyLengthData = [ | | 39 | + { | | 40 | + format: "spki", | | 41 | + data: 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]), | | 42 | + }, | | 43 | + { | | 44 | + format: "pkcs8", | | 45 | + data: 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 | + }, | | 47 | + { | | 48 | + format: "jwk", | | 49 | + data: { | | 50 | + crv: "Ed448", | | 51 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0", | | 52 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", | | 53 | + kty: "OKP" | | 54 | + }, | | 55 | + }, | | 56 | + { | | 57 | + format: "jwk", | | 58 | + data: { | | 59 | + crv: "Ed448", | | 60 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalq", | | 61 | + kty: "OKP" | | 62 | + }, | | 63 | + }, | | 64 | +]; | | 65 | + | | 66 | +var missingJWKFieldKeyData = [ | | 67 | + { | | 68 | + param: "x", | | 69 | + data: { | | 70 | + crv: "Ed448", | | 71 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", | | 72 | + kty: "OKP" | | 73 | + } | | 74 | + }, | | 75 | + { | | 76 | + param: "kty", | | 77 | + data: { | | 78 | + crv: "Ed448", | | 79 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", | | 80 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", | | 81 | + } | | 82 | + }, | | 83 | + { | | 84 | + param: "crv", | | 85 | + data: { | | 86 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", | | 87 | + x: "q0u4hf19LFryToNxDP-gx0pX4nSAHbIFewvcXqAytv5rx4uARTZa6ybobh8U_TSdB8SElfWkalqA", | | 88 | + kty: "OKP" | | 89 | + } | | 90 | + } | | 91 | +]; | | 92 | + | | 93 | +// The public key doesn't match the private key. | | 94 | +var invalidJWKKeyData = [ | | 95 | + { | | 96 | + crv: "Ed448", | | 97 | + d: "Dv8DRYwo4BecUh3jEslpt4NDSOyrmRpg47Lpp55M2eSA7ykXEtLIPQRyctXJ9ChmT2ltJnBFjx0u", | | 98 | + x: "X9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2m0bHBhvWeD3x5Q9s0foavq_oJWGA", | | 99 | + kty: "OKP" | | 100 | + }, | | 101 | +]; | | 102 | + | | 103 | +run_test(["Ed448"]); |
|