--- qt5/src/poppler-form.h 2016-11-28 22:09:14.668220924 +0100 +++ qt5/src/poppler-form.h 2016-11-29 20:32:51.026645438 +0100 @@ -30,6 +30,7 @@ class FormWidgetButton; class FormWidgetText; class FormWidgetChoice; +class FormWidgetSignature; namespace Poppler { @@ -338,6 +339,90 @@ Q_DISABLE_COPY(FormFieldChoice) }; + /** + A form field that represents a signature. + + \since xy.z + */ + class POPPLER_QT5_EXPORT FormFieldSignature : public FormField { + public: + + /** + The verfication result of this signature field. + */ + enum SignatureStatus { + SignatureValid, ///< The signature is cryptographically valid. + SignatureInvalid, ///< The signature is cryptographically invalid. + SignatureDigestMismatch, ///< The document content was changed after the signature was applied. + SignatureDecodingError, ///< The signature CMS/PKCS7 structure is malformed. + SignatureGenericError, ///< The signature could not be verified. + SignatureNotFound, ///< The requested signature is not present in the document. + SignatureNotVerified ///< The signature is not yet verified. + }; + + /** + The verification result of this signature field's certificate. + */ + enum CertificateStatus { + CertificateTrusted, ///< The certificate is considered trusted. + CertificateUntrustedIssuer, ///< The issuer of this certificate has been marked as untrusted by the user. + CertificateUnknownIssuer, ///< The certificate trust chain has not finished in a trusted root certificate. + CertificateRevoked, ///< The certificate was revoked by the issuing certificate authority. + CertificateExpired, ///< The signing time is outside the validity bounds of this certificate. + CertificateGenericError, ///< The certificate could not be verified. + CertificateNotVerified ///< The certificate is not yet verified. + }; + + /** + The validation options of this signature field. + */ + enum ValidateOptions { + ValidateVerifyCertificate = 1, ///< Validate the certificate. + ValidateForceRevalidation = 2, ///< Force revalidation of the certificate. + }; + + /// \cond PRIVATE + FormFieldSignature(DocumentData *doc, ::Page *p, ::FormWidgetSignature *w); + /// \endcond + virtual ~FormFieldSignature(); + + virtual FormType type() const; + + /** + Validate the signature. + */ + void validate(ValidateOptions opt); + + /** + The signature status of the signature field. + */ + SignatureStatus signatureStatus() const; + + /** + The certificate status of the signature field. + */ + CertificateStatus certificateStatus() const; + + /** + The signer name associated with the signature field. + */ + QString signerName() const; + + /** + The signing time associated with the signature field. + */ + time_t signingTime() const; + + private: + Q_DISABLE_COPY(FormFieldSignature) + + SignatureStatus signature_status; + CertificateStatus certificate_status; + + QString signer_name; + time_t signing_time; + }; + } #endif --- qt5/src/poppler-form.cc 2016-11-28 22:09:26.800221289 +0100 +++ qt5/src/poppler-form.cc 2016-11-29 21:28:05.982745135 +0100 @@ -26,6 +26,7 @@ #include #include #include +#include #include "poppler-form.h" #include "poppler-page-private.h" @@ -414,4 +415,96 @@ return !fwc->noSpellCheck(); } + +FormFieldSignature::FormFieldSignature(DocumentData *doc, ::Page *p, ::FormWidgetSignature *w) + : FormField(*new FormFieldData(doc, p, w)) +{ +} + +FormFieldSignature::~FormFieldSignature() +{ +} + +void FormFieldSignature::validate(ValidateOptions opt) +{ + FormWidgetSignature* fws = static_cast(m_formData->fm); + SignatureInfo* si = fws->validateSignature(opt & ValidateVerifyCertificate, + opt & ValidateForceRevalidation); + switch (si->getSignatureValStatus()) { + case SIGNATURE_VALID: + signature_status = SignatureValid; + break; + case SIGNATURE_INVALID: + signature_status = SignatureInvalid; + break; + case SIGNATURE_DIGEST_MISMATCH: + signature_status = SignatureDigestMismatch; + break; + case SIGNATURE_DECODING_ERROR: + signature_status = SignatureDecodingError; + break; + default: + case SIGNATURE_GENERIC_ERROR: + signature_status = SignatureGenericError; + break; + case SIGNATURE_NOT_FOUND: + signature_status = SignatureNotFound; + break; + case SIGNATURE_NOT_VERIFIED: + signature_status = SignatureNotVerified; + break; + } + switch (si->getCertificateValStatus()) { + case CERTIFICATE_TRUSTED: + certificate_status = CertificateTrusted; + break; + case CERTIFICATE_UNTRUSTED_ISSUER: + certificate_status = CertificateUntrustedIssuer; + break; + case CERTIFICATE_UNKNOWN_ISSUER: + certificate_status = CertificateUnknownIssuer; + break; + case CERTIFICATE_REVOKED: + certificate_status = CertificateRevoked; + break; + case CERTIFICATE_EXPIRED: + certificate_status = CertificateExpired; + break; + default: + case CERTIFICATE_GENERIC_ERROR: + certificate_status = CertificateGenericError; + break; + case CERTIFICATE_NOT_VERIFIED: + certificate_status = CertificateNotVerified; + break; + } + signer_name = si->getSignerName(); + signing_time = si->getSigningTime(); +} + +FormField::FormType FormFieldSignature::type() const +{ + return FormField::FormSignature; +} + +FormFieldSignature::SignatureStatus FormFieldSignature::signatureStatus() const +{ + return signature_status; +} + +FormFieldSignature::CertificateStatus FormFieldSignature::certificateStatus() const +{ + return certificate_status; +} + +QString FormFieldSignature::signerName() const +{ + return signer_name; +} + +time_t FormFieldSignature::signingTime() const +{ + return signing_time; +} + } --- qt5/src/poppler-page.cc 2016-11-29 22:18:43.118836476 +0100 +++ qt5/src/poppler-page.cc 2016-11-29 22:19:28.574837843 +0100 @@ -767,6 +767,12 @@ } break; + case formSignature: + { + ff = new FormFieldSignature(m_page->parentDoc, p, static_cast(fm)); + } + break; + default: ; } --- qt5/tests/poppler-forms.cpp 2016-11-29 21:02:15.806698513 +0100 +++ qt5/tests/poppler-forms.cpp 2016-11-29 21:21:41.526733572 +0100 @@ -46,6 +46,34 @@ return out; } +std::ostream& operator<< (std::ostream &out, Poppler::FormFieldSignature::SignatureStatus status) +{ + switch (status) { + case Poppler::FormFieldSignature::SignatureValid: out << "Valid"; break; + case Poppler::FormFieldSignature::SignatureInvalid: out << "Invalid"; break; + case Poppler::FormFieldSignature::SignatureDigestMismatch: out << "DigestMismatch"; break; + case Poppler::FormFieldSignature::SignatureDecodingError: out << "DecodingError"; break; + case Poppler::FormFieldSignature::SignatureGenericError: out << "GenericError"; break; + case Poppler::FormFieldSignature::SignatureNotFound: out << "NotFound"; break; + case Poppler::FormFieldSignature::SignatureNotVerified: out << "NotVerifiedYet"; break; + } + return out; +} + +std::ostream& operator<< (std::ostream &out, Poppler::FormFieldSignature::CertificateStatus status) +{ + switch (status) { + case Poppler::FormFieldSignature::CertificateTrusted: out << "Trusted"; break; + case Poppler::FormFieldSignature::CertificateUntrustedIssuer: out << "UntrustedIssuer"; break; + case Poppler::FormFieldSignature::CertificateUnknownIssuer: out << "UnknownIssuer"; break; + case Poppler::FormFieldSignature::CertificateRevoked: out << "Revoked"; break; + case Poppler::FormFieldSignature::CertificateExpired: out << "Expired"; break; + case Poppler::FormFieldSignature::CertificateGenericError: out << "GenericError"; break; + case Poppler::FormFieldSignature::CertificateNotVerified: out << "NotVerifiedYet"; break; + } + return out; +} + std::ostream& operator<< (std::ostream &out, Qt::Alignment alignment) { switch (alignment) { @@ -110,7 +138,7 @@ if (page) { QList forms = page->formFields(); std::cout << "\tPage " << i + 1 << std::endl; - foreach( const Poppler::FormField *form, forms ) { + foreach( Poppler::FormField *form, forms ) { std::cout << "\t\tForm" << std::endl; std::cout << "\t\t\tType: " << form->type() << std::endl; std::cout << "\t\t\tRect: " << form->rect() << std::endl; @@ -155,7 +183,14 @@ } break; - case Poppler::FormField::FormSignature: + case Poppler::FormField::FormSignature: { + Poppler::FormFieldSignature *signatureForm = static_cast(form); + signatureForm->validate(Poppler::FormFieldSignature::ValidateVerifyCertificate); + std::cout << "\t\t\tSignatureStatus: " << signatureForm->signatureStatus() << std::endl; + std::cout << "\t\t\tCertificateStatus: " << signatureForm->certificateStatus() << std::endl; + std::cout << "\t\t\tSignerName: " << signatureForm->signerName() << std::endl; + std::cout << "\t\t\tSigningTime: " << signatureForm->signingTime() << std::endl; + } break; } }