Skip to content

Commit e52f28c

Browse files
Add Digital Signature sample
Fix typo More cleanup
1 parent c66f3a3 commit e52f28c

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
//
2+
// Copyright (c) 2025, Datalogics, Inc. All rights reserved.
3+
//
4+
// This sample adds a digital signature with a logo to a PDF document.
5+
//
6+
// Command-line: <input-file> <output-file> <logo file> (All optional)
7+
//
8+
9+
#include <iostream>
10+
#include <string>
11+
#include "InitializeLibrary.h"
12+
#include "APDFLDoc.h"
13+
#include "PERCalls.h"
14+
15+
// Header that includes Digital Signature methods
16+
#include "DLExtrasCalls.h"
17+
18+
#define INPUT_LOC "../../../../Resources/Sample_Input/"
19+
#define DEF_INPUT "SixPages.pdf"
20+
#define DEF_OUTPUT "AddDigitalSignature-out.pdf"
21+
#define DEF_LOGO_FILE "ducky_alpha.tif"
22+
23+
// DEF_CERT_FILE points to the signer certificate which may be binary(.der file format)
24+
// or base-64 encoded(.pem file format).
25+
#define DEF_CERT_FILE "Credentials/DER/RSA_certificate.der"
26+
27+
// DEF_KEY_FILE points to the private key corresponding to the signer certificate defined above.
28+
// A key can be binary (.der file format) or base-64 encoded (.pem file format).
29+
#define DEF_KEY_FILE "Credentials/DER/RSA_privKey.der"
30+
31+
int main(int argc, char **argv) {
32+
APDFLib lib;
33+
34+
ASErrorCode errCode = 0;
35+
if (lib.isValid() == false) {
36+
errCode = lib.getInitError();
37+
std::cout << "Initialization failed with code " << errCode << std::endl;
38+
return errCode;
39+
}
40+
41+
std::string const csInputFileName(argc > 1 ? argv[1] : INPUT_LOC DEF_INPUT);
42+
std::string const csOutputFileName(argc > 2 ? argv[2] : DEF_OUTPUT);
43+
std::string const csLogoFileName(argc > 3 ? argv[2] : INPUT_LOC DEF_LOGO_FILE);
44+
std::cout << "Will apply a digital signature to " << csInputFileName.c_str() << " with a logo "
45+
<< csLogoFileName.c_str() << " and save as " << csOutputFileName.c_str() << std::endl;
46+
47+
DURING
48+
49+
// Open the input document.
50+
APDFLDoc APDoc(csInputFileName.c_str(), true);
51+
PDDoc inDoc = APDoc.getPDDoc();
52+
53+
// Setup Sign params
54+
PDSignDocSignParams const signParams = PDSignDocSignInitParams();
55+
56+
PDSignDocSetFieldID(signParams, CreateFieldWithQualifiedName);
57+
58+
// Set the size and location of the signature box (optional)
59+
// If not set, invisible signature will be placed on first page
60+
ASFixedRect annotLocation;
61+
annotLocation.left = ASFloatToFixed(1.0 * 72);
62+
annotLocation.right = ASFloatToFixed(4.0 * 72);
63+
annotLocation.top = ASFloatToFixed(6.0 * 72);
64+
annotLocation.bottom = ASFloatToFixed(8.0 * 72);
65+
PDSignDocSetSignatureBoxPageNumber(signParams, 0);
66+
PDSignDocSetSignatureBoxRectangle(signParams, &annotLocation);
67+
68+
ASText fieldName = ASTextFromEncoded("Signature_es_:signatureblock", PDGetHostEncoding());
69+
PDSignDocSetFieldName(signParams, fieldName);
70+
71+
// Set credential related attributes
72+
PDSignDocSetDigestCategory(signParams, sha256);
73+
PDSignDocSetCredentialDataFormat(signParams, NonPFX);
74+
75+
ASPathName certPath = APDFLDoc::makePath(INPUT_LOC DEF_CERT_FILE);
76+
ASPathName keyPath = APDFLDoc::makePath(INPUT_LOC DEF_KEY_FILE);
77+
78+
ASFile asCertFileDER{nullptr};
79+
ASErrorCode err = ASFileSysOpenFile64(nullptr, certPath, (ASFILE_READ | ASFILE_SERIAL), &asCertFileDER);
80+
81+
ASFile asKeyFileDER{nullptr};
82+
err = ASFileSysOpenFile64(nullptr, keyPath, (ASFILE_READ | ASFILE_SERIAL), &asKeyFileDER);
83+
84+
PDSignDocSetNonPfxSignerCert(signParams, asCertFileDER, 0, OnDisk);
85+
PDSignDocSetNonPfxPrivateKey(signParams, asKeyFileDER, 0, OnDisk);
86+
87+
// Setup the signer information
88+
ASText name = ASTextFromEncoded("John Doe", PDGetHostEncoding());
89+
ASText location = ASTextFromEncoded("Chicago, IL", PDGetHostEncoding());
90+
ASText reason = ASTextFromEncoded("Approval", PDGetHostEncoding());
91+
ASText contact = ASTextFromEncoded("Datalogics, Inc.", PDGetHostEncoding());
92+
93+
// Setup the logo image (optional)
94+
ASPathName logoPath = APDFLDoc::makePath(csLogoFileName.c_str());
95+
ASFile asLogoFile{nullptr};
96+
err = ASFileSysOpenFile64(nullptr, logoPath, (ASFILE_READ | ASFILE_SERIAL), &asLogoFile);
97+
PDEImage logo{DLCreatePDEImageFromASFile(asLogoFile)};
98+
ASFixed const opacity{FloatToASFixed(0.50f)};
99+
100+
PDSignDocSetSignerInfo(signParams, logo, opacity, name, location, reason, contact,
101+
DisplayTraits::kDisplayAll);
102+
103+
// Setup Save params
104+
PDSignDocSaveParams const saveParams = PDSignDocSaveInitParams();
105+
ASPathName outPathName = APDFLDoc::makePath(csOutputFileName.c_str());
106+
107+
PDSignDocSetOutputPath(saveParams, outPathName);
108+
109+
// Finally, sign and save the document
110+
PDSignDocWithParams(inDoc, saveParams, signParams);
111+
112+
// Cleanup
113+
ASTextDestroy(fieldName);
114+
ASTextDestroy(name);
115+
ASTextDestroy(location);
116+
ASTextDestroy(reason);
117+
ASTextDestroy(contact);
118+
119+
// Release logo object
120+
PDERelease(reinterpret_cast<PDEObject>(logo));
121+
ASFileSysReleasePath(nullptr, logoPath);
122+
123+
// Release credential objects
124+
ASFileSysReleasePath(nullptr, certPath);
125+
ASFileSysReleasePath(nullptr, keyPath);
126+
ASFileClose(asCertFileDER);
127+
ASFileClose(asKeyFileDER);
128+
129+
ASFileClose(asLogoFile);
130+
PDDocClose(inDoc);
131+
ASFileSysReleasePath(nullptr, outPathName);
132+
133+
HANDLER
134+
errCode = ERRORCODE;
135+
lib.displayError(errCode);
136+
END_HANDLER
137+
138+
return errCode;
139+
};

Security/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## AddDigitalSignature
2+
Demonstrates adding a digital signature with a logo to a PDF document.
3+
14
## AddPassword
25
Demonstrates protecting a PDF with a password. To open or edit the saved PDF, you must supply the password.
36

0 commit comments

Comments
 (0)