Commit ad7a5283 authored by Erich Hoover's avatar Erich Hoover
Browse files

pdfsig: Sign form signature fields with an appearance

parent 91159355
Pipeline #722092 passed with stages
in 4 minutes and 52 seconds
include(FindGettext)
set(common_srcs
parseargs.cc
......@@ -92,6 +93,17 @@ 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_NSS3)
add_definitions(-DHAVE_GETTEXT)
add_definitions(-DCMAKE_INSTALL_LOCALEDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}")
file(GLOB _dirs "${CMAKE_CURRENT_SOURCE_DIR}/po/*")
foreach (_dir ${_dirs})
if (IS_DIRECTORY "${_dir}")
add_subdirectory("${_dir}")
endif ()
endforeach()
endif ()
if (ENABLE_NSS3)
# pdfsig
set(pdfsig_SOURCES ${common_srcs}
......
......@@ -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
......
......@@ -38,6 +38,7 @@
#include "Page.h"
#include "PDFDoc.h"
#include "PDFDocFactory.h"
#include "DateInfo.h"
#include "Error.h"
#include "GlobalParams.h"
#include "SignatureHandler.h"
......@@ -49,6 +50,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) {
......@@ -135,6 +144,7 @@ static bool printVersion = false;
static bool printHelp = false;
static bool dontVerifyCert = false;
static bool noOCSPRevocationCheck = false;
static bool noAppearance = false;
static bool dumpSignatures = false;
static bool etsiCAdESdetached = false;
static char signatureName[256] = "";
......@@ -151,6 +161,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" },
......@@ -236,6 +247,30 @@ static std::string TextStringToUTF8(const std::string &str)
return convertedStr;
}
static __attribute__((format(printf, 1, 2))) std::string FmtStr(const char *fmt, ...)
{
va_list ap;
int size;
if (noAppearance) {
return "";
}
va_start(ap, fmt);
size = std::vsnprintf(nullptr, 0, fmt, ap);
va_end(ap);
if (size < 0) {
return "";
}
std::vector<char> buffer(size + 1);
va_start(ap, fmt);
std::vsnprintf(&buffer[0], buffer.size(), fmt, ap);
va_end(ap);
return std::string(buffer.begin(), buffer.end() - 1);
}
int main(int argc, char *argv[])
{
char *time_str = nullptr;
......@@ -439,8 +474,22 @@ 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(argv[2], certNickname, digestName, pw, rs.get());
SignatureHandler sigHandler(certNickname, SEC_OID_SHA256);
const std::string timestamp = timeToStringWithFormat(nullptr, "%Y.%m.%d %H:%M:%S ");
const std::string signerName = sigHandler.getSignerName();
const AnnotColor blackColor(0, 0, 0);
const std::string signatureText(FmtStr(_("Digitally signed by %s"), signerName.c_str()) + "\n" + FmtStr(_("Date: %s"), timestamp.c_str()));
const auto gSignatureText = (signatureText.empty() || noAppearance) ? std::make_unique<GooString>("") : utf8ToUtf16WithBom(signatureText);
const auto gSignatureLeftText = (signerName.empty() || noAppearance) ? std::make_unique<GooString>("") : utf8ToUtf16WithBom(signerName);
const bool success = fws->signDocumentWithAppearance(argv[2], certNickname, digestName, pw, rs.get(), nullptr, {}, {}, *gSignatureText, *gSignatureLeftText, 0, 0, std::make_unique<AnnotColor>(blackColor));
return success ? 0 : 3;
}
......
get_filename_component(_lang ${CMAKE_CURRENT_SOURCE_DIR} NAME)
gettext_process_po_files(${_lang} ALL INSTALL_DESTINATION ${CMAKE_INSTALL_LOCALEDIR} PO_FILES
pdfsig.po
)
# English translations for pdfsig package.
# Copyright (C) 2022 Erich E. Hoover
# This file is distributed under the same license as the pdfsig package.
# Erich E. Hoover <erich.e.hoover@gmail.com>, 2022.
#
msgid ""
msgstr ""
"Project-Id-Version: pdfsig VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-25 13:46-0600\n"
"PO-Revision-Date: 2022-10-25 13:56-0600\n"
"Last-Translator: Erich Hoover <erich.e.hoover@gmail.com>\n"
"Language-Team: English\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: utils/pdfsig.cc:481
#, c-format
msgid "Date: %s"
msgstr "Date: %s"
#: utils/pdfsig.cc:480
#, c-format
msgid "Digitally signed by %s"
msgstr "Digitally signed by %s"
# Translations for pdfsig PDF signing tool.
# Copyright (C) 2022 Erich E. Hoover
# This file is distributed under the same license as the pdfsig package.
# Erich E. Hoover <erich.e.hoover@gmail.com>, 2022.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: pdfsig VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-25 13:46-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Erich E. Hoover <erich.e.hoover@gmail.com>\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"
#: utils/pdfsig.cc:481
#, c-format
msgid "Date: %s"
msgstr ""
#: utils/pdfsig.cc:480
#, c-format
msgid "Digitally signed by %s"
msgstr ""
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment