@ -16,9 +16,6 @@ function addPDF() {
openFileDialog ( function ( path ) {
var filedata = getFileAsUint8Array ( path ) ;
/ * *
* Asynchronously downloads PDF .
* /
pdfjsLib . getDocument ( filedata ) . promise . then ( function ( pdfDoc _ ) {
pdfDoc = pdfDoc _ ;
@ -40,6 +37,101 @@ function closePDF(showuserconfirm) {
$ ( "#page-canvas-container .page-canvas" ) . remove ( ) ;
}
function analyzeSignedPDF ( ) {
if ( $ ( "#page-canvas-container .page-canvas" ) . length > 0 && ! confirm ( "Opening a PDF to analyze will close the open document. Are you sure?" ) ) {
return ;
}
closePDF ( false ) ;
openFileDialog ( function ( path ) {
var pdf = Buffer . from ( getFileAsUint8Array ( path ) . buffer ) ;
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 pdfhash = calculateSHA256HashOfString ( pdfdata ) ;
verifyMessage ( sigdata , function ( msg , fprint ) {
parseAndDisplaySignature ( msg , pdfhash , true , fprint ) ;
} , function ( 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 = 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." ) ;
}
} ) ;
pdfjsLib . getDocument ( pdf ) . promise . then ( function ( pdfDoc _ ) {
pdfDoc = pdfDoc _ ;
renderAllPages ( pdfDoc ) ;
pdfZoom ( "fitheight" ) ;
} ) ;
} , ".pdf" ) ;
}
function parseAndDisplaySignature ( msg , pdfhash , verified , fingerprint ) {
var msgparts = { } ;
// Decode message contents
var msglines = msg . split ( "\n" ) ;
for ( var i = 0 ; i < msglines . length ; i ++ ) {
if ( msglines [ i ] . includes ( ":" ) ) {
var parts = msglines [ i ] . split ( ":" , 2 ) ;
msgparts [ parts [ 0 ] ] = parts [ 1 ] ;
}
}
if ( typeof msgparts [ "HASH" ] == "string" ) {
if ( msgparts [ "HASH" ] == pdfhash ) {
if ( verified ) {
$ ( "#verifyModalStatusMessage" ) . html ( "<i class=\"fas fa-check-circle\"></i> File contents match signature. File has not been changed since notarization." ) ;
$ ( "#verifyModalStatusMessage" ) . removeClass ( ) ;
$ ( "#verifyModalStatusMessage" ) . addClass ( [ "alert" , "alert-success" ] ) ;
} else {
$ ( "#verifyModalStatusMessage" ) . html ( "<i class=\"fas fa-question-circle\" > < / i > F i l e c o n t e n t s m a t c h s i g n a t u r e ; h o w e v e r , \
could not verify signature authenticity . It ' s possible the file was changed then re - signed by an unknown person . If you have the \
public key file for the notary that signed the file , < span class = \ "btn btn-outline-secondary btn-sm\"onclick=\"openPublicKeyFile()\" > click here < / s p a n > t o u s e i t , \
then try running the analyze tool again . " ) ;
$ ( "#verifyModalStatusMessage" ) . removeClass ( ) ;
$ ( "#verifyModalStatusMessage" ) . addClass ( [ "alert" , "alert-warning" ] ) ;
}
} else {
$ ( "#verifyModalStatusMessage" ) . html ( "<i class=\"fas fa-exclamation-circle\"></i> File contents do not match signature. Document has been modified since notarization." ) ;
$ ( "#verifyModalStatusMessage" ) . removeClass ( ) ;
$ ( "#verifyModalStatusMessage" ) . addClass ( [ "alert" , "alert-danger" ] ) ;
}
} else {
$ ( "#verifyModalStatusMessage" ) . html ( "<i class=\"fas fa-exclamation-circle\"></i> No file hash found in document signature. Could not verify document integrity." ) ;
$ ( "#verifyModalStatusMessage" ) . removeClass ( ) ;
$ ( "#verifyModalStatusMessage" ) . addClass ( [ "alert" , "alert-danger" ] ) ;
}
// Add extra data to a list below the big message
$ ( "#verifyModalDetailedInfoList" ) . html ( "" ) ;
if ( typeof msgparts [ "DATE" ] == "string" && isNaN ( msgparts [ "DATE" ] ) == false ) {
var datestr = formatTimestamp ( "F j, Y g:i a" , msgparts [ "DATE" ] ) ;
$ ( "#verifyModalDetailedInfoList" ) . append ( '<li class="list-group-item"><i class="far fa-calendar-alt fa-fw"></i> Notarization date/time: ' + datestr + '</li>' ) ;
}
if ( typeof msgparts [ "NOTARY" ] == "string" ) {
$ ( "#verifyModalDetailedInfoList" ) . append ( '<li class="list-group-item"><i class="fas fa-user fa-fw"></i> Notary: ' + sanitizeHTMLString ( msgparts [ "NOTARY" ] ) + '</li>' ) ;
}
if ( typeof msgparts [ "STATE" ] == "string" ) {
$ ( "#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 fingerprint == "string" ) {
$ ( "#verifyModalDetailedInfoList" ) . append ( '<li class="list-group-item"><i class="fas fa-fingerprint fa-fw"></i> Signature fingerprint: ' + fingerprint + '</li>' ) ;
}
new bootstrap . Modal ( document . getElementById ( 'verifyModal' ) ) . show ( ) ;
}
function generatePDF ( callback ) {
var canvases = $ ( "#page-canvas-container .page-canvas" ) ;
var statustextEl = $ ( "#statustext" ) ;
@ -84,15 +176,14 @@ function getPDFAsByteArray(pdf) {
}
function makeAndSaveSignedPDF ( pdf , savepath , callback ) {
const hasha = require ( 'hasha' ) ;
var pdfbuffer = pdf . output ( "arraybuffer" ) ;
var hashstr = hasha ( Buffer . from ( pdfbuffer ) , { algorithm : 'sha256' } ) ;
var message = "HASH:" + hashstr
var hashstr = calculateSHA256HashOfBuffer ( pdfbuffer ) ;
var message = "START"
+ "\nHASH:" + hashstr
+ "\nDATE:" + time ( )
+ "\nNOTARY:" + getStorage ( "notary_name" )
+ "\nSTATE:" + getStorage ( "notary_state" )
+ "\n ";
+ "\n END\n ";
signMessage ( message , keymgr , function ( sig ) {
writeToFile ( savepath , Buffer . from ( pdfbuffer ) ) ;
appendToFile ( savepath , sig ) ;