[poppler] poppler/Form.cc poppler/Form.h poppler/SignatureHandler.cc poppler/SignatureHandler.h qt5/src qt6/src utils/pdfsig.1 utils/pdfsig.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Sep 27 10:07:07 UTC 2021


 poppler/Form.cc             |    8 ++++----
 poppler/Form.h              |    4 ++--
 poppler/SignatureHandler.cc |   12 +++++++++---
 poppler/SignatureHandler.h  |    2 +-
 qt5/src/poppler-form.cc     |    2 +-
 qt5/src/poppler-form.h      |    3 ++-
 qt6/src/poppler-form.cc     |    2 +-
 qt6/src/poppler-form.h      |    3 ++-
 utils/pdfsig.1              |    3 +++
 utils/pdfsig.cc             |    4 +++-
 10 files changed, 28 insertions(+), 15 deletions(-)

New commits:
commit e5516f8c1827862a7e650dd850b0e919a2d6c51e
Author: Theofilos Intzoglou <int.teo at gmail.com>
Date:   Mon Sep 27 10:07:05 2021 +0000

    Add support for AIA fetching to verify certificates

diff --git a/poppler/Form.cc b/poppler/Form.cc
index 2e1bbc98..354c9f8e 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -538,9 +538,9 @@ const GooString *FormWidgetSignature::getSignature() const
     return static_cast<FormFieldSignature *>(field)->getSignature();
 }
 
-SignatureInfo *FormWidgetSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck)
+SignatureInfo *FormWidgetSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA)
 {
-    return static_cast<FormFieldSignature *>(field)->validateSignature(doVerifyCert, forceRevalidation, validationTime, ocspRevocationCheck);
+    return static_cast<FormFieldSignature *>(field)->validateSignature(doVerifyCert, forceRevalidation, validationTime, ocspRevocationCheck, enableAIA);
 }
 
 #ifdef ENABLE_NSS3
@@ -2141,7 +2141,7 @@ void FormWidgetSignature::setSignatureType(FormSignatureType fst)
     static_cast<FormFieldSignature *>(field)->setSignatureType(fst);
 }
 
-SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck)
+SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA)
 {
 #ifdef ENABLE_NSS3
     if (signature_info->getSignatureValStatus() != SIGNATURE_NOT_VERIFIED && !forceRevalidation) {
@@ -2212,7 +2212,7 @@ SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool for
         return signature_info;
     }
 
-    const CertificateValidationStatus cert_val_state = signature_handler.validateCertificate(validationTime, ocspRevocationCheck);
+    const CertificateValidationStatus cert_val_state = signature_handler.validateCertificate(validationTime, ocspRevocationCheck, enableAIA);
     signature_info->setCertificateValStatus(cert_val_state);
     signature_info->setCertificateInfo(signature_handler.getCertificateInfo());
 
diff --git a/poppler/Form.h b/poppler/Form.h
index 572b035f..6489b0dd 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -296,7 +296,7 @@ public:
     void setSignatureType(FormSignatureType fst);
 
     // Use -1 for now as validationTime
-    SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck);
+    SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA);
 
     // returns a list with the boundaries of the signed ranges
     // the elements of the list are of type Goffset
@@ -596,7 +596,7 @@ public:
     FormFieldSignature(PDFDoc *docA, Object &&dict, const Ref ref, FormField *parent, std::set<int> *usedParents);
 
     // Use -1 for now as validationTime
-    SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck);
+    SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime, bool ocspRevocationCheck, bool enableAIA);
 
     // returns a list with the boundaries of the signed ranges
     // the elements of the list are of type Goffset
diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index f4a3bbc5..f3af96ce 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -944,7 +944,7 @@ SignatureValidationStatus SignatureHandler::validateSignature()
     }
 }
 
-CertificateValidationStatus SignatureHandler::validateCertificate(time_t validation_time, bool ocspRevocationCheck)
+CertificateValidationStatus SignatureHandler::validateCertificate(time_t validation_time, bool ocspRevocationCheck, bool useAIACertFetch)
 {
     CERTCertificate *cert;
 
@@ -957,7 +957,7 @@ CertificateValidationStatus SignatureHandler::validateCertificate(time_t validat
     PRTime vTime = 0; // time in microseconds since the epoch, special value 0 means now
     if (validation_time > 0)
         vTime = 1000000 * (PRTime)validation_time;
-    CERTValInParam inParams[3];
+    CERTValInParam inParams[4];
     inParams[0].type = cert_pi_revocationFlags;
     if (ocspRevocationCheck) {
         inParams[0].value.pointer.revocation = CERT_GetClassicOCSPEnabledSoftFailurePolicy();
@@ -966,7 +966,13 @@ CertificateValidationStatus SignatureHandler::validateCertificate(time_t validat
     }
     inParams[1].type = cert_pi_date;
     inParams[1].value.scalar.time = vTime;
-    inParams[2].type = cert_pi_end;
+    if (useAIACertFetch) {
+        inParams[2].type = cert_pi_useAIACertFetch;
+        inParams[2].value.scalar.b = PR_TRUE;
+        inParams[3].type = cert_pi_end;
+    } else {
+        inParams[2].type = cert_pi_end;
+    }
 
     CERT_PKIXVerifyCert(cert, certificateUsageEmailSigner, inParams, nullptr, CMSSignerInfo->cmsg->pwfn_arg);
 
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index 32277898..c18a897f 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -55,7 +55,7 @@ public:
     void restartHash();
     SignatureValidationStatus validateSignature();
     // Use -1 as validation_time for now
-    CertificateValidationStatus validateCertificate(time_t validation_time, bool ocspRevocationCheck);
+    CertificateValidationStatus validateCertificate(time_t validation_time, bool ocspRevocationCheck, bool useAIACertFetch);
     std::unique_ptr<X509CertificateInfo> getCertificateInfo() const;
     static std::vector<std::unique_ptr<X509CertificateInfo>> getAvailableSigningCertificates();
     std::unique_ptr<GooString> signDetached(const char *password) const;
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index b07f97e2..1d2ef539 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -980,7 +980,7 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime &v
 {
     FormWidgetSignature *fws = static_cast<FormWidgetSignature *>(m_formData->fm);
     const time_t validationTimeT = validationTime.isValid() ? validationTime.toSecsSinceEpoch() : -1;
-    SignatureInfo *si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT, !(opt & ValidateWithoutOCSPRevocationCheck));
+    SignatureInfo *si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT, !(opt & ValidateWithoutOCSPRevocationCheck), opt & ValidateUseAIACertFetch);
 
     // get certificate info
     const X509CertificateInfo *ci = si->getCertificateInfo();
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index dce89632..a07f689c 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -787,7 +787,8 @@ public:
     {
         ValidateVerifyCertificate = 1, ///< Validate the certificate.
         ValidateForceRevalidation = 2, ///< Force revalidation of the certificate.
-        ValidateWithoutOCSPRevocationCheck = 4 ///< Do not contact OCSP servers to check for certificate revocation status \since 21.10
+        ValidateWithoutOCSPRevocationCheck = 4, ///< Do not contact OCSP servers to check for certificate revocation status \since 21.10
+        ValidateUseAIACertFetch = 8 ///< Use the AIA extension for certificate fetching \since 21.10
     };
 
     /// \cond PRIVATE
diff --git a/qt6/src/poppler-form.cc b/qt6/src/poppler-form.cc
index cc947055..eb651528 100644
--- a/qt6/src/poppler-form.cc
+++ b/qt6/src/poppler-form.cc
@@ -980,7 +980,7 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime &v
 {
     FormWidgetSignature *fws = static_cast<FormWidgetSignature *>(m_formData->fm);
     const time_t validationTimeT = validationTime.isValid() ? validationTime.toSecsSinceEpoch() : -1;
-    SignatureInfo *si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT, !(opt & ValidateWithoutOCSPRevocationCheck));
+    SignatureInfo *si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT, !(opt & ValidateWithoutOCSPRevocationCheck), opt & ValidateUseAIACertFetch);
 
     // get certificate info
     const X509CertificateInfo *ci = si->getCertificateInfo();
diff --git a/qt6/src/poppler-form.h b/qt6/src/poppler-form.h
index 94b75c9d..441c31e9 100644
--- a/qt6/src/poppler-form.h
+++ b/qt6/src/poppler-form.h
@@ -739,7 +739,8 @@ public:
     {
         ValidateVerifyCertificate = 1, ///< Validate the certificate.
         ValidateForceRevalidation = 2, ///< Force revalidation of the certificate.
-        ValidateWithoutOCSPRevocationCheck = 4 ///< Do not contact OCSP servers to check for certificate revocation status \since 21.10
+        ValidateWithoutOCSPRevocationCheck = 4, ///< Do not contact OCSP servers to check for certificate revocation status \since 21.10
+        ValidateUseAIACertFetch = 8 ///< Use the AIA extension for certificate fetching \since 21.10
     };
 
     /// \cond PRIVATE
diff --git a/utils/pdfsig.1 b/utils/pdfsig.1
index 09b6be52..7e262009 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 \-aia
+Enable the use of Authority Information Access (AIA) extension to fetch missing certificates to build the certificate chain.
+.TP
 .B \-dump
 Dump all signatures into current directory.
 .TP
diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc
index 3849387c..d59c5ff0 100644
--- a/utils/pdfsig.cc
+++ b/utils/pdfsig.cc
@@ -139,12 +139,14 @@ static char digestName[256] = "SHA256";
 static GooString reason;
 static bool listNicknames = false;
 static bool addNewSignature = false;
+static bool useAIACertFetch = false;
 static GooString newSignatureFieldName;
 
 static const ArgDesc argDesc[] = { { "-nssdir", argGooString, &nssDir, 0, "path to directory of libnss3 database" },
                                    { "-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" },
+                                   { "-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" },
                                    { "-new-signature-field-name", argGooString, &newSignatureFieldName, 0, "field name used for the newly added signature. A random ID will be used if empty" },
@@ -397,7 +399,7 @@ int main(int argc, char *argv[])
     }
 
     for (unsigned int i = 0; i < sigCount; i++) {
-        const SignatureInfo *sig_info = signatures.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */, !noOCSPRevocationCheck);
+        const SignatureInfo *sig_info = signatures.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */, !noOCSPRevocationCheck, useAIACertFetch);
         printf("Signature #%u:\n", i + 1);
         printf("  - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
         printf("  - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());


More information about the poppler mailing list