mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Verification tool - output text
This commit is contained in:
@@ -74,9 +74,13 @@ public:
|
||||
inline void beginTableHeaderRow(QString name) { beginElement(Element::TableHeaderRow, name); }
|
||||
inline void endTableHeaderRow() { endElement(); }
|
||||
inline void beginTableRow(QString name) { beginElement(Element::TableRow, name); }
|
||||
inline void beginTableRow(QString name, int reference) { beginElement(Element::TableRow, name, QString(), Qt::AlignLeft, reference); }
|
||||
inline void endTableRow() { endElement(); }
|
||||
inline void writeTableHeaderColumn(QString name, QString description, Qt::Alignment alignment = Qt::AlignCenter) { beginElement(Element::TableHeaderColumn, name, description, alignment); endElement(); }
|
||||
inline void writeTableColumn(QString name, QString description, Qt::Alignment alignment = Qt::AlignLeft) { beginElement(Element::TableColumn, name, description, alignment); endElement(); }
|
||||
inline void writeText(QString name, QString description) { beginElement(Element::Text, name, description); endElement(); }
|
||||
inline void beginHeader(QString name, QString description, int reference = 0) { beginElement(Element::Header, name, description, Qt::AlignLeft, reference); }
|
||||
inline void endHeader() { endElement(); }
|
||||
|
||||
/// Ends current line
|
||||
void endl();
|
||||
|
@@ -143,8 +143,9 @@ void PDFToolAbstractApplication::initializeCommandLineParser(QCommandLineParser*
|
||||
parser->addOption(QCommandLineOption("ver-no-user-cert", "Disable user certificate store."));
|
||||
parser->addOption(QCommandLineOption("ver-no-sys-cert", "Disable system certificate store."));
|
||||
parser->addOption(QCommandLineOption("ver-no-cert-check", "Disable certificate validation."));
|
||||
parser->addOption(QCommandLineOption("ver-cert-details", "Print certificate details (including chain, if found)."));
|
||||
parser->addOption(QCommandLineOption("ver-details", "Print details (including certificate chain, if found)."));
|
||||
parser->addOption(QCommandLineOption("ver-ignore-exp-date", "Ignore certificate expiration date."));
|
||||
parser->addOption(QCommandLineOption("ver-date-format", "Console output date/time format (valid values: short|long|iso|rfc2822).", "ver-date-format", "short"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +185,7 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
|
||||
if (optionFlags.testFlag(OpenDocument))
|
||||
{
|
||||
options.document = positionalArguments.isEmpty() ? QString() : positionalArguments.front();
|
||||
options.password = parser->value("password");
|
||||
options.password = parser->isSet("pswd") ? parser->value("password") : QString();
|
||||
options.permissiveReading = !parser->isSet("no-permissive-reading");
|
||||
}
|
||||
|
||||
@@ -193,8 +194,30 @@ PDFToolOptions PDFToolAbstractApplication::getOptions(QCommandLineParser* parser
|
||||
options.verificationUseUserCertificates = !parser->isSet("ver-no-user-cert");
|
||||
options.verificationUseSystemCertificates = !parser->isSet("ver-no-sys-cert");
|
||||
options.verificationOmitCertificateCheck = parser->isSet("ver-no-cert-check");
|
||||
options.verificationPrintCertificateDetails = parser->isSet("ver-cert-details");
|
||||
options.verificationPrintCertificateDetails = parser->isSet("ver-details");
|
||||
options.verificationIgnoreExpirationDate = parser->isSet("ver-ignore-exp-date");
|
||||
|
||||
QString dateFormat = parser->value("ver-date-format");
|
||||
if (dateFormat == "short")
|
||||
{
|
||||
options.verificationDateFormat = Qt::DefaultLocaleShortDate;
|
||||
}
|
||||
else if (dateFormat == "long")
|
||||
{
|
||||
options.verificationDateFormat = Qt::DefaultLocaleLongDate;
|
||||
}
|
||||
else if (dateFormat == "iso")
|
||||
{
|
||||
options.verificationDateFormat = Qt::ISODate;
|
||||
}
|
||||
else if (dateFormat == "rfc2822")
|
||||
{
|
||||
options.verificationDateFormat = Qt::RFC2822Date;
|
||||
}
|
||||
else if (!dateFormat.isEmpty())
|
||||
{
|
||||
PDFConsole::writeError(PDFToolTranslationContext::tr("Unknown console date/time format '%1'. Defaulting to short date/time format.").arg(dateFormat));
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <vector>
|
||||
@@ -52,6 +53,7 @@ struct PDFToolOptions
|
||||
bool verificationOmitCertificateCheck = false;
|
||||
bool verificationPrintCertificateDetails = false;
|
||||
bool verificationIgnoreExpirationDate = false;
|
||||
Qt::DateFormat verificationDateFormat = Qt::DefaultLocaleShortDate;
|
||||
};
|
||||
|
||||
/// Base class for all applications
|
||||
|
@@ -107,6 +107,115 @@ int PDFToolVerifySignaturesApplication::execute(const PDFToolOptions& options)
|
||||
pdf::PDFForm form = pdf::PDFForm::parse(&document, document.getCatalog()->getFormObject());
|
||||
std::vector<pdf::PDFSignatureVerificationResult> signatures = pdf::PDFSignatureHandler::verifySignatures(form, reader.getSource(), parameters);
|
||||
|
||||
PDFOutputFormatter formatter(options.outputStyle);
|
||||
formatter.beginDocument("signatures", PDFToolTranslationContext::tr("Digital signatures/timestamps verification of %1").arg(options.document));
|
||||
formatter.endl();
|
||||
|
||||
auto getTypeName = [](const pdf::PDFSignatureVerificationResult& signature)
|
||||
{
|
||||
switch (signature.getType())
|
||||
{
|
||||
case pdf::PDFSignature::Type::Invalid:
|
||||
return PDFToolTranslationContext::tr("Invalid");
|
||||
|
||||
case pdf::PDFSignature::Type::Sig:
|
||||
return PDFToolTranslationContext::tr("Signature");
|
||||
|
||||
case pdf::PDFSignature::Type::DocTimeStamp:
|
||||
return PDFToolTranslationContext::tr("Timestamp");
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return QString();
|
||||
};
|
||||
|
||||
if (!signatures.empty())
|
||||
{
|
||||
formatter.beginTable("overview", PDFToolTranslationContext::tr("Overview"));
|
||||
|
||||
formatter.beginTableHeaderRow("header");
|
||||
formatter.writeTableHeaderColumn("no", PDFToolTranslationContext::tr("No."), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("type", PDFToolTranslationContext::tr("Type"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("common-name", PDFToolTranslationContext::tr("Signed by"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("cert-status", PDFToolTranslationContext::tr("Certificate"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("signature-status", PDFToolTranslationContext::tr("Signature"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("signing-date", PDFToolTranslationContext::tr("Signing date"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("timestamp-date", PDFToolTranslationContext::tr("Timestamp date"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("hash-algorithm", PDFToolTranslationContext::tr("Hash alg."), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("handler", PDFToolTranslationContext::tr("Handler"), Qt::AlignLeft);
|
||||
formatter.writeTableHeaderColumn("whole-signed", PDFToolTranslationContext::tr("Signed whole"), Qt::AlignLeft);
|
||||
formatter.endTableHeaderRow();
|
||||
|
||||
int i = 1;
|
||||
for (const pdf::PDFSignatureVerificationResult& signature : signatures)
|
||||
{
|
||||
const pdf::PDFCertificateInfos& certificateInfos = signature.getCertificateInfos();
|
||||
const pdf::PDFCertificateInfo* certificateInfo = !certificateInfos.empty() ? &certificateInfos.front() : nullptr;
|
||||
|
||||
formatter.beginTableRow("signature", i);
|
||||
|
||||
formatter.writeTableColumn("no", QString::number(i), Qt::AlignRight);
|
||||
formatter.writeTableColumn("type", getTypeName(signature));
|
||||
|
||||
QString commonName = certificateInfo ? certificateInfo->getName(pdf::PDFCertificateInfo::CommonName) : PDFToolTranslationContext::tr("Unknown");
|
||||
formatter.writeTableColumn("common-name", commonName);
|
||||
formatter.writeTableColumn("cert-status", options.verificationOmitCertificateCheck ? PDFToolTranslationContext::tr("Skipped") : signature.getCertificateStatusText());
|
||||
formatter.writeTableColumn("signature-status", signature.getSignatureStatusText());
|
||||
formatter.writeTableColumn("signing-date", signature.getSignatureDate().isValid() ? signature.getSignatureDate().toLocalTime().toString(options.verificationDateFormat) : QString());
|
||||
formatter.writeTableColumn("timestamp-date", signature.getTimestampDate().isValid() ? signature.getTimestampDate().toLocalTime().toString(options.verificationDateFormat) : QString());
|
||||
formatter.writeTableColumn("hash-algorithm", signature.getHashAlgorithms().join(", ").toUpper());
|
||||
formatter.writeTableColumn("handler", QString::fromLatin1(signature.getSignatureHandler()));
|
||||
formatter.writeTableColumn("whole-signed", signature.hasFlag(pdf::PDFSignatureVerificationResult::Warning_Signature_NotCoveredBytes) ? PDFToolTranslationContext::tr("No") : PDFToolTranslationContext::tr("Yes"));
|
||||
|
||||
formatter.endTableRow();
|
||||
++i;
|
||||
}
|
||||
|
||||
formatter.endTable();
|
||||
|
||||
|
||||
if (options.verificationPrintCertificateDetails)
|
||||
{
|
||||
formatter.endl();
|
||||
formatter.beginHeader("details", PDFToolTranslationContext::tr("Details"));
|
||||
|
||||
int i = 1;
|
||||
for (const pdf::PDFSignatureVerificationResult& signature : signatures)
|
||||
{
|
||||
formatter.endl();
|
||||
formatter.beginHeader("signature", PDFToolTranslationContext::tr("%1 #%2").arg(getTypeName(signature)).arg(i), i);
|
||||
|
||||
const pdf::PDFCertificateInfos& certificateInfos = signature.getCertificateInfos();
|
||||
const pdf::PDFCertificateInfo* certificateInfo = !certificateInfos.empty() ? &certificateInfos.front() : nullptr;
|
||||
QString commonName = certificateInfo ? certificateInfo->getName(pdf::PDFCertificateInfo::CommonName) : PDFToolTranslationContext::tr("Unknown");
|
||||
formatter.writeText("common-name", PDFToolTranslationContext::tr("Signed by: %1").arg(commonName));
|
||||
formatter.writeText("certificate-status", PDFToolTranslationContext::tr("Certificate status: %1").arg(options.verificationOmitCertificateCheck ? PDFToolTranslationContext::tr("Skipped") : signature.getCertificateStatusText()));
|
||||
formatter.writeText("signature-status", PDFToolTranslationContext::tr("Signature status: %1").arg(signature.getSignatureStatusText()));
|
||||
formatter.writeText("signing-date", PDFToolTranslationContext::tr("Signing date: %1").arg(signature.getSignatureDate().isValid() ? signature.getSignatureDate().toLocalTime().toString(options.verificationDateFormat) : QString()));
|
||||
formatter.writeText("timestamp-date", PDFToolTranslationContext::tr("Timestamp date: %1").arg(signature.getTimestampDate().isValid() ? signature.getTimestampDate().toLocalTime().toString(options.verificationDateFormat) : QString()));
|
||||
formatter.writeText("hash-algorithm", PDFToolTranslationContext::tr("Hash algorithm: %1").arg(signature.getHashAlgorithms().join(", ").toUpper()));
|
||||
formatter.writeText("handler", PDFToolTranslationContext::tr("Handler: %1").arg(QString::fromLatin1(signature.getSignatureHandler())));
|
||||
formatter.writeText("whole-signed", PDFToolTranslationContext::tr("Is whole document signed: %1").arg(signature.hasFlag(pdf::PDFSignatureVerificationResult::Warning_Signature_NotCoveredBytes) ? PDFToolTranslationContext::tr("No") : PDFToolTranslationContext::tr("Yes")));
|
||||
|
||||
formatter.endHeader();
|
||||
++i;
|
||||
}
|
||||
|
||||
formatter.endHeader();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.writeText("no-signatures", PDFToolTranslationContext::tr("No digital signatures or timestamps found in the document."));
|
||||
}
|
||||
|
||||
formatter.endDocument();
|
||||
|
||||
PDFConsole::writeText(formatter.getString());
|
||||
return ExitSuccess;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user