diff --git a/core/signatureutils.cpp b/core/signatureutils.cpp index 345dd1c7a..1f9f97e7d 100644 --- a/core/signatureutils.cpp +++ b/core/signatureutils.cpp @@ -91,6 +91,11 @@ QByteArray CertificateInfo::certificateData() const return QByteArray(); } +bool CertificateInfo::checkPassword(const QString & /*password*/) const +{ + return false; +} + SignatureInfo::SignatureInfo() { } diff --git a/core/signatureutils.h b/core/signatureutils.h index 83c98c065..ee408562f 100644 --- a/core/signatureutils.h +++ b/core/signatureutils.h @@ -124,6 +124,13 @@ public: */ virtual QByteArray certificateData() const; + /** + * Checks if the given password is the correct one for this certificate + * + * @since 21.04 + */ + virtual bool checkPassword(const QString &password) const; + protected: friend class SignatureInfo; CertificateInfo(); diff --git a/generators/poppler/pdfsignatureutils.cpp b/generators/poppler/pdfsignatureutils.cpp index 31e6fb291..536ae53d1 100644 --- a/generators/poppler/pdfsignatureutils.cpp +++ b/generators/poppler/pdfsignatureutils.cpp @@ -126,6 +126,16 @@ QByteArray PopplerCertificateInfo::certificateData() const return m_info.certificateData(); } +bool PopplerCertificateInfo::checkPassword(const QString &password) const +{ +#ifdef HAVE_POPPLER_SIGNING + return m_info.checkPassword(password); +#else + Q_UNUSED(password); + return false; +#endif +} + PopplerSignatureInfo::PopplerSignatureInfo(const Poppler::SignatureValidationInfo &info) : m_info(info) { diff --git a/generators/poppler/pdfsignatureutils.h b/generators/poppler/pdfsignatureutils.h index 9027f0bc7..56a29db01 100644 --- a/generators/poppler/pdfsignatureutils.h +++ b/generators/poppler/pdfsignatureutils.h @@ -36,6 +36,7 @@ public: int publicKeyStrength() const override; bool isSelfSigned() const override; QByteArray certificateData() const override; + bool checkPassword(const QString &password) const override; private: Poppler::CertificateInfo m_info; diff --git a/part/pageviewannotator.cpp b/part/pageviewannotator.cpp index 11b6dd1fd..6e557459a 100644 --- a/part/pageviewannotator.cpp +++ b/part/pageviewannotator.cpp @@ -358,10 +358,10 @@ public: const QList &certs = certStore->signingCertificates(); QStringList items; - QHash nickToCommonName; + QHash nickToCert; for (auto cert : certs) { items.append(cert->nickName()); - nickToCommonName[cert->nickName()] = cert->subjectInfo(Okular::CertificateInfo::CommonName); + nickToCert[cert->nickName()] = cert; } if (items.isEmpty()) { @@ -375,12 +375,24 @@ public: certNicknameToUse = QInputDialog::getItem(m_pageView, i18n("Select certificate to sign with"), i18n("Certificates:"), items, 0, false, &resok); if (resok) { - bool passok = false; - const QString title = i18n("Enter password (if any) to unlock certificate: %1", certNicknameToUse); - passToUse = QInputDialog::getText(m_pageView, i18n("Enter certificate password"), title, QLineEdit::Password, QString(), &passok); + // I could not find any case in which i need to enter a password to use the certificate, seems that once you unlcok the firefox/NSS database + // you don't need a password anymore, but still there's code to do that in NSS so we have code to ask for it if needed. What we do is + // ask if the empty password is fine, if it is we don't ask the user anything, if it's not, we ask for a password + Okular::CertificateInfo *cert = nickToCert.value(certNicknameToUse); + bool passok = cert->checkPassword(QString()); + while (!passok) { + const QString title = i18n("Enter password (if any) to unlock certificate: %1", certNicknameToUse); + bool ok; + passToUse = QInputDialog::getText(m_pageView, i18n("Enter certificate password"), title, QLineEdit::Password, QString(), &ok); + if (ok) { + passok = cert->checkPassword(passToUse); + } else { + break; + } + } if (passok) { - certCommonName = nickToCommonName.value(certNicknameToUse); + certCommonName = cert->subjectInfo(Okular::CertificateInfo::CommonName); } else { certNicknameToUse.clear(); }