|
| 1 | +// META: title=WebCryptoAPI: Properties discard the context in algorithm normalization |
| 2 | + |
| 3 | +let nextTest = 0; |
| 4 | +let tests = {}; |
| 5 | +function closeChild(testId) { |
| 6 | + if (tests[testId]) { |
| 7 | + let {child, t} = tests[testId]; |
| 8 | + delete tests[testId]; |
| 9 | + document.body.removeChild(child); |
| 10 | + t.done(); |
| 11 | + } |
| 12 | +} |
| 13 | + |
| 14 | +function runInChild(t, childScript) { |
| 15 | + let testId = nextTest++; |
| 16 | + const preamble = ` |
| 17 | +let testId = ${testId}; |
| 18 | +function closeChildOnAccess(obj, key) { |
| 19 | + const oldValue = obj[key]; |
| 20 | + Object.defineProperty(obj, key, {get: () => { |
| 21 | + top.closeChild(testId); |
| 22 | + return oldValue; |
| 23 | + }}); |
| 24 | +} |
| 25 | +`; |
| 26 | + childScript = preamble + childScript; |
| 27 | + |
| 28 | + let child = document.createElement("iframe"); |
| 29 | + tests[testId] = {t, child}; |
| 30 | + document.body.appendChild(child); |
| 31 | + let script = document.createElement("script"); |
| 32 | + script.textContent = childScript; |
| 33 | + child.contentDocument.body.appendChild(script); |
| 34 | +} |
| 35 | + |
| 36 | +async_test((t) => { |
| 37 | + const childScript = ` |
| 38 | +let algorithm = {name: "AES-GCM", length: 128}; |
| 39 | +closeChildOnAccess(algorithm, "name"); |
| 40 | +crypto.subtle.generateKey(algorithm, true, ["encrypt", "decrypt"]);`; |
| 41 | + runInChild(t, childScript); |
| 42 | +}, "Context is discarded in generateKey"); |
| 43 | + |
| 44 | +async_test((t) => { |
| 45 | + const childScript = ` |
| 46 | +let algorithm = {name: "AES-GCM"}; |
| 47 | +closeChildOnAccess(algorithm, "name"); |
| 48 | +crypto.subtle.importKey("raw", new Uint8Array(16), algorithm, true, |
| 49 | + ["encrypt", "decrypt"]);`; |
| 50 | + runInChild(t, childScript); |
| 51 | +}, "Context is discarded in importKey"); |
| 52 | + |
| 53 | +async_test((t) => { |
| 54 | + const childScript = ` |
| 55 | +(async () => { |
| 56 | + let key = await crypto.subtle.generateKey( |
| 57 | + {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| 58 | + let algorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| 59 | + closeChildOnAccess(algorithm, "name"); |
| 60 | + crypto.subtle.encrypt(algorithm, key, new Uint8Array()); |
| 61 | +})();`; |
| 62 | + runInChild(t, childScript); |
| 63 | +}, "Context is discarded in encrypt"); |
| 64 | + |
| 65 | +async_test((t) => { |
| 66 | + const childScript = ` |
| 67 | +(async () => { |
| 68 | + let key = await crypto.subtle.generateKey( |
| 69 | + {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| 70 | + let algorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| 71 | + let encrypted = await crypto.subtle.encrypt(algorithm, key, new Uint8Array()); |
| 72 | + closeChildOnAccess(algorithm, "name"); |
| 73 | + crypto.subtle.decrypt(algorithm, key, encrypted); |
| 74 | +})();`; |
| 75 | + runInChild(t, childScript); |
| 76 | +}, "Context is discarded in decrypt"); |
| 77 | + |
| 78 | +async_test((t) => { |
| 79 | + const childScript = ` |
| 80 | +let algorithm = {name: "SHA-256"}; |
| 81 | +closeChildOnAccess(algorithm, "name"); |
| 82 | +crypto.subtle.digest(algorithm, new Uint8Array());`; |
| 83 | + runInChild(t, childScript); |
| 84 | +}, "Context is discarded in digest"); |
| 85 | + |
| 86 | +async_test((t) => { |
| 87 | + const childScript = ` |
| 88 | +(async () => { |
| 89 | + let key = await crypto.subtle.generateKey( |
| 90 | + {name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]); |
| 91 | + let algorithm = {name: "ECDSA", hash: "SHA-256"}; |
| 92 | + closeChildOnAccess(algorithm, "name"); |
| 93 | + crypto.subtle.sign(algorithm, key.privateKey, new Uint8Array()); |
| 94 | +})();`; |
| 95 | + runInChild(t, childScript); |
| 96 | +}, "Context is discarded in sign"); |
| 97 | + |
| 98 | +async_test((t) => { |
| 99 | + const childScript = ` |
| 100 | +(async () => { |
| 101 | + let key = await crypto.subtle.generateKey( |
| 102 | + {name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]); |
| 103 | + let algorithm = {name: "ECDSA", hash: "SHA-256"}; |
| 104 | + let data = new Uint8Array(); |
| 105 | + let signature = await crypto.subtle.sign(algorithm, key.privateKey, data); |
| 106 | + closeChildOnAccess(algorithm, "name"); |
| 107 | + crypto.subtle.verify(algorithm, key.publicKey, signature, data); |
| 108 | +})();`; |
| 109 | + runInChild(t, childScript); |
| 110 | +}, "Context is discarded in verify"); |
| 111 | + |
| 112 | +async_test((t) => { |
| 113 | + const childScript = ` |
| 114 | +(async () => { |
| 115 | + let key = await crypto.subtle.importKey( |
| 116 | + "raw", new Uint8Array(16), "HKDF", false, ["deriveBits"]); |
| 117 | + let algorithm = { |
| 118 | + name: "HKDF", |
| 119 | + hash: "SHA-256", |
| 120 | + salt: new Uint8Array(), |
| 121 | + info: new Uint8Array(), |
| 122 | + }; |
| 123 | + closeChildOnAccess(algorithm, "name"); |
| 124 | + crypto.subtle.deriveBits(algorithm, key, 16); |
| 125 | +})();`; |
| 126 | + runInChild(t, childScript); |
| 127 | +}, "Context is discarded in deriveBits"); |
| 128 | + |
| 129 | +async_test((t) => { |
| 130 | + const childScript = ` |
| 131 | +(async () => { |
| 132 | + let key = await crypto.subtle.importKey( |
| 133 | + "raw", new Uint8Array(16), "HKDF", false, ["deriveKey"]); |
| 134 | + let algorithm = { |
| 135 | + name: "HKDF", |
| 136 | + hash: "SHA-256", |
| 137 | + salt: new Uint8Array(), |
| 138 | + info: new Uint8Array(), |
| 139 | + }; |
| 140 | + let derivedAlgorithm = {name: "AES-GCM", length: 128}; |
| 141 | + closeChildOnAccess(algorithm, "name"); |
| 142 | + crypto.subtle.deriveKey(algorithm, key, derivedAlgorithm, true, |
| 143 | + ["encrypt", "decrypt"]); |
| 144 | +})();`; |
| 145 | + runInChild(t, childScript); |
| 146 | +}, "Context is discarded in deriveKey"); |
| 147 | + |
| 148 | +async_test((t) => { |
| 149 | + const childScript = ` |
| 150 | +(async () => { |
| 151 | + let key = await crypto.subtle.importKey( |
| 152 | + "raw", new Uint8Array(16), "HKDF", false, ["deriveKey"]); |
| 153 | + let algorithm = { |
| 154 | + name: "HKDF", |
| 155 | + hash: "SHA-256", |
| 156 | + salt: new Uint8Array(), |
| 157 | + info: new Uint8Array(), |
| 158 | + }; |
| 159 | + let derivedAlgorithm = {name: "AES-GCM", length: 128}; |
| 160 | + closeChildOnAccess(derivedAlgorithm, "name"); |
| 161 | + crypto.subtle.deriveKey(algorithm, key, derivedAlgorithm, true, |
| 162 | + ["encrypt", "decrypt"]); |
| 163 | +})();`; |
| 164 | + runInChild(t, childScript); |
| 165 | +}, "Context is discarded in deriveKey (2)"); |
| 166 | + |
| 167 | +async_test((t) => { |
| 168 | + const childScript = ` |
| 169 | +(async () => { |
| 170 | + let wrapKey = await crypto.subtle.generateKey( |
| 171 | + {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| 172 | + let key = await crypto.subtle.generateKey( |
| 173 | + {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| 174 | + let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| 175 | + closeChildOnAccess(wrapAlgorithm, "name"); |
| 176 | + crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| 177 | +})();`; |
| 178 | + runInChild(t, childScript); |
| 179 | +}, "Context is discarded in wrapKey"); |
| 180 | + |
| 181 | +async_test((t) => { |
| 182 | + const childScript = ` |
| 183 | +(async () => { |
| 184 | + let wrapKey = await crypto.subtle.generateKey( |
| 185 | + {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| 186 | + let keyAlgorithm = {name: "AES-GCM", length: 128}; |
| 187 | + let keyUsages = ["encrypt", "decrypt"]; |
| 188 | + let key = await crypto.subtle.generateKey(keyAlgorithm, true, keyUsages); |
| 189 | + let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| 190 | + let wrapped = await crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| 191 | + closeChildOnAccess(wrapAlgorithm, "name"); |
| 192 | + crypto.subtle.unwrapKey( |
| 193 | + "raw", wrapped, wrapKey, wrapAlgorithm, keyAlgorithm, true, keyUsages); |
| 194 | +})();`; |
| 195 | + runInChild(t, childScript); |
| 196 | +}, "Context is discarded in unwrapKey"); |
| 197 | + |
| 198 | +async_test((t) => { |
| 199 | + const childScript = ` |
| 200 | +(async () => { |
| 201 | + let wrapKey = await crypto.subtle.generateKey( |
| 202 | + {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| 203 | + let keyAlgorithm = {name: "AES-GCM", length: 128}; |
| 204 | + let keyUsages = ["encrypt", "decrypt"]; |
| 205 | + let key = await crypto.subtle.generateKey(keyAlgorithm, true, keyUsages); |
| 206 | + let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| 207 | + let wrapped = await crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| 208 | + closeChildOnAccess(keyAlgorithm, "name"); |
| 209 | + crypto.subtle.unwrapKey( |
| 210 | + "raw", wrapped, wrapKey, wrapAlgorithm, keyAlgorithm, true, keyUsages); |
| 211 | +})();`; |
| 212 | + runInChild(t, childScript); |
| 213 | +}, "Context is discarded in unwrapKey (2)"); |
0 commit comments