poppler/Form.cc | 2 +- utils/pdfsig.1 | 4 ++-- utils/pdfsig.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 4 deletions(-)
New commits: commit 64ccb8d248611fd1d7aef279d08ea7589a4e1fcb Author: Erich E. Hoover <[email protected]> Date: Mon Aug 1 16:02:05 2022 -0600 pdfsig: Add support for specifying signature by field name diff --git a/utils/pdfsig.1 b/utils/pdfsig.1 index 7e262009..872c6e8d 100644 --- a/utils/pdfsig.1 +++ b/utils/pdfsig.1 @@ -58,8 +58,8 @@ Add a new signature to the document. .B \-new-signature-field-name " name" Specifies the field name to be used when adding a new signature. A random ID will be used by default. .TP -.B \-sign " n" -Sign the document in the n-th signature field present in the document (must be unsigned). +.B \-sign " field" +Sign the document in the specified signature field present in the document (must be unsigned). Field can be specified by field name (string) or the n-th signature field in the document (integer). .TP .B \-nick " nickname" Use the certificate with the given nickname for signing. diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc index 88ce3808..ca522de9 100644 --- a/utils/pdfsig.cc +++ b/utils/pdfsig.cc @@ -136,6 +136,7 @@ static bool dontVerifyCert = false; static bool noOCSPRevocationCheck = false; static bool dumpSignatures = false; static bool etsiCAdESdetached = false; +static char signatureName[256] = ""; static int signatureNumber = 0; static char certNickname[256] = ""; static char password[256] = ""; @@ -154,7 +155,7 @@ static const ArgDesc argDesc[] = { { "-nssdir", argGooString, &nssDir, 0, "path { "-dump", argFlag, &dumpSignatures, 0, "dump all signatures into current directory" }, { "-add-signature", argFlag, &addNewSignature, 0, "adds a new signature to the document" }, { "-new-signature-field-name", argGooString, &newSignatureFieldName, 0, "field name used for the newly added signature. A random ID will be used if empty" }, - { "-sign", argInt, &signatureNumber, 0, "sign the document in the signature field with the given number" }, + { "-sign", argString, &signatureName, 256, "sign the document in the given signature field (by name or number)" }, { "-etsi", argFlag, &etsiCAdESdetached, 0, "create a signature of type ETSI.CAdES.detached instead of adbe.pkcs7.detached" }, { "-nick", argString, &certNickname, 256, "use the certificate with the given nickname for signing" }, { "-kpw", argString, &password, 256, "password for the signing key (might be missing if the key isn't password protected)" }, @@ -301,6 +302,15 @@ int main(int argc, char *argv[]) return 1; } + if (strlen(signatureName) > 0) { + signatureNumber = atoi(signatureName); + if (signatureNumber == 0) { + signatureNumber = -1; + } + } else { + signatureNumber = 0; + } + if (addNewSignature && signatureNumber > 0) { // incompatible options print_version_usage(true); @@ -367,6 +377,26 @@ int main(int argc, char *argv[]) const std::vector<FormFieldSignature *> signatures = doc->getSignatureFields(); const unsigned int sigCount = signatures.size(); + if (signatureNumber == -1) { + for (unsigned int i = 0; i < sigCount; i++) { + const GooString *goo = signatures.at(i)->getCreateWidget()->getField()->getFullyQualifiedName(); + if (!goo) { + continue; + } + + const std::string name = TextStringToUTF8(goo->toStr()); + if (name == signatureName) { + signatureNumber = i + 1; + break; + } + } + + if (signatureNumber == -1) { + fprintf(stderr, "Signature field not found by name\n"); + return 2; + } + } + if (signatureNumber > 0) { // We are signing an existing signature field if (argc == 2) { commit ec71a5dc45039f2a8352b99803e98c148a2679a8 Author: Erich E. Hoover <[email protected]> Date: Fri Jul 29 10:12:53 2022 -0600 pdfsig: List signature field names when listing signature information diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc index 6effd9d4..88ce3808 100644 --- a/utils/pdfsig.cc +++ b/utils/pdfsig.cc @@ -217,6 +217,23 @@ static std::vector<std::unique_ptr<X509CertificateInfo>> getAvailableSigningCert return vCerts; } +static std::string TextStringToUTF8(const std::string &str) +{ + const UnicodeMap *utf8Map = globalParams->getUtf8Map(); + + Unicode *u; + int len = TextStringToUCS4(str, &u); + + std::string convertedStr; + for (int i = 0; i < len; ++i) { + char buf[8]; + const int n = utf8Map->mapUnicode(u[i], buf, sizeof(buf)); + convertedStr.append(buf, n); + } + + return convertedStr; +} + int main(int argc, char *argv[]) { char *time_str = nullptr; @@ -422,6 +439,11 @@ int main(int argc, char *argv[]) for (unsigned int i = 0; i < sigCount; i++) { FormFieldSignature *ffs = signatures.at(i); printf("Signature #%u:\n", i + 1); + const GooString *goo = ffs->getCreateWidget()->getField()->getFullyQualifiedName(); + if (goo) { + const std::string name = TextStringToUTF8(goo->toStr()); + printf(" - Signature Field Name: %s\n", name.c_str()); + } if (ffs->getSignatureType() == unsigned_signature_field) { printf(" The signature form field is not signed.\n"); commit 41af89601202f7973a6044f31ed14eba05c77f9a Author: Erich E. Hoover <[email protected]> Date: Tue Aug 2 14:12:06 2022 -0600 Fix convertToUtf16 so it does not add the Unicode marker to the output string diff --git a/poppler/Form.cc b/poppler/Form.cc index 2b725606..3ee37611 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -103,7 +103,7 @@ static GooString *convertToUtf16(GooString *pdfDocEncodingString) int tmp_length; char *tmp_str = pdfDocEncodingToUTF16(pdfDocEncodingString->toStr(), &tmp_length); delete pdfDocEncodingString; - pdfDocEncodingString = new GooString(tmp_str, tmp_length); + pdfDocEncodingString = new GooString(tmp_str + 2, tmp_length - 2); // Remove the unicode BOM delete[] tmp_str; return pdfDocEncodingString; }
