in src/js/background.js [94:198]
async function validateManifest(rootHash, leaves, host, version, workaround) {
// does rootHash match what was published?
const cfResponse = await getCFHashWorkaroundFunction(host, version).catch(
cfError => {
console.log('error fetching hash from CF', cfError);
return {
valid: false,
reason: 'ENDPOINT_FAILURE',
error: cfError,
};
}
);
if (cfResponse == null || cfResponse.json == null) {
return {
valid: false,
reason: 'UNKNOWN_ENDPOINT_ISSUE',
};
}
const cfPayload = await cfResponse.json();
let cfRootHash = cfPayload.root_hash;
if (cfPayload.root_hash.startsWith('0x')) {
cfRootHash = cfPayload.root_hash.slice(2);
}
// validate
if (rootHash !== cfRootHash) {
console.log('hash mismatch with CF ', rootHash, cfRootHash);
// secondary hash to mitigate accidental build issue.
const encoder = new TextEncoder();
const backupHashEncoded = encoder.encode(workaround);
const backupHashArray = Array.from(
new Uint8Array(await crypto.subtle.digest('SHA-256', backupHashEncoded))
);
const backupHash = backupHashArray
.map(b => b.toString(16).padStart(2, '0'))
.join('');
console.log(
'secondary hashing of CF value fails too ',
rootHash,
backupHash
);
if (backupHash !== cfRootHash) {
return {
valid: false,
reason: 'ROOT_HASH_VERFIY_FAIL_3RD_PARTY',
};
}
}
let oldhashes = leaves.map(
leaf => fromHexString(leaf.replace('0x', '')).buffer
);
let newhashes = [];
let bonus = '';
while (oldhashes.length > 1) {
for (let index = 0; index < oldhashes.length; index += 2) {
const validSecondValue = index + 1 < oldhashes.length;
if (validSecondValue) {
const hashValue = new Uint8Array(
oldhashes[index].byteLength + oldhashes[index + 1].byteLength
);
hashValue.set(new Uint8Array(oldhashes[index]), 0);
hashValue.set(
new Uint8Array(oldhashes[index + 1]),
oldhashes[index].byteLength
);
newhashes.push(await crypto.subtle.digest('SHA-256', hashValue.buffer));
} else {
bonus = oldhashes[index];
}
}
oldhashes = newhashes;
if (bonus !== '') {
oldhashes.push(bonus);
}
console.log(
'layer hex is ',
oldhashes.map(hash => {
return Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, ''))
.join('');
})
);
newhashes = [];
bonus = '';
console.log(
'in loop hashes.length is',
oldhashes.length,
rootHash,
oldhashes
);
}
const lastHash = toHexString(new Uint8Array(oldhashes[0]));
console.log('before return comparison', rootHash, lastHash);
if (lastHash === rootHash) {
return {
valid: true,
};
}
return {
valid: false,
reason: 'ROOT_HASH_VERFIY_FAIL_IN_PAGE',
};
}