forked from mirrors/gecko-dev
Automatic update from web-platform-tests Handle the context getting discarded in NormalizeAlgorithm The WebCrypto result machinery tracks when the context was discarded to cancel the operation, if still pending. However, that logic did not correctly account for the context being discarded before the task is posted: - CryptoResultImpl::Resolver DCHECKs that the context is valid when it is created. As far as I can tell, that DCHECK isn't necessary? - If CryptoResultImpl::Cancel is called before calling CryptoResultImpl::Result, the cancel flag is null, which breaks WebCryptoResult's DCHECKs and null pointer derefs later in release code. Instead, remove the DCHECK and retain the cancel flag in CryptoResultImpl so WebCryptoResult can observe cancelation in either order. These two changes fix the crashes. This CL additionally makes webcrypto_impl.cc check for cancellation before posting the task. This isn't strictly necessary, but avoids a pointless thread hop. Bug: 1324846 Change-Id: Idd8f2174f438fc3bfb5ffd140b9983d5b6b8039d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3664759 Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: David Benjamin <davidben@chromium.org> Reviewed-by: Yuki Shiino <yukishiino@chromium.org> Cr-Commit-Position: refs/heads/main@{#1008433} -- wpt-commits: 335c36d606c02daa4a35bd073d8c0bbd96a2fad3 wpt-pr: 34191
213 lines
7 KiB
JavaScript
213 lines
7 KiB
JavaScript
// 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)");
|