[poppler] poppler/CertificateInfo.cc poppler/CertificateInfo.h poppler/GPGMECryptoSignBackend.cc qt5/src qt6/src utils/pdfsig.cc
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Aug 2 22:39:29 UTC 2023
poppler/CertificateInfo.cc | 11 ++++++++++-
poppler/CertificateInfo.h | 19 +++++++++++++++++++
poppler/GPGMECryptoSignBackend.cc | 7 +++++++
qt5/src/poppler-form.cc | 23 +++++++++++++++++++++++
qt5/src/poppler-form.h | 25 +++++++++++++++++++++++++
qt6/src/poppler-form.cc | 23 +++++++++++++++++++++++
qt6/src/poppler-form.h | 25 +++++++++++++++++++++++++
utils/pdfsig.cc | 18 +++++++++++++++++-
8 files changed, 149 insertions(+), 2 deletions(-)
New commits:
commit 7dedced88e354625ef3f4dc09c9732a4d91cf5d7
Author: Sune Vuorela <sune at vuorela.dk>
Date: Wed Aug 2 22:39:27 2023 +0000
Provide the key location for certificates you can sign with
diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc
index b6a8437a..d4ae8f64 100644
--- a/poppler/CertificateInfo.cc
+++ b/poppler/CertificateInfo.cc
@@ -17,7 +17,7 @@
#include <cstring>
#include <cstdlib>
-X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_self_signed(false) { }
+X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_self_signed(false), keyLocation(KeyLocation::Unknown) { }
X509CertificateInfo::~X509CertificateInfo() = default;
@@ -120,3 +120,12 @@ void X509CertificateInfo::setIsSelfSigned(bool isSelfSigned)
{
is_self_signed = isSelfSigned;
}
+KeyLocation X509CertificateInfo::getKeyLocation() const
+{
+ return keyLocation;
+}
+
+void X509CertificateInfo::setKeyLocation(KeyLocation location)
+{
+ keyLocation = location;
+}
diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
index 600ecb52..d2dbc34f 100644
--- a/poppler/CertificateInfo.h
+++ b/poppler/CertificateInfo.h
@@ -41,6 +41,22 @@ enum PublicKeyType
OTHERKEY
};
+/** A signing key can be located in different places
+ sometimes. For the user, it might be easier to pick
+ the key located on a card if it has some visual
+ indicator that it is somehow removable.
+
+ \note a keylocation for a certificate without a private
+ key (cannot be used for signing) will likely be "Unknown"
+ */
+enum class KeyLocation
+{
+ Unknown, /** We don't know the location */
+ Other, /** We know the location, but it is somehow not covered by this enum */
+ Computer, /** The key is on this computer */
+ HardwareToken /** The key is on a dedicated hardware token, either a smartcard or a dedicated usb token (e.g. gnuk, nitrokey or yubikey) */
+};
+
class POPPLER_PRIVATE_EXPORT X509CertificateInfo
{
public:
@@ -101,6 +117,7 @@ public:
unsigned int getKeyUsageExtensions() const;
const GooString &getCertificateDER() const;
bool getIsSelfSigned() const;
+ KeyLocation getKeyLocation() const;
/* SETTERS */
void setVersion(int);
@@ -113,6 +130,7 @@ public:
void setKeyUsageExtensions(unsigned int);
void setCertificateDER(const GooString &);
void setIsSelfSigned(bool);
+ void setKeyLocation(KeyLocation location);
private:
EntityInfo issuer_info;
@@ -125,6 +143,7 @@ private:
unsigned int ku_extensions;
int cert_version;
bool is_self_signed;
+ KeyLocation keyLocation;
};
#endif
diff --git a/poppler/GPGMECryptoSignBackend.cc b/poppler/GPGMECryptoSignBackend.cc
index 6f82e266..273cce0e 100644
--- a/poppler/GPGMECryptoSignBackend.cc
+++ b/poppler/GPGMECryptoSignBackend.cc
@@ -153,6 +153,13 @@ static std::unique_ptr<X509CertificateInfo> getCertificateInfoFromKey(const GpgM
}
certificateInfo->setKeyUsageExtensions(kue);
+ auto subkey = key.subkey(0);
+ if (subkey.isCardKey()) {
+ certificateInfo->setKeyLocation(KeyLocation::HardwareToken);
+ } else if (subkey.isSecret()) {
+ certificateInfo->setKeyLocation(KeyLocation::Computer);
+ }
+
return certificateInfo;
}
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index d46b5b42..08c91c33 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -610,6 +610,7 @@ public:
int version;
bool is_self_signed;
bool is_null;
+ CertificateInfo::KeyLocation keyLocation;
};
CertificateInfo::CertificateInfo() : d_ptr(new CertificateInfoPrivate())
@@ -735,6 +736,12 @@ CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const
return kuExtensions;
}
+CertificateInfo::KeyLocation CertificateInfo::keyLocation() const
+{
+ Q_D(const CertificateInfo);
+ return d->keyLocation;
+}
+
QByteArray CertificateInfo::publicKey() const
{
Q_D(const CertificateInfo);
@@ -971,6 +978,21 @@ SignatureValidationInfo FormFieldSignature::validate(ValidateOptions opt) const
return validate(opt, QDateTime());
}
+static CertificateInfo::KeyLocation fromPopplerCore(KeyLocation location)
+{
+ switch (location) {
+ case KeyLocation::Computer:
+ return CertificateInfo::KeyLocation::Computer;
+ case KeyLocation::Other:
+ return CertificateInfo::KeyLocation::Other;
+ case KeyLocation::Unknown:
+ return CertificateInfo::KeyLocation::Unknown;
+ case KeyLocation::HardwareToken:
+ return CertificateInfo::KeyLocation::HardwareToken;
+ }
+ return CertificateInfo::KeyLocation::Unknown;
+}
+
static CertificateInfoPrivate *createCertificateInfoPrivate(const X509CertificateInfo *ci)
{
CertificateInfoPrivate *certPriv = new CertificateInfoPrivate;
@@ -978,6 +1000,7 @@ static CertificateInfoPrivate *createCertificateInfoPrivate(const X509Certificat
if (ci) {
certPriv->version = ci->getVersion();
certPriv->ku_extensions = ci->getKeyUsageExtensions();
+ certPriv->keyLocation = fromPopplerCore(ci->getKeyLocation());
const GooString &certSerial = ci->getSerialNumber();
certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index 9599a855..ad4fa2c3 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -535,6 +535,24 @@ public:
Organization,
};
+ /** A signing key can be located in different places
+ sometimes. For the user, it might be easier to pick
+ the key located on a card if it has some visual
+ indicator that it is somehow removable.
+
+ \note a keylocation for a certificate without a private
+ key (cannot be used for signing) will likely be "Unknown"
+
+ \since 23.09
+ */
+ enum class KeyLocation
+ {
+ Unknown, /** We don't know the location */
+ Other, /** We know the location, but it is somehow not covered by this enum */
+ Computer, /** The key is on this computer */
+ HardwareToken /** The key is on a dedicated hardware token, either a smartcard or a dedicated usb token (e.g. gnuk, nitrokey or yubikey) */
+ };
+
CertificateInfo();
explicit CertificateInfo(CertificateInfoPrivate *priv);
~CertificateInfo();
@@ -618,6 +636,13 @@ public:
*/
bool checkPassword(const QString &password) const;
+ /**
+ The storage location for this key
+
+ \since 23.09
+ */
+ KeyLocation keyLocation() const;
+
CertificateInfo(const CertificateInfo &other);
CertificateInfo &operator=(const CertificateInfo &other);
diff --git a/qt6/src/poppler-form.cc b/qt6/src/poppler-form.cc
index 94fc06e0..781e9546 100644
--- a/qt6/src/poppler-form.cc
+++ b/qt6/src/poppler-form.cc
@@ -610,6 +610,7 @@ public:
int version;
bool is_self_signed;
bool is_null;
+ CertificateInfo::KeyLocation keyLocation;
};
CertificateInfo::CertificateInfo() : d_ptr(new CertificateInfoPrivate())
@@ -735,6 +736,12 @@ CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const
return kuExtensions;
}
+CertificateInfo::KeyLocation CertificateInfo::keyLocation() const
+{
+ Q_D(const CertificateInfo);
+ return d->keyLocation;
+}
+
QByteArray CertificateInfo::publicKey() const
{
Q_D(const CertificateInfo);
@@ -971,6 +978,21 @@ SignatureValidationInfo FormFieldSignature::validate(ValidateOptions opt) const
return validate(opt, QDateTime());
}
+static CertificateInfo::KeyLocation fromPopplerCore(KeyLocation location)
+{
+ switch (location) {
+ case KeyLocation::Computer:
+ return CertificateInfo::KeyLocation::Computer;
+ case KeyLocation::Other:
+ return CertificateInfo::KeyLocation::Other;
+ case KeyLocation::Unknown:
+ return CertificateInfo::KeyLocation::Unknown;
+ case KeyLocation::HardwareToken:
+ return CertificateInfo::KeyLocation::HardwareToken;
+ }
+ return CertificateInfo::KeyLocation::Unknown;
+}
+
static CertificateInfoPrivate *createCertificateInfoPrivate(const X509CertificateInfo *ci)
{
CertificateInfoPrivate *certPriv = new CertificateInfoPrivate;
@@ -978,6 +1000,7 @@ static CertificateInfoPrivate *createCertificateInfoPrivate(const X509Certificat
if (ci) {
certPriv->version = ci->getVersion();
certPriv->ku_extensions = ci->getKeyUsageExtensions();
+ certPriv->keyLocation = fromPopplerCore(ci->getKeyLocation());
const GooString &certSerial = ci->getSerialNumber();
certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
diff --git a/qt6/src/poppler-form.h b/qt6/src/poppler-form.h
index 2915df6c..7bd4105d 100644
--- a/qt6/src/poppler-form.h
+++ b/qt6/src/poppler-form.h
@@ -501,6 +501,24 @@ public:
Organization,
};
+ /** A signing key can be located in different places
+ sometimes. For the user, it might be easier to pick
+ the key located on a card if it has some visual
+ indicator that it is somehow removable.
+
+ \note a keylocation for a certificate without a private
+ key (cannot be used for signing) will likely be "Unknown"
+
+ \since 23.09
+ */
+ enum class KeyLocation
+ {
+ Unknown, /** We don't know the location */
+ Other, /** We know the location, but it is somehow not covered by this enum */
+ Computer, /** The key is on this computer */
+ HardwareToken /** The key is on a dedicated hardware token, either a smartcard or a dedicated usb token (e.g. gnuk, nitrokey or yubikey) */
+ };
+
CertificateInfo();
explicit CertificateInfo(CertificateInfoPrivate *priv);
~CertificateInfo();
@@ -584,6 +602,13 @@ public:
*/
bool checkPassword(const QString &password) const;
+ /**
+ The storage location for this key
+
+ \since 23.09
+ */
+ KeyLocation keyLocation() const;
+
CertificateInfo(const CertificateInfo &other);
CertificateInfo &operator=(const CertificateInfo &other);
diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc
index 7e6c7e8b..1c016847 100644
--- a/utils/pdfsig.cc
+++ b/utils/pdfsig.cc
@@ -256,6 +256,21 @@ static std::vector<std::unique_ptr<X509CertificateInfo>> getAvailableSigningCert
return vCerts;
}
+static std::string locationToString(KeyLocation location)
+{
+ switch (location) {
+ case KeyLocation::Unknown:
+ return {};
+ case KeyLocation::Other:
+ return "(Other)";
+ case KeyLocation::Computer:
+ return "(Computer)";
+ case KeyLocation::HardwareToken:
+ return "(Hardware Token)";
+ }
+ return {};
+}
+
static std::string TextStringToUTF8(const std::string &str)
{
const UnicodeMap *utf8Map = globalParams->getUtf8Map();
@@ -329,7 +344,8 @@ int main(int argc, char *argv[])
printf("Certificate nicknames available:\n");
for (auto &cert : vCerts) {
const GooString &nick = cert->getNickName();
- printf("%s\n", nick.c_str());
+ const auto location = locationToString(cert->getKeyLocation());
+ printf("%s %s\n", nick.c_str(), location.c_str());
}
}
}
More information about the poppler
mailing list