diff --git a/src/js/crypto.js b/src/js/crypto.js index db11a8c..b0c485b 100644 --- a/src/js/crypto.js +++ b/src/js/crypto.js @@ -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"); } diff --git a/src/js/filesystem.js b/src/js/filesystem.js index 4db9347..2785305 100644 --- a/src/js/filesystem.js +++ b/src/js/filesystem.js @@ -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, diff --git a/src/js/pdf.js b/src/js/pdf.js index 911a94b..c55eca3 100644 --- a/src/js/pdf.js +++ b/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('