#define _CRT_SECURE_NO_WARNINGS
#include <openssl/applink.c>
#include “OpenSSLSignatureHandler.h”
void SignPDF(const UString& in_docpath,
const UString& in_approval_field_name,
const UString& in_private_key_file_path,
const UString& in_keyfile_password,
const UString& in_appearance_img_path,
const UString& in_outpath)
{
/*
During the certification of a document, you are still using a digital signature to guarantee the integrity of the document.
However, you are also adding additional restriction on the document preventing further action on it.
The certification of a document being a reliable option, no futher action is possible once this has been applied:
:the modification will then need to be done on the original « non-sign/certified » document.
The option to certify is only available to the first signer of the document.
*/
cout << "================================================================================" << endl;
cout << "Signing PDF document" << endl;
// Open an existing PDF
PDFDoc doc(in_docpath);
// Retrieve the unsigned approval signature field.
Field found_approval_field(doc.GetField(in_approval_field_name));
PDF::DigitalSignatureField found_approval_signature_digsig_field(found_approval_field);
// Add an appearance to the signature field.
PDF::Image img = PDF::Image::Create(doc, in_appearance_img_path);
Annots::SignatureWidget found_approval_signature_widget(found_approval_field.GetSDFObj());
found_approval_signature_widget.CreateSignatureAppearance(img);
// Prepare the signature and signature handler for signing.
OpenSSLSignatureHandler sigHandler(in_private_key_file_path.ConvertToUtf8().c_str(), in_keyfile_password.ConvertToUtf8().c_str());
SignatureHandlerId sigHandlerId = doc.AddSignatureHandler(sigHandler);
found_approval_signature_digsig_field.SignOnNextSaveWithCustomHandler(sigHandlerId);
/* Add to the digital signature dictionary a SubFilter name that uniquely identifies the signature format for verification tools.
As an example, the custom handler defined in this file uses the CMS/PKCS #7 detached format, so we embed one of the standard predefined SubFilter values: "adbe.pkcs7.detached".
It is not necessary to do this when using the StdSignatureHandler. */
Obj f_obj = found_approval_signature_digsig_field.GetSDFObj();
f_obj.FindObj("V").PutName("SubFilter", "adbe.pkcs7.detached");
// The actual approval signing will be done during the following incremental save operation.
doc.Save(in_outpath, SDFDoc::e_incremental, NULL);
cout << "================================================================================" << endl;
}
void addDTSandEnableLTV(const UString& in_docpath,const UString& in_approval_field_name,const UString& tsa_cer_path,const UString& in_outpath) {
PDFDoc doc(in_docpath);
Field found_approval_field(doc.GetField(in_approval_field_name));
PDF::DigitalSignatureField found_approval_signature_digsig_field(found_approval_field);
TimestampingConfiguration tst_config("https://freetsa.org/tsr");
VerificationOptions opts(VerificationOptions::e_compatibility_and_archiving);
opts.AddTrustedCertificate("./Certificate V2/cacert.pem");
opts.EnableOnlineCRLRevocationChecking(true);
puts("Testing timestamping configuration.");
const TimestampingResult config_result(found_approval_signature_digsig_field.GenerateContentsWithEmbeddedTimestamp(tst_config, opts));
if (config_result.GetStatus()){
puts("Success: timestamping configuration usable. Attempting to timestamp.");
}
else{
// Print details of timestamping failure.
puts(config_result.GetString().ConvertToUtf8().c_str());
if (config_result.HasResponseVerificationResult()){
EmbeddedTimestampVerificationResult tst_result(config_result.GetResponseVerificationResult());
printf("CMS digest status: %s\n", tst_result.GetCMSDigestStatusAsString().ConvertToUtf8().c_str());
printf("Message digest status: %s\n", tst_result.GetMessageImprintDigestStatusAsString().ConvertToUtf8().c_str());
printf("Trust status: %s\n", tst_result.GetTrustStatusAsString().ConvertToUtf8().c_str());
}
}
}
int main(int * argc ,char * argv[])
{
PDFNet::Initialize(“demo:1633957651957:78a80cae03000000006daebb38099f54ad99b64ef524fca4902e1636bd”);
PDFDoc doc("testClear.pdf");
DigitalSignatureField approval_signature_field = doc.CreateDigitalSignatureField("PDFTronApprovalSig");
Annots::SignatureWidget widgetAnnotApproval = Annots::SignatureWidget::Create(doc, Rect(300, 287, 376, 306), approval_signature_field);
Page page1 = doc.GetPage(1);
page1.AnnotPushBack(widgetAnnotApproval);
doc.Save("waiver_withApprovalField_output.pdf", SDFDoc::e_remove_unused, 0);
SignPDF("waiver_withApprovalField_output.pdf", "PDFTronApprovalSig", "./Certificate V2/GemBoxRSA4096.pfx", "GemBoxPassword", "signature.jpg", "signed.pdf");
}