/********************************************************************* PDF-AS.SigHandler.cpp *********************************************************************/ #include "PDF-AS.SigHandler.h" #include "FormsHFT.h" #include #include #include using namespace std; HFT gDigSigHFT = NULL; HFT gAcroFormHFT = NULL; HFT gPubSecHFT = NULL; boolean gSigHandlerInitialized = false; clock_t openStamp = 0; clock_t validatedStamp = 0; map verifyUrls; #define OPEN_INTERVAL 2000 // ms. no validation after document was opened #define VALID_INTERVAL 6000 // ms. no multi signature validation /*------------------------------------------------------- Custom validation Callbacks -------------------------------------------------------*/ // on document open static ACCBPROTO1 void ACCBPROTO2 DSDocOpen(PDDoc pdDoc) { // do nothing, no auto validation openStamp = clock(); } // not called static ACCBPROTO1 ASBool ACCBPROTO2 DSCanValidate(PDDoc pdDoc, CosObj sigField, CosObj sigAnnot, ASAtom filter ) { return true; } // validate signature static ACCBPROTO1 DSValidState ACCBPROTO2 DSValidateSig(PDDoc pdDoc, CosObj sigField, CosObj sigAnnot) { int i = 9; long startDif = clock() - openStamp; if (startDif < OPEN_INTERVAL) { return DSSigValid; } long validateDif = clock() - validatedStamp; //if (validateDif < VALID_INTERVAL) { // return DSSigValid; //} CosObj sigEntry = CosDictGet(sigAnnot, ASAtomFromString("V")); CosObj urlObj = CosDictGet(sigEntry, ASAtomFromString("ContactInfo")); char *urlStr = "https://www.buergerkarte.at/signature-verification"; // default url if (CosObjGetType(urlObj) == CosString) { ASTCount len; urlStr = CosStringValue(urlObj, &len ); } if (validateDif < VALID_INTERVAL) { // multi sig verify //string ustr (urlStr); if (verifyUrls.find(urlStr) == verifyUrls.end()) { verifyUrls[urlStr] = true; } else { return DSSigValid; } } else { verifyUrls.clear(); verifyUrls[urlStr]; } char msg[1024]; sprintf(msg, "Dieses Dokument enthält PDF-AS Signaturen. Wollen Sie diese unter %s verifizieren?", urlStr); ASInt32 choice = AVAlert(ALERT_NOTE, msg, "Ja", "Nein", NULL, false); validatedStamp = clock(); if(choice==2) { return DSSigUnknown; } //AVAlertNote("Diese PDF-AS Signatur kann unter www.buergerkarte.at verifiziert werden"); //string url = "https://www.buergerkarte.at/signature-verification"; // get this from document char script[2048]; sprintf(script, "app.launchURL('%s', true)", urlStr); AFExecuteThisScript (pdDoc, script, NULL); return DSSigValid; } /*------------------------------------------------------- Core Handshake Callbacks -------------------------------------------------------*/ /* DocSignExportHFTs ** ------------------------------------------------------ ** ** Create and register the HFT's. ** ** Return true to continue loading plug-in. ** Return false to cause plug-in loading to stop. */ ACCB1 ASBool ACCB2 DocSignExportHFTs(void) { return true; } /* DocSignImportReplaceAndRegister ** ------------------------------------------------------ ** ** This routine is where you can: ** 1) Import plug-in supplied HFTs. ** 2) Replace functions in the HFTs you're using (where allowed). ** 3) Register to receive notification events. ** ** Return true to continue loading plug-in. ** Return false to cause plug-in loading to stop. */ ACCB1 ASBool ACCB2 DocSignImportReplaceAndRegister(void) { gDigSigHFT = ASExtensionMgrGetHFT(ASAtomFromString("DigSigHFT"), 1); if (!gDigSigHFT) return false; gAcroFormHFT = Init_AcroFormHFT; if(!gAcroFormHFT) return false; /* PubSec HFT */ gPubSecHFT = ASExtensionMgrGetHFT(ASAtomFromString("PubSecHFT"), 1); if (!gPubSecHFT) return false; return true; } /* DocSignInit ** ------------------------------------------------------ ** ** The main initialization routine. ** ** Return true to continue loading plug-in. ** Return false to cause plug-in loading to stop. */ ACCB1 ASBool ACCB2 DocSignInit(void) { DSRegisterSignatureHandler(); return true; } void DSRegisterSignatureHandler() { DigSigHandlerRec gSigHandlerRec; if( gDigSigHFT == NULL ) return; if (!gSigHandlerInitialized) { memset( &gSigHandlerRec, 0, sizeof(DigSigHandlerRec) ); gSigHandlerRec.size = sizeof (DigSigHandlerRec); gSigHandlerRec.uiName = PDFAS_HANDLER_NAME; gSigHandlerRec.filterKey = ASAtomFromString(PDFAS_HANDLER_NAME); gSigHandlerRec.canBlindSign = true; gSigHandlerRec.canEncrypt = true; gSigHandlerRec.dsDocOpen = ASCallbackCreateProto(DSDocOpenProc, DSDocOpen ); //gSigHandlerRec.dsGetBoolProperty = ASCallbackCreateProto(DSGetBoolPropertyProc, DSGetBoolProperty ); gSigHandlerRec.dsCanValidate = ASCallbackCreateProto(DSCanValidateProc, DSCanValidate ); //gSigHandlerRec.dsDocClose = ASCallbackCreateProto(DSDocCloseProc, DSDocClose ); //gSigHandlerRec.dsDefaultValue = ASCallbackCreateProto(DSDefaultValueProc, DSDefaultValue ); //gSigHandlerRec.dsNewSigData = // ASCallbackCreateProto(DSNewSigDataProc, DSNewSigData ); //gSigHandlerRec.dsCommitSign = // ASCallbackCreateProto(DSCommitSignProc, DSCommitSign ); //gSigHandlerRec.dsFinishSign = // ASCallbackCreateProto(DSFinishSignProc, DSFinishSign ); //gSigHandlerRec.dsFreeSigData = // ASCallbackCreateProto(DSFreeSigDataProc, DSFreeSigData ); gSigHandlerRec.dsValidateSig = ASCallbackCreateProto(DSValidateSigProc, DSValidateSig ); //gSigHandlerRec.dsGetValidState = // ASCallbackCreateProto(DSGetValidStateProc, DSGetValidState ); //gSigHandlerRec.dsProperties = (void (__cdecl*)(PDDoc ,CosObj, CosObj))NULL; //ASCallbackCreateProto(DSPropertiesProc, DSProperties ); //gSigHandlerRec.dsUnValidateSig = // ASCallbackCreateProto(DSUnValidateSigProc, DSUnValidateSig ); //gSigHandlerRec.dsReValidateSig = // ASCallbackCreateProto(DSUnValidateSigProc, DSReValidateSig ); gSigHandlerInitialized = true; } DigSigRegisterFilter( gExtensionID, &gSigHandlerRec ); } /** not used, left as example **/ void RegisterFHandler() { PubSecHandlerRec fHandlerRec; if( true ) { memset( &fHandlerRec, 0, sizeof(fHandlerRec) ); fHandlerRec.size = sizeof(PubSecHandlerRec); //fHandlerRec.getBoolProperty = ASCallbackCreateProto(PSGetBoolPropertyProc, GetBoolProperty ); //fHandlerRec.getAtomProperty = ASCallbackCreateProto(PSGetAtomPropertyProc, GetAtomProperty ); //fHandlerRec.getTextProperty = ASCallbackCreateProto(PSGetTextPropertyProc, GetTextProperty ); //fHandlerRec.getInt32Property = ASCallbackCreateProto(PSGetInt32PropertyProc, GetInt32Property ); //fHandlerRec.newEngine = ASCallbackCreateProto(PSNewEngineProc, DSHandler::NewEngine ); //fHandlerRec.destroyEngine = ASCallbackCreateProto(PSDestroyEngineProc, DSHandler::DestroyEngine ); //fHandlerRec.sessionAcquire = ASCallbackCreateProto(PSSessionAcquireProc, DSHandler::SessionAcquire ); //fHandlerRec.sessionRelease = ASCallbackCreateProto(PSSessionReleaseProc, DSHandler::SessionRelease ); //fHandlerRec.sessionReady = ASCallbackCreateProto(PSSessionReadyProc, DSHandler::SessionReady ); //fHandlerRec.performOperation = ASCallbackCreateProto(PSPerformOperationProc, DSHandler::PerformOperation ); //fHandlerRec.sigGetSigProperties = ASCallbackCreateProto(PSSigGetSigPropertiesProc, DSHandler::SigGetSigProperties ); //fHandlerRec.sigAuthenticate = ASCallbackCreateProto(PSSigAuthenticateProc, DSHandler::SigAuthenticate ); //fHandlerRec.sigGetSigValue = ASCallbackCreateProto(PSSigGetSigValueProc, DSHandler::SigGetSigValue ); //// Set up this callback if you want to have custom appearance //fHandlerRec.sigCreateAPNXObj = ASCallbackCreateProto(PSSigCreateAPNXObjProc, DSHandler::SigCreateAPNXObj ); //fHandlerRec.sigValidate = ASCallbackCreateProto(PSSigValidateProc, DSHandler::SigValidate ); //fHandlerRec.sigValidateDialog = NULL; //fHandlerRec.sigPropDialog = NULL; //fHandlerRec.getLogo = ASCallbackCreateProto(PSGetLogoProc, DSHandler::GetLogo ); //// SigVal methods //fHandlerRec.sigValGetText = ASCallbackCreateProto(PSSigValGetTextProc, DSSigVal::GetText ); //// Once you set up the PSSigCreateAPNXObjProc callback, you must set up this callback //// in order to have the PSGetLogoProc callback invoked //fHandlerRec.sigValGetAPLabel = ASCallbackCreateProto(PSSigValGetAPLabelProc, DSSigVal::GetAPLabel ); //// Cert exchange methods //fHandlerRec.exportData = ASCallbackCreateProto(PSExportDataProc, DSHandler::ExportData ); //fHandlerRec.importData = NULL; // //// Encryption methods //fHandlerRec.cryptOpenCMSEnvelope = ASCallbackCreateProto(PSOpenCMSEnvelopeProc, DSHandler::openCMSEnvelope); //fHandlerRec.cryptGetImplicitRecipients = ASCallbackCreateProto(PSGetImplicitRecipientsProc, DSHandler::getImplicitRecipients); //fbHandlerIsInit = true; } /* Register security handler. Note that ownership of this struct is retained by this plug-in */ ASBool bOk = PSRegisterHandler( gExtensionID, &fHandlerRec ); } /* DocSignUnload ** ------------------------------------------------------ ** ** The unload routine. ** ** Called when your plug-in is being unloaded when the application quits. ** Use this routine to release any system resources you may have ** allocated. ** ** Returning false will cause an alert to display that unloading failed. */ ACCB1 ASBool ACCB2 DocSignUnload(void) { return true; } /* GetExtensionName ** ------------------------------------------------------ ** ** Get the extension name associated with this plugin */ ASAtom GetExtensionName() { return ASAtomFromString("PDF-AS.SigHandler"); /* Change to your extension's name */ } /* ** PIHandshake ** Required Plug-in handshaking routine: Do not change it's name! PIMain.c expects ** this function to be named and typed as shown. */ ACCB1 ASBool ACCB2 PIHandshake(Uns32 handshakeVersion, void *handshakeData) { if (handshakeVersion == HANDSHAKE_V0200) { /* Cast handshakeData to the appropriate type */ PIHandshakeData_V0200 *hsData = (PIHandshakeData_V0200 *)handshakeData; /* Set the name we want to go by */ hsData->extensionName = GetExtensionName(); /* If you export your own HFT, do so in here */ hsData->exportHFTsCallback = ASCallbackCreate(&DocSignExportHFTs); /* ** If you import plug-in HFTs, replace functionality, and/or want to register for notifications before ** the user has a chance to do anything, do so in here. */ hsData->importReplaceAndRegisterCallback = ASCallbackCreate( &DocSignImportReplaceAndRegister); /* Perform your plug-in's initialization in here */ hsData->initCallback = ASCallbackCreate(&DocSignInit); /* Perform any memory freeing or state saving on "quit" in here */ hsData->unloadCallback = ASCallbackCreate(&DocSignUnload); /* All done */ return true; } /* Each time the handshake version changes, add a new "else if" branch */ /* ** If we reach here, then we were passed a handshake version number we don't know about. ** This shouldn't ever happen since our main() routine chose the version number. */ return false; }