Commit 995eabef authored by taco@waag.org's avatar taco@waag.org
Browse files

blockhash verification in backend

parent 1ec3cc9f
......@@ -231,7 +231,7 @@ var blockhash = function(src, bits, method, callback) {
try {
if (contentType === 'image/png') {
png = new PNG(data);
png = new window.PNG(data);
imgData = {
width: png.width,
......
......@@ -9,63 +9,103 @@ browser.runtime.onMessage.addListener(function(msg, sender, sendResponse){
if(msg.command == "verify"){
let keys = msg.signatures.map(entry=> entry[0]);
let values = msg.signatures.map(entry=>entry[1]);
var values = msg.signatures.map(entry=>entry[1]);
let envelopes = msg.signatures.map(entry=>entry[2]);
//TODO first calculate all hashes and replace the message of each img fragment
//then verify everything
Promise.all(values.map(signature =>
fetch('http://localhost:3000/verify', { method: 'POST', headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}, body: signature })
.then(resp => resp.text())
//get the image expressions urls
let img_indices = keys.map(key => key.endsWith('img')).reduce((out, bool, index) => bool ? out.concat(index) : out, []);
var urls_to_be_hashed = img_indices.map(index => JSON.parse(values[index]).message);
//first retrieve all image hashes
//(does xhr on the url to get the image data, this can be optimized)
Promise.all(urls_to_be_hashed.map(url =>
getBlockhash(url).then(resp => {
return resp;
}).catch(function(err){
return "hash failed";
})
)).then(responses => {
//if all responses are VALID we show a green check mark
const valid = responses.every(function (response) {
return JSON.parse(response)["status"] == 'VALID';
});
//then replace the image urls with the calculated hashes
responses.forEach((hash, index) => {
let fragment_index = img_indices[index];
let obj = JSON.parse(values[fragment_index]);
obj.message = hash;
values[fragment_index] = JSON.stringify(obj);
});
//now verify all signatures (with the hashes in place of the message for image fragments)
Promise.all(values.map(signature =>
fetch('http://localhost:3000/verify', { method: 'POST', headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
}, body: signature })
.then(resp => resp.text())
)).then(responses => {
handleValidationResults(msg, responses, keys, values, envelopes, tab_id);
}).catch(function(err) {
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_server_error-48.png"
});
})
//index resultset
const indexed_result = zip(keys,responses);
//save state for later use, indexed by tab
const state = {"signatures": msg.signatures, "results": indexed_result, "envelopes": envelopes}
}).catch(function(err){
console.log(err);
});
//set the verfication state
let key1 = "pop_state_" + tab_id;
var args = {};
args[key1] = state;
browser.storage.local.set(args);
}
});
//set the provenance view toggle state for this tab, default to off
let key2 = "pop_toggle_" + tab_id;
var args = {};
args[key2] = false;
browser.storage.local.set(args);
//wrap blockhash call into a promise
function getBlockhash(url){
return new Promise((resolve,reject) => {
blockhashjs.blockhash(url,16,2,function(err,hash){
if(err) reject(err);
resolve(hash);
});
});
};
if(valid){
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_valid-48.png"
});
console.log('registering click');
browser.browserAction.onClicked.addListener((tab) => {
toggleProvenanceView(tab);
});
}else{
browser.browserAction.onClicked.addListener((tab) => {
toggleProvenanceView(tab);
});
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_invalid-48.png"
});
}
}).catch(function(err) {
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_server_error-48.png"
});
})
function handleValidationResults(msg, responses, keys, values, envelopes, tab_id){
//if all responses are VALID we show a green check mark
const valid = responses.every(function (response) {
return JSON.parse(response)["status"] == 'VALID';
});
//index resultset
const indexed_result = zip(keys,responses);
//save state for later use, indexed by tab
const state = {"signatures": msg.signatures, "results": indexed_result, "envelopes": envelopes}
//set the verfication state
let key1 = "pop_state_" + tab_id;
var args = {};
args[key1] = state;
browser.storage.local.set(args);
//set the provenance view toggle state for this tab, default to off
let key2 = "pop_toggle_" + tab_id;
var args = {};
args[key2] = false;
browser.storage.local.set(args);
if(valid){
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_valid-48.png"
});
console.log('registering click');
browser.browserAction.onClicked.addListener((tab) => {
toggleProvenanceView(tab);
});
}else{
browser.browserAction.onClicked.addListener((tab) => {
toggleProvenanceView(tab);
});
browser.browserAction.setIcon({
tabId: tab_id, path: "icons/pop_certificate_invalid-48.png"
});
}
});
}
//toggle provenance view for current tab
function toggleProvenanceView(active_tab) {
......
//this is a content script, fired at document complete (it can not do xhr)
console.log("pop verification extension loaded (v0) ");
//console.log(blockhash);
//implementation of unpacking signatures for verification according to v0
//step 1. base64 decode
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment