| // META: title=WebCryptoAPI: Properties discard the context in algorithm normalization |
| |
| let nextTest = 0; |
| let tests = {}; |
| function closeChild(testId) { |
| if (tests[testId]) { |
| let {child, t} = tests[testId]; |
| delete tests[testId]; |
| document.body.removeChild(child); |
| t.done(); |
| } |
| } |
| |
| function runInChild(t, childScript) { |
| let testId = nextTest++; |
| const preamble = ` |
| let testId = ${testId}; |
| function closeChildOnAccess(obj, key) { |
| const oldValue = obj[key]; |
| Object.defineProperty(obj, key, {get: () => { |
| top.closeChild(testId); |
| return oldValue; |
| }}); |
| } |
| `; |
| childScript = preamble + childScript; |
| |
| let child = document.createElement("iframe"); |
| tests[testId] = {t, child}; |
| document.body.appendChild(child); |
| let script = document.createElement("script"); |
| script.textContent = childScript; |
| child.contentDocument.body.appendChild(script); |
| } |
| |
| async_test((t) => { |
| const childScript = ` |
| let algorithm = {name: "AES-GCM", length: 128}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.generateKey(algorithm, true, ["encrypt", "decrypt"]);`; |
| runInChild(t, childScript); |
| }, "Context is discarded in generateKey"); |
| |
| async_test((t) => { |
| const childScript = ` |
| let algorithm = {name: "AES-GCM"}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.importKey("raw", new Uint8Array(16), algorithm, true, |
| ["encrypt", "decrypt"]);`; |
| runInChild(t, childScript); |
| }, "Context is discarded in importKey"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| let algorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.encrypt(algorithm, key, new Uint8Array()); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in encrypt"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| let algorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| let encrypted = await crypto.subtle.encrypt(algorithm, key, new Uint8Array()); |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.decrypt(algorithm, key, encrypted); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in decrypt"); |
| |
| async_test((t) => { |
| const childScript = ` |
| let algorithm = {name: "SHA-256"}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.digest(algorithm, new Uint8Array());`; |
| runInChild(t, childScript); |
| }, "Context is discarded in digest"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.generateKey( |
| {name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]); |
| let algorithm = {name: "ECDSA", hash: "SHA-256"}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.sign(algorithm, key.privateKey, new Uint8Array()); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in sign"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.generateKey( |
| {name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]); |
| let algorithm = {name: "ECDSA", hash: "SHA-256"}; |
| let data = new Uint8Array(); |
| let signature = await crypto.subtle.sign(algorithm, key.privateKey, data); |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.verify(algorithm, key.publicKey, signature, data); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in verify"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.importKey( |
| "raw", new Uint8Array(16), "HKDF", false, ["deriveBits"]); |
| let algorithm = { |
| name: "HKDF", |
| hash: "SHA-256", |
| salt: new Uint8Array(), |
| info: new Uint8Array(), |
| }; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.deriveBits(algorithm, key, 16); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in deriveBits"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.importKey( |
| "raw", new Uint8Array(16), "HKDF", false, ["deriveKey"]); |
| let algorithm = { |
| name: "HKDF", |
| hash: "SHA-256", |
| salt: new Uint8Array(), |
| info: new Uint8Array(), |
| }; |
| let derivedAlgorithm = {name: "AES-GCM", length: 128}; |
| closeChildOnAccess(algorithm, "name"); |
| crypto.subtle.deriveKey(algorithm, key, derivedAlgorithm, true, |
| ["encrypt", "decrypt"]); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in deriveKey"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let key = await crypto.subtle.importKey( |
| "raw", new Uint8Array(16), "HKDF", false, ["deriveKey"]); |
| let algorithm = { |
| name: "HKDF", |
| hash: "SHA-256", |
| salt: new Uint8Array(), |
| info: new Uint8Array(), |
| }; |
| let derivedAlgorithm = {name: "AES-GCM", length: 128}; |
| closeChildOnAccess(derivedAlgorithm, "name"); |
| crypto.subtle.deriveKey(algorithm, key, derivedAlgorithm, true, |
| ["encrypt", "decrypt"]); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in deriveKey (2)"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let wrapKey = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| let key = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["encrypt", "decrypt"]); |
| let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| closeChildOnAccess(wrapAlgorithm, "name"); |
| crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in wrapKey"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let wrapKey = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| let keyAlgorithm = {name: "AES-GCM", length: 128}; |
| let keyUsages = ["encrypt", "decrypt"]; |
| let key = await crypto.subtle.generateKey(keyAlgorithm, true, keyUsages); |
| let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| let wrapped = await crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| closeChildOnAccess(wrapAlgorithm, "name"); |
| crypto.subtle.unwrapKey( |
| "raw", wrapped, wrapKey, wrapAlgorithm, keyAlgorithm, true, keyUsages); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in unwrapKey"); |
| |
| async_test((t) => { |
| const childScript = ` |
| (async () => { |
| let wrapKey = await crypto.subtle.generateKey( |
| {name: "AES-GCM", length: 128}, true, ["wrapKey", "unwrapKey"]); |
| let keyAlgorithm = {name: "AES-GCM", length: 128}; |
| let keyUsages = ["encrypt", "decrypt"]; |
| let key = await crypto.subtle.generateKey(keyAlgorithm, true, keyUsages); |
| let wrapAlgorithm = {name: "AES-GCM", iv: new Uint8Array(12)}; |
| let wrapped = await crypto.subtle.wrapKey("raw", key, wrapKey, wrapAlgorithm); |
| closeChildOnAccess(keyAlgorithm, "name"); |
| crypto.subtle.unwrapKey( |
| "raw", wrapped, wrapKey, wrapAlgorithm, keyAlgorithm, true, keyUsages); |
| })();`; |
| runInChild(t, childScript); |
| }, "Context is discarded in unwrapKey (2)"); |