From 514623e7a02239aa0c1f47c907ae8719910282ca Mon Sep 17 00:00:00 2001 From: Sune Vuorela Date: Tue, 16 Apr 2024 11:32:45 +0200 Subject: [PATCH] Mark certificates that can do qualified signing Certain signatures can do qualified signing (legally binding). Ensure that they can be properly tagged in various UI's. --- poppler/CertificateInfo.cc | 12 +++++++++++- poppler/CertificateInfo.h | 3 +++ poppler/GPGMECryptoSignBackend.cc | 2 ++ qt6/src/poppler-form.cc | 8 ++++++++ qt6/src/poppler-form.h | 7 +++++++ utils/pdfsig.cc | 2 +- 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc index d4ae8f640..8e12c08aa 100644 --- a/poppler/CertificateInfo.cc +++ b/poppler/CertificateInfo.cc @@ -17,7 +17,7 @@ #include #include -X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_self_signed(false), keyLocation(KeyLocation::Unknown) { } +X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_qualified(false), is_self_signed(false), keyLocation(KeyLocation::Unknown) { } X509CertificateInfo::~X509CertificateInfo() = default; @@ -129,3 +129,13 @@ void X509CertificateInfo::setKeyLocation(KeyLocation location) { keyLocation = location; } + +bool X509CertificateInfo::isQualified() const +{ + return is_qualified; +} + +void X509CertificateInfo::setQualified(bool qualified) +{ + is_qualified = qualified; +} diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h index d2dbc34f4..99db5b660 100644 --- a/poppler/CertificateInfo.h +++ b/poppler/CertificateInfo.h @@ -117,6 +117,8 @@ class POPPLER_PRIVATE_EXPORT X509CertificateInfo unsigned int getKeyUsageExtensions() const; const GooString &getCertificateDER() const; bool getIsSelfSigned() const; + bool isQualified() const; + void setQualified(bool qualified); KeyLocation getKeyLocation() const; /* SETTERS */ @@ -142,6 +144,7 @@ class POPPLER_PRIVATE_EXPORT X509CertificateInfo GooString cert_nick; unsigned int ku_extensions; int cert_version; + bool is_qualified; bool is_self_signed; KeyLocation keyLocation; }; diff --git a/poppler/GPGMECryptoSignBackend.cc b/poppler/GPGMECryptoSignBackend.cc index de1d9a2d3..840acc02d 100644 --- a/poppler/GPGMECryptoSignBackend.cc +++ b/poppler/GPGMECryptoSignBackend.cc @@ -176,6 +176,8 @@ static std::unique_ptr getCertificateInfoFromKey(const GpgM certificateInfo->setKeyLocation(KeyLocation::Computer); } + certificateInfo->setQualified(subkey.isQualified()); + return certificateInfo; } diff --git a/qt6/src/poppler-form.cc b/qt6/src/poppler-form.cc index 18a26cc87..348b499b7 100644 --- a/qt6/src/poppler-form.cc +++ b/qt6/src/poppler-form.cc @@ -619,6 +619,7 @@ class CertificateInfoPrivate int version; bool is_self_signed; bool is_null; + bool is_qualified; CertificateInfo::KeyLocation keyLocation; }; @@ -660,6 +661,12 @@ QByteArray CertificateInfo::serialNumber() const return d->serial_number; } +bool CertificateInfo::isQualified() const +{ + Q_D(const CertificateInfo); + return d->is_qualified; +} + QString CertificateInfo::issuerInfo(EntityInfoKey key) const { Q_D(const CertificateInfo); @@ -1043,6 +1050,7 @@ static CertificateInfoPrivate *createCertificateInfoPrivate(const X509Certificat certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength()); certPriv->is_null = false; + certPriv->is_qualified = ci->isQualified(); } return certPriv; diff --git a/qt6/src/poppler-form.h b/qt6/src/poppler-form.h index a15b2e44a..4207303be 100644 --- a/qt6/src/poppler-form.h +++ b/qt6/src/poppler-form.h @@ -599,6 +599,13 @@ class POPPLER_QT6_EXPORT CertificateInfo */ bool isSelfSigned() const; + /** + * Can be used to do qualified electronic signatures (legally binding) + * + * https://en.wikipedia.org/wiki/Qualified_electronic_signature + */ + bool isQualified() const; + /** The DER encoded certificate. */ diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc index 233e99f52..6515ea2f1 100644 --- a/utils/pdfsig.cc +++ b/utils/pdfsig.cc @@ -354,7 +354,7 @@ int main(int argc, char *argv[]) for (auto &cert : vCerts) { const GooString &nick = cert->getNickName(); const auto location = locationToString(cert->getKeyLocation()); - printf("%s %s\n", nick.c_str(), location.c_str()); + printf("%s %s %s\n", nick.c_str(), (cert->isQualified() ? "(*)" : " "), location.c_str()); } } }