Begin adding support for browser
This commit is contained in:
parent
8e73504214
commit
a56ea40640
@ -274,19 +274,30 @@ function calculateSHA256HashOfString(str) {
|
||||
}
|
||||
|
||||
function openPublicKeyFile() {
|
||||
openFileDialog(function (path) {
|
||||
var keyfile = getFileAsString(path);
|
||||
openFileDialog(function (path, html5file) {
|
||||
var importpk = function (keyfile) {
|
||||
kbpgp.KeyManager.import_from_armored_pgp({
|
||||
armored: keyfile
|
||||
}, function (err, pubkeymgr) {
|
||||
if (!err) {
|
||||
keyring.add_key_manager(pubkeymgr);
|
||||
alert("Public key file loaded. You can now analyze PDFs signed by the key's owner.");
|
||||
} else {
|
||||
alert("Error loading public key: " + err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
kbpgp.KeyManager.import_from_armored_pgp({
|
||||
armored: keyfile
|
||||
}, function (err, pubkeymgr) {
|
||||
if (!err) {
|
||||
keyring.add_key_manager(pubkeymgr);
|
||||
alert("Public key file loaded. You can now analyze PDFs signed by the key's owner.");
|
||||
} else {
|
||||
alert("Error loading public key: " + err);
|
||||
if (typeof nw != 'undefined') {
|
||||
var keyfile = getFileAsString(path);
|
||||
importpk(keyfile);
|
||||
} else {
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function (e) {
|
||||
importpk(e.target.result);
|
||||
}
|
||||
});
|
||||
fileReader.readAsText(html5file);
|
||||
}
|
||||
}, ".asc");
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ function openFileDialog(callback, accept) {
|
||||
dialog.setAttribute("accept", accept);
|
||||
}
|
||||
dialog.onchange = function () {
|
||||
callback(dialog.value);
|
||||
callback(dialog.value, this.files[0]);
|
||||
}
|
||||
dialog.dispatchEvent(new MouseEvent("click", {
|
||||
"view": window,
|
||||
|
154
src/js/pdf.js
154
src/js/pdf.js
@ -56,42 +56,84 @@ function analyzeSignedPDF() {
|
||||
return;
|
||||
}
|
||||
closePDF(false);
|
||||
openFileDialog(function (path) {
|
||||
var pdf = Buffer.from(getFileAsUint8Array(path).buffer);
|
||||
openFileDialog(function (path, html5file) {
|
||||
var analyze = function (pdf) {
|
||||
var splitindex = pdf.indexOf("-----BEGIN PGP MESSAGE-----");
|
||||
if (splitindex == -1) {
|
||||
alert("Selected file does not contain any recognized signature data.");
|
||||
return;
|
||||
}
|
||||
var pdfdata = pdf.slice(0, splitindex);
|
||||
var sigdata = pdf.slice(splitindex).toString();
|
||||
|
||||
var splitindex = pdf.indexOf("-----BEGIN PGP MESSAGE-----");
|
||||
if (splitindex == -1) {
|
||||
alert("Selected file does not contain any recognized signature data.");
|
||||
return;
|
||||
}
|
||||
var pdfdata = pdf.slice(0, splitindex);
|
||||
var sigdata = pdf.slice(splitindex).toString();
|
||||
var verify = function (pdfhash) {
|
||||
loadKeyFromLocalStorage(function () {
|
||||
verifyMessage(sigdata, function (msg, fprint) {
|
||||
parseAndDisplaySignature(msg, pdfhash, true, fprint);
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
console.log(sigdata);
|
||||
var base64 = sigdata.split("\n\n", 2)[1].split("\n-----END PGP MESSAGE-----")[0];
|
||||
base64 = base64.substring(0, base64.lastIndexOf("\n")).replaceAll("\n", "");
|
||||
try {
|
||||
var msg = window.atob(base64).split("START", 2)[1].split("END", 2)[0];
|
||||
parseAndDisplaySignature(msg, pdfhash, false, null);
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
alert("Error: could not parse signature data.");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var pdfhash = calculateSHA256HashOfString(pdfdata);
|
||||
if (typeof nw != 'undefined') {
|
||||
pdfjsLib.getDocument(pdf).promise.then(function (pdfDoc_) {
|
||||
pdfDoc = pdfDoc_;
|
||||
|
||||
loadKeyFromLocalStorage(function () {
|
||||
verifyMessage(sigdata, function (msg, fprint) {
|
||||
parseAndDisplaySignature(msg, pdfhash, true, fprint);
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
var base64 = sigdata.split("\n\n", 2)[1].split("\n-----END PGP MESSAGE-----")[0];
|
||||
base64 = base64.substring(0, base64.lastIndexOf("\n")).replaceAll("\n", "");
|
||||
try {
|
||||
var msg = window.atob(base64).split("START", 2)[1].split("END", 2)[0];
|
||||
parseAndDisplaySignature(msg, pdfhash, false, null);
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
alert("Error: could not parse signature data.");
|
||||
renderAllPages(pdfDoc);
|
||||
pdfZoom("fitheight");
|
||||
});
|
||||
} else {
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function () {
|
||||
pdfjsLib.getDocument(new Uint8Array(this.result)).promise.then(function (pdfDoc_) {
|
||||
pdfDoc = pdfDoc_;
|
||||
|
||||
renderAllPages(pdfDoc);
|
||||
pdfZoom("fitheight");
|
||||
});
|
||||
};
|
||||
fileReader.readAsArrayBuffer(html5file);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
pdfjsLib.getDocument(pdf).promise.then(function (pdfDoc_) {
|
||||
pdfDoc = pdfDoc_;
|
||||
|
||||
renderAllPages(pdfDoc);
|
||||
pdfZoom("fitheight");
|
||||
});
|
||||
if (typeof nw != 'undefined') {
|
||||
verify(calculateSHA256HashOfString(pdfdata));
|
||||
} else {
|
||||
window.crypto.subtle.digest("SHA-256", (new TextEncoder()).encode(pdfdata))
|
||||
.then(hash => {
|
||||
window.hash = hash;
|
||||
// here hash is an arrayBuffer,
|
||||
// so we'll connvert it to its hex version
|
||||
let result = '';
|
||||
const view = new DataView(hash);
|
||||
for (let i = 0; i < hash.byteLength; i += 4) {
|
||||
result += ('00000000' + view.getUint32(i).toString(16)).slice(-8);
|
||||
}
|
||||
verify(result);
|
||||
});
|
||||
}
|
||||
};
|
||||
if (typeof nw != 'undefined') {
|
||||
// running in NW.js so we have Node
|
||||
analyze(Buffer.from(getFileAsUint8Array(path).buffer));
|
||||
} else {
|
||||
// no Node :(
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function (e) {
|
||||
analyze(e.target.result);
|
||||
}
|
||||
fileReader.readAsBinaryString(html5file);
|
||||
}
|
||||
|
||||
}, ".pdf");
|
||||
}
|
||||
@ -143,25 +185,33 @@ then run the analyze tool again to prove if it was changed since notarization.")
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="fas fa-map-marked-alt fa-fw"></i> State: ' + sanitizeHTMLString(msgparts["STATE"]).toUpperCase() + '</li>');
|
||||
}
|
||||
if (typeof msgparts["OTS"] == "string") {
|
||||
var bytearray = [];
|
||||
var bytestrarray = msgparts["OTS"].match(/.{1,3}/g);
|
||||
for (var i = 0; i < bytestrarray.length; i++) {
|
||||
bytearray.push(bytestrarray[i] * 1);
|
||||
}
|
||||
const detached = OpenTimestamps.DetachedTimestampFile.fromHash(new OpenTimestamps.Ops.OpSHA256(), Uint8Array.from(Buffer.from(pdfhash, 'hex')));
|
||||
const detachedOts = OpenTimestamps.DetachedTimestampFile.deserialize(bytearray);
|
||||
let options = {};
|
||||
OpenTimestamps.verify(detachedOts, detached, options).then(verifyResult => {
|
||||
console.log(verifyResult);
|
||||
if (typeof verifyResult != "undefined") {
|
||||
if (typeof verifyResult.bitcoin != undefined) {
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="fas fa-clock fa-fw"></i> Signing time independently verified on the Bitcoin blockchain. Signed at ' + formatTimestamp("F j, Y g:i a", verifyResult.bitcoin.timestamp) + '</li>');
|
||||
}
|
||||
if (typeof verifyResult.litecoin != undefined) {
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="fas fa-clock fa-fw"></i> Signing time independently verified on the Litecoin blockchain. Signed at ' + formatTimestamp("F j, Y g:i a", verifyResult.bitcoin.timestamp) + '</li>');
|
||||
}
|
||||
try {
|
||||
var bytearray = [];
|
||||
var bytestrarray = msgparts["OTS"].match(/.{1,3}/g);
|
||||
for (var i = 0; i < bytestrarray.length; i++) {
|
||||
bytearray.push(bytestrarray[i] * 1);
|
||||
}
|
||||
});
|
||||
const detached = OpenTimestamps.DetachedTimestampFile.fromHash(new OpenTimestamps.Ops.OpSHA256(), Uint8Array.from(Buffer.from(pdfhash, 'hex')));
|
||||
const detachedOts = OpenTimestamps.DetachedTimestampFile.deserialize(bytearray);
|
||||
console.log(OpenTimestamps.info(detachedOts));
|
||||
let options = {
|
||||
ignoreBitcoinNode: true,
|
||||
timeout: 5000
|
||||
};
|
||||
OpenTimestamps.verify(detachedOts, detached, options).then(verifyResult => {
|
||||
console.log(verifyResult);
|
||||
if (typeof verifyResult != "undefined") {
|
||||
if (typeof verifyResult.bitcoin != undefined) {
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="fas fa-clock fa-fw"></i> Signing time independently verified on the Bitcoin blockchain. Signed at ' + formatTimestamp("F j, Y g:i a", verifyResult.bitcoin.timestamp) + '</li>');
|
||||
}
|
||||
if (typeof verifyResult.litecoin != undefined) {
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="fas fa-clock fa-fw"></i> Signing time independently verified on the Litecoin blockchain. Signed at ' + formatTimestamp("F j, Y g:i a", verifyResult.bitcoin.timestamp) + '</li>');
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
$("#verifyModalDetailedInfoList").append('<li class="list-group-item"><i class="far fa-file fa-fw"></i> Actual file hash: ' + pdfhash + '</li>');
|
||||
@ -287,6 +337,12 @@ function savePDF() {
|
||||
|
||||
function pdfZoom(str) {
|
||||
disableGuideBox();
|
||||
if ($("#page-canvas-container .page-canvas").length == 0) {
|
||||
setTimeout(function () {
|
||||
pdfZoom(str);
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
var widthpx = $("#page-canvas-container .page-canvas").css("width").replace("px", "") * 1;
|
||||
var zoomstep = 100;
|
||||
console.log(widthpx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user