mirror of
https://invent.kde.org/graphics/okular
synced 2024-06-30 22:54:24 +00:00
Use async signature validation
Also, show information about the validity of the certificate used for the signature BUG: 446298
This commit is contained in:
parent
e5900f9a4f
commit
0bd2c9cfa0
26
core/form.h
26
core/form.h
|
@ -485,6 +485,32 @@ public:
|
|||
*/
|
||||
virtual bool sign(const NewSignatureData &data, const QString &newPath) const = 0;
|
||||
|
||||
using SubscriptionHandle = uint64_t;
|
||||
/**
|
||||
* Subscribes to updates to signatureInfo
|
||||
*
|
||||
* Especially certificate validation can be a slow task and the
|
||||
* underlying infrastructure might offload it to a background job.
|
||||
*
|
||||
* Whenever those background jobs finished, the callback(s) will be invoked
|
||||
*
|
||||
* @return handle to be able to be put back into \ref unsubscribeUpdates
|
||||
*
|
||||
* @since 24.08
|
||||
*/
|
||||
virtual SubscriptionHandle subscribeUpdates(const std::function<void()> &callback) const = 0;
|
||||
/**
|
||||
* Unsubscribes a handle for updates. Handle must be acquired by
|
||||
* the \ref subscribeUpdates function
|
||||
*
|
||||
* @return true if subscription succeeded and false if failed.
|
||||
* The most likely reason for for failure is if the handle was
|
||||
* already unsubscribed or for other reasons not existing
|
||||
*
|
||||
* @since 24.08
|
||||
*/
|
||||
virtual bool unsubscribeUpdates(const SubscriptionHandle &) const = 0;
|
||||
|
||||
protected:
|
||||
FormFieldSignature();
|
||||
|
||||
|
|
|
@ -333,14 +333,15 @@ public:
|
|||
* The verification result of the certificate.
|
||||
*/
|
||||
enum CertificateStatus {
|
||||
CertificateStatusUnknown, ///< The certificate status is unknown for some reason.
|
||||
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.
|
||||
CertificateStatusUnknown, ///< The certificate status is unknown for some reason.
|
||||
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.
|
||||
CertificateVerificationInProgress, ///< The certification is not yet verified, but in progress \since 24.08
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -397,12 +397,39 @@ PopplerFormFieldSignature::PopplerFormFieldSignature(std::unique_ptr<Poppler::Fo
|
|||
if (!PDFSettings::checkOCSPServers()) {
|
||||
validateOptions = validateOptions | Poppler::FormFieldSignature::ValidateWithoutOCSPRevocationCheck;
|
||||
}
|
||||
|
||||
#if POPPLER_VERSION_MACRO > QT_VERSION_CHECK(24, 4, 0)
|
||||
auto result = m_field->validateAsync(static_cast<Poppler::FormFieldSignature::ValidateOptions>(validateOptions));
|
||||
m_info = fromPoppler(result.first);
|
||||
m_asyncObject = result.second;
|
||||
QObject::connect(m_asyncObject.get(), &Poppler::AsyncObject::done, m_asyncObject.get(), [this]() {
|
||||
m_info.setCertificateStatus(fromPoppler(m_field->validateResult()));
|
||||
for (auto [_, callback] : m_updateSubscriptions) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
#else
|
||||
m_info = fromPoppler(m_field->validate(static_cast<Poppler::FormFieldSignature::ValidateOptions>(validateOptions)));
|
||||
#endif
|
||||
SET_ACTIONS
|
||||
}
|
||||
|
||||
PopplerFormFieldSignature::~PopplerFormFieldSignature() = default;
|
||||
|
||||
static Okular::FormFieldSignature::SubscriptionHandle globalHandle = 0;
|
||||
|
||||
Okular::FormFieldSignature::SubscriptionHandle PopplerFormFieldSignature::subscribeUpdates(const std::function<void()> &callback) const
|
||||
{
|
||||
auto handle = (globalHandle++);
|
||||
m_updateSubscriptions.emplace(handle, callback);
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool PopplerFormFieldSignature::unsubscribeUpdates(const SubscriptionHandle &handle) const
|
||||
{
|
||||
return m_updateSubscriptions.erase(handle) == 1;
|
||||
}
|
||||
|
||||
Okular::NormalizedRect PopplerFormFieldSignature::rect() const
|
||||
{
|
||||
return m_rect;
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
#include "core/form.h"
|
||||
#include <poppler-form.h>
|
||||
#include <poppler-version.h>
|
||||
#include <unordered_map>
|
||||
#define POPPLER_VERSION_MACRO ((POPPLER_VERSION_MAJOR << 16) | (POPPLER_VERSION_MINOR << 8) | (POPPLER_VERSION_MICRO))
|
||||
|
||||
class PopplerFormFieldButton : public Okular::FormFieldButton
|
||||
{
|
||||
|
@ -140,11 +143,18 @@ public:
|
|||
Okular::SignatureInfo signatureInfo() const override;
|
||||
bool sign(const Okular::NewSignatureData &oData, const QString &newPath) const override;
|
||||
|
||||
SubscriptionHandle subscribeUpdates(const std::function<void()> &callback) const final;
|
||||
bool unsubscribeUpdates(const SubscriptionHandle &handle) const final;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poppler::FormFieldSignature> m_field;
|
||||
Okular::SignatureInfo m_info;
|
||||
Okular::NormalizedRect m_rect;
|
||||
int m_id;
|
||||
#if POPPLER_VERSION_MACRO > QT_VERSION_CHECK(24, 4, 0)
|
||||
std::shared_ptr<Poppler::AsyncObject> m_asyncObject;
|
||||
#endif
|
||||
mutable std::unordered_map<SubscriptionHandle, std::function<void()>> m_updateSubscriptions;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,6 +137,10 @@ Okular::SignatureInfo::CertificateStatus fromPoppler(Poppler::SignatureValidatio
|
|||
return Okular::SignatureInfo::CertificateGenericError;
|
||||
case Poppler::SignatureValidationInfo::CertificateNotVerified:
|
||||
return Okular::SignatureInfo::CertificateNotVerified;
|
||||
#if POPPLER_VERSION_MACRO > QT_VERSION_CHECK(24, 04, 0)
|
||||
case Poppler::SignatureValidationInfo::CertificateVerificationInProgress:
|
||||
return Okular::SignatureInfo::CertificateVerificationInProgress;
|
||||
#endif
|
||||
default:
|
||||
return Okular::SignatureInfo::CertificateStatusUnknown;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
Okular::SignatureInfo fromPoppler(const Poppler::SignatureValidationInfo &info);
|
||||
Okular::CertificateInfo fromPoppler(const Poppler::CertificateInfo &info);
|
||||
Okular::SignatureInfo::CertificateStatus fromPoppler(Poppler::SignatureValidationInfo::CertificateStatus status);
|
||||
|
||||
class PopplerCertificateStore : public Okular::CertificateStore
|
||||
{
|
||||
|
|
|
@ -68,6 +68,8 @@ QString getReadableCertStatus(Okular::SignatureInfo::CertificateStatus certStatu
|
|||
return i18n("Certificate has Expired.");
|
||||
case Okular::SignatureInfo::CertificateNotVerified:
|
||||
return i18n("Certificate has not yet been verified.");
|
||||
case Okular::SignatureInfo::CertificateVerificationInProgress:
|
||||
return i18n("Certificate validation in progress");
|
||||
default:
|
||||
return i18n("Unknown issue with Certificate or corrupted data.");
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "core/signatureutils.h"
|
||||
|
||||
struct SignatureItem {
|
||||
enum DataType { Root, RevisionInfo, ValidityStatus, SigningTime, Reason, Location, FieldInfo };
|
||||
enum DataType { Root, RevisionInfo, ValidityStatus, CertificateStatus, SigningTime, Reason, Location, FieldInfo };
|
||||
|
||||
SignatureItem();
|
||||
SignatureItem(SignatureItem *parent, const Okular::FormFieldSignature *form, DataType type, int page);
|
||||
|
@ -154,6 +154,15 @@ void SignatureModelPrivate::notifySetup(const QVector<Okular::Page *> &pages, in
|
|||
auto childItem1 = new SignatureItem(parentItem, nullptr, SignatureItem::ValidityStatus, pageNumber);
|
||||
childItem1->displayString = SignatureGuiUtils::getReadableSignatureStatus(info.signatureStatus());
|
||||
|
||||
auto childItem1a = new SignatureItem(parentItem, nullptr, SignatureItem::CertificateStatus, pageNumber);
|
||||
childItem1a->displayString = SignatureGuiUtils::getReadableCertStatus(info.certificateStatus());
|
||||
sf->subscribeUpdates([childItem1a, sf, this]() {
|
||||
const Okular::SignatureInfo &info = sf->signatureInfo();
|
||||
childItem1a->displayString = SignatureGuiUtils::getReadableCertStatus(info.certificateStatus());
|
||||
auto index = indexForItem(childItem1a);
|
||||
q->dataChanged(index, index);
|
||||
});
|
||||
|
||||
auto childItem2 = new SignatureItem(parentItem, nullptr, SignatureItem::SigningTime, pageNumber);
|
||||
childItem2->displayString = i18n("Signing Time: %1", QLocale().toString(info.signingTime(), QLocale::LongFormat));
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user