Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// 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)");