diff options
author | Erich E. Hoover <erich.e.hoover@gmail.com> | 2024-02-08 11:07:24 -0700 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2024-02-18 17:45:13 +0000 |
commit | a7f1652ebdb78a4757565a91b62294ad7333ec75 (patch) | |
tree | 543fcde1d305d878061e61361a5ac75cfa90538b | |
parent | 53b98e8d3c7783b4340e6006e7641fa6b0ffe3ec (diff) |
pdfsig: Sign form signature fields with an appearance
-rw-r--r-- | utils/CMakeLists.txt | 7 | ||||
-rw-r--r-- | utils/pdfsig.1 | 3 | ||||
-rw-r--r-- | utils/pdfsig.cc | 33 | ||||
-rw-r--r-- | utils/po/CMakeLists.txt | 26 | ||||
-rw-r--r-- | utils/po/pdfsig.pot | 26 |
5 files changed, 94 insertions, 1 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index d9795eb9..8fb7a509 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -1,3 +1,4 @@ +include(FindGettext) set(common_srcs parseargs.cc @@ -93,6 +94,12 @@ target_link_libraries(pdfinfo ${common_libs}) install(TARGETS pdfinfo DESTINATION bin) install(FILES pdfinfo.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +if (GETTEXT_FOUND AND ENABLE_SIGNATURES) + add_definitions(-DHAVE_GETTEXT) + add_definitions(-DCMAKE_INSTALL_LOCALEDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}") + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/po") +endif () + if (ENABLE_SIGNATURES) # pdfsig set(pdfsig_SOURCES ${common_srcs} diff --git a/utils/pdfsig.1 b/utils/pdfsig.1 index 30364684..93bb5ea5 100644 --- a/utils/pdfsig.1 +++ b/utils/pdfsig.1 @@ -46,6 +46,9 @@ Do not validate the certificate. .B \-no-ocsp Do not perform online OCSP certificate revocation check (local Certificate Revocation Lists (CRL) are still used). .TP +.B \-no-appearance +Do not add appearance information when signing existing fields (signer name and date). +.TP .B \-aia Enable the use of Authority Information Access (AIA) extension to fetch missing certificates to build the certificate chain. .TP diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc index ecf43e9a..d9079611 100644 --- a/utils/pdfsig.cc +++ b/utils/pdfsig.cc @@ -38,6 +38,7 @@ #include "Page.h" #include "PDFDoc.h" #include "PDFDocFactory.h" +#include "DateInfo.h" #include "Error.h" #include "GlobalParams.h" #ifdef ENABLE_NSS3 @@ -52,6 +53,14 @@ # include <libgen.h> #endif +#ifdef HAVE_GETTEXT +# include <libintl.h> +# include <clocale> +# define _(STRING) gettext(STRING) +#else +# define _(STRING) STRING +#endif + static const char *getReadableSigState(SignatureValidationStatus sig_vs) { switch (sig_vs) { @@ -139,6 +148,7 @@ static bool printHelp = false; static bool printCryptoSignBackends = false; static bool dontVerifyCert = false; static bool noOCSPRevocationCheck = false; +static bool noAppearance = false; static bool dumpSignatures = false; static bool etsiCAdESdetached = false; static char backendString[256] = ""; @@ -156,6 +166,7 @@ static const ArgDesc argDesc[] = { { "-nssdir", argGooString, &nssDir, 0, "path { "-nss-pwd", argGooString, &nssPassword, 0, "password to access the NSS database (if any)" }, { "-nocert", argFlag, &dontVerifyCert, 0, "don't perform certificate validation" }, { "-no-ocsp", argFlag, &noOCSPRevocationCheck, 0, "don't perform online OCSP certificate revocation check" }, + { "-no-appearance", argFlag, &noAppearance, 0, "don't add appearance information when signing existing fields" }, { "-aia", argFlag, &useAIACertFetch, 0, "use Authority Information Access (AIA) extension for certificate fetching" }, { "-dump", argFlag, &dumpSignatures, 0, "dump all signatures into current directory" }, { "-add-signature", argFlag, &addNewSignature, 0, "adds a new signature to the document" }, @@ -512,8 +523,28 @@ int main(int argc, char *argv[]) printf("Unexpected number of widgets for the signature: %d\n", ffs->getNumWidgets()); return 2; } +#ifdef HAVE_GETTEXT + if (!noAppearance) { + setlocale(LC_ALL, ""); + bindtextdomain("pdfsig", CMAKE_INSTALL_LOCALEDIR); + textdomain("pdfsig"); + } +#endif FormWidgetSignature *fws = static_cast<FormWidgetSignature *>(ffs->getWidget(0)); - const bool success = fws->signDocument(std::string { argv[2] }, std::string { certNickname }, std::string { password }, rs.get()); + auto backend = CryptoSign::Factory::createActive(); + auto sigHandler = backend->createSigningHandler(certNickname, HashAlgorithm::Sha256); + std::unique_ptr<X509CertificateInfo> certInfo = sigHandler->getCertificateInfo(); + if (!certInfo) { + fprintf(stderr, "signDocument: error getting signature info\n"); + return 2; + } + const std::string signerName = certInfo->getSubjectInfo().commonName; + const std::string timestamp = timeToStringWithFormat(nullptr, "%Y.%m.%d %H:%M:%S %z"); + const AnnotColor blackColor(0, 0, 0); + const std::string signatureText(GooString::format(_("Digitally signed by {0:s}"), signerName.c_str())->toStr() + "\n" + GooString::format(_("Date: {0:s}"), timestamp.c_str())->toStr()); + const auto gSignatureText = std::make_unique<GooString>((signatureText.empty() || noAppearance) ? "" : utf8ToUtf16WithBom(signatureText)); + const auto gSignatureLeftText = std::make_unique<GooString>((signerName.empty() || noAppearance) ? "" : utf8ToUtf16WithBom(signerName)); + const bool success = fws->signDocumentWithAppearance(argv[2], std::string { certNickname }, std::string { password }, rs.get(), nullptr, {}, {}, *gSignatureText, *gSignatureLeftText, 0, 0, std::make_unique<AnnotColor>(blackColor)); return success ? 0 : 3; } diff --git a/utils/po/CMakeLists.txt b/utils/po/CMakeLists.txt new file mode 100644 index 00000000..d9fca3c5 --- /dev/null +++ b/utils/po/CMakeLists.txt @@ -0,0 +1,26 @@ +file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/*") +foreach (_dir ${_files}) + if (IS_DIRECTORY "${_dir}") + add_subdirectory("${_dir}") + get_filename_component(_lang ${_dir} NAME) + list(APPEND _langs ${_lang}) + endif () +endforeach() + + +macro(UPDATE_POT_FILE input) + set(_potFile "${input}.pot") + foreach(_lang ${_langs}) + set(_poFile "${CMAKE_CURRENT_SOURCE_DIR}/${_lang}/${input}.po") + list(APPEND _commands + COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_poFile} "${CMAKE_CURRENT_SOURCE_DIR}/${_potFile}") + endforeach() + add_custom_target(update_pot_${input} + ALL + COMMAND xgettext --keyword=_ --language=c++ --package-name=pdfsig --output-dir=po --output=${_potFile} ${input}.cc + ${_commands} + DEPENDS ../${input}.cc + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/..) +endmacro() + +UPDATE_POT_FILE(pdfsig) diff --git a/utils/po/pdfsig.pot b/utils/po/pdfsig.pot new file mode 100644 index 00000000..83095113 --- /dev/null +++ b/utils/po/pdfsig.pot @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the pdfsig package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: pdfsig\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-12 14:44-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: pdfsig.cc:544 +msgid "Digitally signed by {0:s}" +msgstr "" + +#: pdfsig.cc:544 +msgid "Date: {0:s}" +msgstr "" |