| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4299cd5 commit 28cad47
137 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,2 @@ | |||
| 1 | - features: | ||
| 2 | - - name: web-cryptography | ||
| 3 | - files: '**' | ||
| 1 | + rules: | ||
| 2 | + - "**": [web-cryptography] | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,128 @@ | |||
| 1 | + async function defineCfrgTests(algorithmName, operation) { | ||
| 2 | + const subtle = self.crypto.subtle; | ||
| 3 | + const isDeriveBits = operation === "deriveBits"; | ||
| 4 | + | ||
| 5 | + kSmallOrderPoint[algorithmName].forEach(test => { | ||
| 6 | + promise_test(async() => { | ||
| 7 | + let privateKey; | ||
| 8 | + let publicKey; | ||
| 9 | + let derived; | ||
| 10 | + let error; | ||
| 11 | + | ||
| 12 | + try { | ||
| 13 | + privateKey = await subtle.importKey( | ||
| 14 | + "pkcs8", | ||
| 15 | + pkcs8[algorithmName], | ||
| 16 | + {name: algorithmName}, | ||
| 17 | + false, | ||
| 18 | + ["deriveBits", "deriveKey"] | ||
| 19 | + ); | ||
| 20 | + publicKey = await subtle.importKey( | ||
| 21 | + "spki", | ||
| 22 | + test.vector, | ||
| 23 | + {name: algorithmName}, | ||
| 24 | + false, | ||
| 25 | + [] | ||
| 26 | + ); | ||
| 27 | + derived = isDeriveBits | ||
| 28 | + ? await subtle.deriveBits( | ||
| 29 | + {name: algorithmName, public: publicKey}, | ||
| 30 | + privateKey, | ||
| 31 | + 8 * sizes[algorithmName] | ||
| 32 | + ) | ||
| 33 | + : await subtle.deriveKey( | ||
| 34 | + {name: algorithmName, public: publicKey}, | ||
| 35 | + privateKey, | ||
| 36 | + {name: "HMAC", hash: "SHA-256", length: 256}, | ||
| 37 | + true, | ||
| 38 | + ["sign", "verify"] | ||
| 39 | + ); | ||
| 40 | + } catch (caught) { | ||
| 41 | + error = caught; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + assert_not_equals(privateKey, undefined, "Private key should be valid."); | ||
| 45 | + assert_not_equals(publicKey, undefined, "Public key should be valid."); | ||
| 46 | + assert_not_equals(error, undefined, "Operation should fail."); | ||
| 47 | + assert_equals( | ||
| 48 | + error.name, | ||
| 49 | + "OperationError", | ||
| 50 | + "Should throw correct error, not " + error.name + ": " + error.message + "." | ||
| 51 | + ); | ||
| 52 | + assert_equals(derived, undefined, "Operation succeeded, but should not have."); | ||
| 53 | + }, algorithmName + | ||
| 54 | + (isDeriveBits ? " key derivation" : " deriveBits") + | ||
| 55 | + " checks for all-zero value result with a key of order " + test.order); | ||
| 56 | + }); | ||
| 57 | + | ||
| 58 | + if (!isDeriveBits) { | ||
| 59 | + promise_test(async() => { | ||
| 60 | + const key = await subtle.generateKey( | ||
| 61 | + {name: algorithmName}, | ||
| 62 | + true, | ||
| 63 | + ["deriveKey", "deriveBits"] | ||
| 64 | + ); | ||
| 65 | + const derived = await subtle.deriveKey( | ||
| 66 | + {name: algorithmName, public: key.publicKey}, | ||
| 67 | + key.privateKey, | ||
| 68 | + {name: "HMAC", hash: "SHA-256", length: 256}, | ||
| 69 | + true, | ||
| 70 | + ["sign", "verify"] | ||
| 71 | + ); | ||
| 72 | + assert_not_equals(derived, undefined, "Key derivation failed."); | ||
| 73 | + }, "Key derivation using a " + algorithmName + " generated keys."); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + const noUsage = isDeriveBits ? ["deriveKey"] : ["deriveBits"]; | ||
| 77 | + const [ | ||
| 78 | + privateKey, | ||
| 79 | + noUsagePrivateKey, | ||
| 80 | + publicKey, | ||
| 81 | + ecdhPublicKey, | ||
| 82 | + ] = await Promise.all([ | ||
| 83 | + subtle.importKey( | ||
| 84 | + "pkcs8", | ||
| 85 | + pkcs8[algorithmName], | ||
| 86 | + {name: algorithmName}, | ||
| 87 | + false, | ||
| 88 | + ["deriveBits", "deriveKey"] | ||
| 89 | + ), | ||
| 90 | + subtle.importKey( | ||
| 91 | + "pkcs8", | ||
| 92 | + pkcs8[algorithmName], | ||
| 93 | + {name: algorithmName}, | ||
| 94 | + false, | ||
| 95 | + noUsage | ||
| 96 | + ), | ||
| 97 | + subtle.importKey( | ||
| 98 | + "spki", | ||
| 99 | + spki[algorithmName], | ||
| 100 | + {name: algorithmName}, | ||
| 101 | + false, | ||
| 102 | + [] | ||
| 103 | + ), | ||
| 104 | + subtle.importKey( | ||
| 105 | + "spki", | ||
| 106 | + ecSPKI, | ||
| 107 | + {name: "ECDH", namedCurve: "P-256"}, | ||
| 108 | + false, | ||
| 109 | + [] | ||
| 110 | + ), | ||
| 111 | + ]); | ||
| 112 | + | ||
| 113 | + registerDeriveTests({ | ||
| 114 | + operation, | ||
| 115 | + algorithmName, | ||
| 116 | + mixedCaseName: algorithmName.toLowerCase(), | ||
| 117 | + size: sizes[algorithmName], | ||
| 118 | + derivation: derivations[algorithmName], | ||
| 119 | + privateKey, | ||
| 120 | + publicKey, | ||
| 121 | + noUsagePrivateKey, | ||
| 122 | + invalidPublicKeys: [{ | ||
| 123 | + name: algorithmName + " mismatched algorithms", | ||
| 124 | + key: ecdhPublicKey, | ||
| 125 | + }], | ||
| 126 | + missingPublicLabel: algorithmName + " missing public property", | ||
| 127 | + }); | ||
| 128 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,227 +1,7 @@ | |||
| 1 | 1 | function define_tests_25519() { | |
| 2 | - return define_tests("X25519"); | ||
| 2 | + return defineCfrgTests("X25519", "deriveBits"); | ||
| 3 | 3 | } | |
| 4 | 4 | ||
| 5 | 5 | function define_tests_448() { | |
| 6 | - return define_tests("X448"); | ||
| 7 | - } | ||
| 8 | - | ||
| 9 | - function define_tests(algorithmName) { | ||
| 10 | - // May want to test prefixed implementations. | ||
| 11 | - var subtle = self.crypto.subtle; | ||
| 12 | - | ||
| 13 | - // Verify the derive functions perform checks against the all-zero value results, | ||
| 14 | - // ensuring small-order points are rejected. | ||
| 15 | - // https://www.rfc-editor.org/rfc/rfc7748#section-6.1 | ||
| 16 | - { | ||
| 17 | - kSmallOrderPoint[algorithmName].forEach(function(test) { | ||
| 18 | - promise_test(async() => { | ||
| 19 | - let derived; | ||
| 20 | - let privateKey; | ||
| 21 | - let publicKey; | ||
| 22 | - try { | ||
| 23 | - privateKey = await subtle.importKey("pkcs8", pkcs8[algorithmName], | ||
| 24 | - {name: algorithmName}, | ||
| 25 | - false, ["deriveBits", "deriveKey"]); | ||
| 26 | - publicKey = await subtle.importKey("spki", test.vector, | ||
| 27 | - {name: algorithmName}, | ||
| 28 | - false, []) | ||
| 29 | - derived = await subtle.deriveBits({name: algorithmName, public: publicKey}, privateKey, 8 * sizes[algorithmName]); | ||
| 30 | - } catch (err) { | ||
| 31 | - assert_true(privateKey !== undefined, "Private key should be valid."); | ||
| 32 | - assert_true(publicKey !== undefined, "Public key should be valid."); | ||
| 33 | - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message + "."); | ||
| 34 | - } | ||
| 35 | - assert_equals(derived, undefined, "Operation succeeded, but should not have."); | ||
| 36 | - }, algorithmName + " key derivation checks for all-zero value result with a key of order " + test.order); | ||
| 37 | - }); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - return importKeys(pkcs8, spki, sizes) | ||
| 41 | - .then(function(results) { | ||
| 42 | - publicKeys = results.publicKeys; | ||
| 43 | - privateKeys = results.privateKeys; | ||
| 44 | - noDeriveBitsKeys = results.noDeriveBitsKeys; | ||
| 45 | - ecdhKeys = results.ecdhKeys; | ||
| 46 | - | ||
| 47 | - { | ||
| 48 | - // Basic success case | ||
| 49 | - promise_test(function(test) { | ||
| 50 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 51 | - .then(function(derivation) { | ||
| 52 | - assert_true(equalBuffers(derivation, derivations[algorithmName]), "Derived correct bits"); | ||
| 53 | - }, function(err) { | ||
| 54 | - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); | ||
| 55 | - }); | ||
| 56 | - }, algorithmName + " good parameters"); | ||
| 57 | - | ||
| 58 | - // Case insensitivity check | ||
| 59 | - promise_test(function(test) { | ||
| 60 | - return subtle.deriveBits({name: algorithmName.toLowerCase(), public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 61 | - .then(function(derivation) { | ||
| 62 | - assert_true(equalBuffers(derivation, derivations[algorithmName]), "Derived correct bits"); | ||
| 63 | - }, function(err) { | ||
| 64 | - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); | ||
| 65 | - }); | ||
| 66 | - }, algorithmName + " mixed case parameters"); | ||
| 67 | - | ||
| 68 | - // Shorter than entire derivation per algorithm | ||
| 69 | - promise_test(function(test) { | ||
| 70 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] - 32) | ||
| 71 | - .then(function(derivation) { | ||
| 72 | - assert_true(equalBuffers(derivation, derivations[algorithmName], 8 * sizes[algorithmName] - 32), "Derived correct bits"); | ||
| 73 | - }, function(err) { | ||
| 74 | - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); | ||
| 75 | - }); | ||
| 76 | - }, algorithmName + " short result"); | ||
| 77 | - | ||
| 78 | - // Non-multiple of 8 | ||
| 79 | - promise_test(function(test) { | ||
| 80 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] - 11) | ||
| 81 | - .then(function(derivation) { | ||
| 82 | - assert_true(equalBuffers(derivation, derivations[algorithmName], 8 * sizes[algorithmName] - 11), "Derived correct bits"); | ||
| 83 | - }, function(err) { | ||
| 84 | - assert_unreached("deriveBits failed with error " + err.name + ": " + err.message); | ||
| 85 | - }); | ||
| 86 | - }, algorithmName + " non-multiple of 8 bits"); | ||
| 87 | - | ||
| 88 | - // Errors to test: | ||
| 89 | - | ||
| 90 | - // - missing public property TypeError | ||
| 91 | - promise_test(function(test) { | ||
| 92 | - return subtle.deriveBits({name: algorithmName}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 93 | - .then(function(derivation) { | ||
| 94 | - assert_unreached("deriveBits succeeded but should have failed with TypeError"); | ||
| 95 | - }, function(err) { | ||
| 96 | - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 97 | - }); | ||
| 98 | - }, algorithmName + " missing public property"); | ||
| 99 | - | ||
| 100 | - // - Non CryptoKey public property TypeError | ||
| 101 | - promise_test(function(test) { | ||
| 102 | - return subtle.deriveBits({name: algorithmName, public: {message: "Not a CryptoKey"}}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 103 | - .then(function(derivation) { | ||
| 104 | - assert_unreached("deriveBits succeeded but should have failed with TypeError"); | ||
| 105 | - }, function(err) { | ||
| 106 | - assert_equals(err.name, "TypeError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 107 | - }); | ||
| 108 | - }, algorithmName + " public property of algorithm is not a CryptoKey"); | ||
| 109 | - | ||
| 110 | - // - wrong algorithm | ||
| 111 | - promise_test(function(test) { | ||
| 112 | - return subtle.deriveBits({name: algorithmName, public: ecdhKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 113 | - .then(function(derivation) { | ||
| 114 | - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); | ||
| 115 | - }, function(err) { | ||
| 116 | - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 117 | - }); | ||
| 118 | - }, algorithmName + " mismatched algorithms"); | ||
| 119 | - | ||
| 120 | - // - No deriveBits usage in baseKey InvalidAccessError | ||
| 121 | - promise_test(function(test) { | ||
| 122 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, noDeriveBitsKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 123 | - .then(function(derivation) { | ||
| 124 | - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); | ||
| 125 | - }, function(err) { | ||
| 126 | - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 127 | - }); | ||
| 128 | - }, algorithmName + " no deriveBits usage for base key"); | ||
| 129 | - | ||
| 130 | - // - Use public key for baseKey InvalidAccessError | ||
| 131 | - promise_test(function(test) { | ||
| 132 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, publicKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 133 | - .then(function(derivation) { | ||
| 134 | - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); | ||
| 135 | - }, function(err) { | ||
| 136 | - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 137 | - }); | ||
| 138 | - }, algorithmName + " base key is not a private key"); | ||
| 139 | - | ||
| 140 | - // - Use private key for public property InvalidAccessError | ||
| 141 | - promise_test(function(test) { | ||
| 142 | - return subtle.deriveBits({name: algorithmName, public: privateKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 143 | - .then(function(derivation) { | ||
| 144 | - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); | ||
| 145 | - }, function(err) { | ||
| 146 | - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 147 | - }); | ||
| 148 | - }, algorithmName + " public property value is a private key"); | ||
| 149 | - | ||
| 150 | - // - Use secret key for public property InvalidAccessError | ||
| 151 | - promise_test(function(test) { | ||
| 152 | - return subtle.generateKey({name: "AES-CBC", length: 128}, true, ["encrypt", "decrypt"]) | ||
| 153 | - .then(function(secretKey) { | ||
| 154 | - return subtle.deriveBits({name: algorithmName, public: secretKey}, privateKeys[algorithmName], 8 * sizes[algorithmName]) | ||
| 155 | - .then(function(derivation) { | ||
| 156 | - assert_unreached("deriveBits succeeded but should have failed with InvalidAccessError"); | ||
| 157 | - }, function(err) { | ||
| 158 | - assert_equals(err.name, "InvalidAccessError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 159 | - }); | ||
| 160 | - }); | ||
| 161 | - }, algorithmName + " public property value is a secret key"); | ||
| 162 | - | ||
| 163 | - // - Length greater than possible for particular curves OperationError | ||
| 164 | - promise_test(function(test) { | ||
| 165 | - return subtle.deriveBits({name: algorithmName, public: publicKeys[algorithmName]}, privateKeys[algorithmName], 8 * sizes[algorithmName] + 8) | ||
| 166 | - .then(function(derivation) { | ||
| 167 | - assert_unreached("deriveBits succeeded but should have failed with OperationError"); | ||
| 168 | - }, function(err) { | ||
| 169 | - assert_equals(err.name, "OperationError", "Should throw correct error, not " + err.name + ": " + err.message); | ||
| 170 | - }); | ||
| 171 | - }, algorithmName + " asking for too many bits"); | ||
| 172 | - } | ||
| 173 | - }); | ||
| 174 | - | ||
| 175 | - function importKeys(pkcs8, spki, sizes) { | ||
| 176 | - var privateKeys = {}; | ||
| 177 | - var publicKeys = {}; | ||
| 178 | - var noDeriveBitsKeys = {}; | ||
| 179 | - var ecdhPublicKeys = {}; | ||
| 180 | - | ||
| 181 | - var promises = []; | ||
| 182 | - { | ||
| 183 | - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], | ||
| 184 | - {name: algorithmName}, | ||
| 185 | - false, ["deriveBits", "deriveKey"]) | ||
| 186 | - .then(function(key) { | ||
| 187 | - privateKeys[algorithmName] = key; | ||
| 188 | - }, function (err) { | ||
| 189 | - privateKeys[algorithmName] = null; | ||
| 190 | - }); | ||
| 191 | - promises.push(operation); | ||
| 192 | - } | ||
| 193 | - { | ||
| 194 | - var operation = subtle.importKey("pkcs8", pkcs8[algorithmName], | ||
| 195 | - {name: algorithmName}, | ||
| 196 | - false, ["deriveKey"]) | ||
| 197 | - .then(function(key) { | ||
| 198 | - noDeriveBitsKeys[algorithmName] = key; | ||
| 199 | - }, function (err) { | ||
| 200 | - noDeriveBitsKeys[algorithmName] = null; | ||
| 201 | - }); | ||
| 202 | - promises.push(operation); | ||
| 203 | - } | ||
| 204 | - { | ||
| 205 | - var operation = subtle.importKey("spki", spki[algorithmName], | ||
| 206 | - {name: algorithmName}, | ||
| 207 | - false, []) | ||
| 208 | - .then(function(key) { | ||
| 209 | - publicKeys[algorithmName] = key; | ||
| 210 | - }, function (err) { | ||
| 211 | - publicKeys[algorithmName] = null; | ||
| 212 | - }); | ||
| 213 | - promises.push(operation); | ||
| 214 | - } | ||
| 215 | - { | ||
| 216 | - var operation = subtle.importKey("spki", ecSPKI, | ||
| 217 | - {name: "ECDH", namedCurve: "P-256"}, | ||
| 218 | - false, []) | ||
| 219 | - .then(function(key) { | ||
| 220 | - ecdhPublicKeys[algorithmName] = key; | ||
| 221 | - }); | ||
| 222 | - } | ||
| 223 | - return Promise.all(promises) | ||
| 224 | - .then(function(results) {return {privateKeys: privateKeys, publicKeys: publicKeys, noDeriveBitsKeys: noDeriveBitsKeys, ecdhKeys: ecdhPublicKeys}}); | ||
| 225 | - } | ||
| 226 | - | ||
| 6 | + return defineCfrgTests("X448", "deriveBits"); | ||
| 227 | 7 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,8 @@ | |||
| 1 | 1 | // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves | |
| 2 | 2 | // META: script=../util/helpers.js | |
| 3 | 3 | // META: script=cfrg_curves_bits_fixtures.js | |
| 4 | + // META: script=derive.js | ||
| 5 | + // META: script=cfrg_curves.js | ||
| 4 | 6 | // META: script=cfrg_curves_bits.js | |
| 5 | 7 | ||
| 6 | 8 | // Define subtests from a `promise_test` to ensure the harness does not | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,8 @@ | |||
| 1 | 1 | // META: title=WebCryptoAPI: deriveKey() Using ECDH with CFRG Elliptic Curves | |
| 2 | 2 | // META: script=../util/helpers.js | |
| 3 | 3 | // META: script=cfrg_curves_bits_fixtures.js | |
| 4 | + // META: script=derive.js | ||
| 5 | + // META: script=cfrg_curves.js | ||
| 4 | 6 | // META: script=cfrg_curves_bits.js | |
| 5 | 7 | ||
| 6 | 8 | // Define subtests from a `promise_test` to ensure the harness does not | |
| Back | FazBrowse Home | New Git URL |
0 commit comments