[pim/libkleo] /: Show issuer serial number and issuer name for unknown S/MIME certs
Ingo Klöcker <[email protected]> Tue, 4 Aug 2026 14:33:46 +0000 (UTC)
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 2e714e6ef53f7eedbdd776b798454c02a79aab86 by Ingo Klöcker, on behalf of Ingo Klöcker.
Committed on 04/08/2026 at 14:33.
Pushed by kloecker into branch 'master'.
Show issuer serial number and issuer name for unknown S/MIME certs
This allows the user to search for the S/MIME certificate that was used
for signing something but that is not included with the signature.
GnuPG-bug-id: 7786
M +9 -1 autotests/formattingtest.cpp
M +20 -0 src/utils/formatting.cpp
https://invent.kde.org/pim/libkleo/-/commit/2e714e6ef53f7eedbdd776b798454c02a79aab86
diff --git a/autotests/formattingtest.cpp b/autotests/formattingtest.cpp
index 6587f301..014c6a97 100644
--- a/autotests/formattingtest.cpp
+++ b/autotests/formattingtest.cpp
@@ -24,6 +24,7 @@
#include <QTest>
#include <gpgme++/engineinfo.h>
+#include <gpgme++/gpgmepp_version.h>
#include <gpgme++/importresult.h>
#include <gpgme++/signingresult.h>
#include <gpgme++/verificationresult.h>
@@ -529,7 +530,14 @@ private Q_SLOTS:
QCOMPARE(verificationResult.numSignatures(), 1);
const QString result = Formatting::prettyDataSignature(verificationResult.signature(0), {});
- const auto expected = u"The data cannot be trusted. Reason: The signature cannot be verified because the corresponding certificate is not available."_s;
+ const auto expected = u"The data cannot be trusted. Reason: The signature cannot be verified because the corresponding certificate is not available."_s
+#if GPGMEPP_VERSION >= QT_VERSION_CHECK(2, 1, 1)
+ + ((GpgME::engineInfo(GpgME::GpgEngine).engineVersion() >= "2.5.22")
+ ? u" The signing certificate’s serial number and issuer are "
+ "#1A03/1.2.840.113549.1.9.1=#696E666F40673130636F64652E636F6D,CN=g10 Code TEST CA 2019,OU=Testlab,O=g10 Code GmbH,C=DE."_s
+ : QString{})
+#endif
+ ;
QCOMPARE(result, expected);
}
diff --git a/src/utils/formatting.cpp b/src/utils/formatting.cpp
index 84e84686..b211ce2f 100644
--- a/src/utils/formatting.cpp
+++ b/src/utils/formatting.cpp
@@ -38,6 +38,7 @@
#include <QRegularExpression>
#include <QString>
+#include <gpgme++/gpgmepp_version.h>
#include <gpgme++/importresult.h>
#include <gpgme++/key.h>
@@ -1539,6 +1540,18 @@ static QString renderFingerprintLinkV2(const char *fpr)
return u"<a href=\"certificate:%1\">%2</a>"_s.arg(QString::fromLatin1(fpr), Formatting::prettyID(fpr));
}
+#if GPGMEPP_VERSION >= QT_VERSION_CHECK(2, 1, 1)
+// assumes that issuerSerial is hex-encoded serial number and that issuerName is RFC 2253-encoded DN of issuer
+static QString renderSMIMECertificateReference(const char *issuerSerial, const char *issuerName)
+{
+ Q_ASSERT(issuerSerial && issuerName);
+ if (!(issuerSerial && issuerName)) {
+ return {};
+ }
+ return QString::fromLatin1('#' + QByteArrayView{issuerSerial} + '/' + QByteArrayView{issuerName});
+}
+#endif
+
static QDateTime signatureCreationTime(const GpgME::Signature &sig)
{
return sig.creationTime() != 0 ? QDateTime::fromSecsSinceEpoch(quint32(sig.creationTime())) : QDateTime();
@@ -1823,6 +1836,13 @@ QString Kleo::Formatting::prettyDataSignature(const GpgME::Signature &sig, const
if (sig.fingerprint()) {
text += u' ';
text += i18nc("@info", "The signing certificate’s fingerprint is %1.", renderFingerprintLinkV2(sig.fingerprint()));
+#if GPGMEPP_VERSION >= QT_VERSION_CHECK(2, 1, 1)
+ } else if (sig.issuerSerial() && sig.issuerName()) {
+ text += u' ';
+ text += i18nc("@info",
+ "The signing certificate’s serial number and issuer are %1.",
+ renderSMIMECertificateReference(sig.issuerSerial(), sig.issuerName()));
+#endif
}
return text;
}