1// META: title=WebCryptoAPI: Properties discard the context in algorithm normalization 2 3let nextTest = 0; 4let tests = {}; 5function 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 14function runInChild(t, childScript) { 15 let testId = nextTest++; 16 const preamble = ` 17let testId = ${testId}; 18function 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 36async_test((t) => { 37 const childScript = ` 38let algorithm = {name: "AES-GCM", length: 128}; 39closeChildOnAccess(algorithm, "name"); 40crypto.subtle.generateKey(algorithm, true, ["encrypt", "decrypt"]);`; 41 runInChild(t, childScript); 42}, "Context is discarded in generateKey"); 43 44async_test((t) => { 45 const childScript = ` 46let algorithm = {name: "AES-GCM"}; 47closeChildOnAccess(algorithm, "name"); 48crypto.subtle.importKey("raw", new Uint8Array(16), algorithm, true, 49 ["encrypt", "decrypt"]);`; 50 runInChild(t, childScript); 51}, "Context is discarded in importKey"); 52 53async_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 65async_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 78async_test((t) => { 79 const childScript = ` 80let algorithm = {name: "SHA-256"}; 81closeChildOnAccess(algorithm, "name"); 82crypto.subtle.digest(algorithm, new Uint8Array());`; 83 runInChild(t, childScript); 84}, "Context is discarded in digest"); 85 86async_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 98async_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 112async_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 129async_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 148async_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 167async_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 181async_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 198async_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)"); 214