[poppler] 10 commits - CMakeLists.txt poppler/CertificateInfo.cc poppler/CertificateInfo.h poppler/Form.cc poppler/SignatureHandler.cc poppler/SignatureHandler.h poppler/SignatureInfo.cc poppler/SignatureInfo.h qt5/src

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Jan 6 09:59:17 UTC 2019


 CMakeLists.txt              |    2 
 poppler/CertificateInfo.cc  |  144 +++++++++++++++++++++++++++
 poppler/CertificateInfo.h   |  120 ++++++++++++++++++++++
 poppler/Form.cc             |    3 
 poppler/SignatureHandler.cc |  114 ++++++++++++++++++++-
 poppler/SignatureHandler.h  |    5 
 poppler/SignatureInfo.cc    |   14 ++
 poppler/SignatureInfo.h     |    7 +
 qt5/src/poppler-form.cc     |  234 +++++++++++++++++++++++++++++++++++++++++++-
 qt5/src/poppler-form.h      |  139 +++++++++++++++++++++++++-
 10 files changed, 771 insertions(+), 11 deletions(-)

New commits:
commit 5196cf634cddabde8963306ab99f86c3840fbbbb
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jan 5 20:11:22 2019 +0100

    qt5: Remove CertificateInfo()
    
    This is BC because the version with it was never released
    
    People will shoot themselves on the foot and we don't need it

diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index 50425b86..ef13e58c 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -1,6 +1,6 @@
 /* poppler-form.h: qt interface to poppler
  * Copyright (C) 2007-2008, 2011, Pino Toscano <pino at kde.org>
- * Copyright (C) 2008, 2011, 2012, 2015-2018 Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2008, 2011, 2012, 2015-2019 Albert Astals Cid <aacid at kde.org>
  * Copyright (C) 2011 Carlos Garcia Campos <carlosgc at gnome.org>
  * Copyright (C) 2012, Adam Reichold <adamreichold at myopera.com>
  * Copyright (C) 2016, Hanno Meyer-Thurow <h.mth at web.de>
@@ -523,11 +523,6 @@ public:
   bool is_null;
 };
 
-CertificateInfo::CertificateInfo()
-  : d_ptr( nullptr )
-{
-}
-
 CertificateInfo::CertificateInfo(CertificateInfoPrivate* priv)
   : d_ptr( priv )
 {
@@ -681,6 +676,11 @@ QByteArray CertificateInfo::certificateData() const
 
 class SignatureValidationInfoPrivate {
 public:
+	SignatureValidationInfoPrivate(CertificateInfo &&ci)
+		: cert_info(ci)
+	{
+	}
+
 	SignatureValidationInfo::SignatureStatus signature_status;
 	SignatureValidationInfo::CertificateStatus certificate_status;
 	CertificateInfo cert_info;
@@ -869,7 +869,47 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
   FormWidgetSignature* fws = static_cast<FormWidgetSignature*>(m_formData->fm);
   const time_t validationTimeT = validationTime.isValid() ? validationTime.toTime_t() : -1;
   SignatureInfo* si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT);
-  SignatureValidationInfoPrivate* priv = new SignatureValidationInfoPrivate;
+
+  // get certificate info
+  const X509CertificateInfo *ci = si->getCertificateInfo();
+  CertificateInfoPrivate* certPriv = new CertificateInfoPrivate;
+  certPriv->is_null = true;
+  if (ci)
+  {
+    certPriv->version = ci->getVersion();
+    certPriv->ku_extensions = ci->getKeyUsageExtensions();
+
+    const GooString &certSerial = ci->getSerialNumber();
+    certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
+
+    const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
+    certPriv->issuer_info.common_name = issuerInfo.commonName.c_str();
+    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName.c_str();
+    certPriv->issuer_info.email_address = issuerInfo.email.c_str();
+    certPriv->issuer_info.org_name = issuerInfo.organization.c_str();
+
+    const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
+    certPriv->subject_info.common_name = subjectInfo.commonName.c_str();
+    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName.c_str();
+    certPriv->subject_info.email_address = subjectInfo.email.c_str();
+    certPriv->subject_info.org_name = subjectInfo.organization.c_str();
+
+    X509CertificateInfo::Validity certValidity = ci->getValidity();
+    certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
+    certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);
+
+    const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
+    certPriv->public_key = QByteArray(pkInfo.publicKey.c_str(), pkInfo.publicKey.getLength());
+    certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
+    certPriv->public_key_strength = pkInfo.publicKeyStrength;
+
+    const GooString &certDer = ci->getCertificateDER();
+    certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength());
+
+    certPriv->is_null = false;
+  }
+
+  SignatureValidationInfoPrivate* priv = new SignatureValidationInfoPrivate(CertificateInfo(certPriv));
   switch (si->getSignatureValStatus()) {
     case SIGNATURE_VALID:
       priv->signature_status = SignatureValidationInfo::SignatureValid;
@@ -940,46 +980,6 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
   }
   delete checkedSignature;
 
-  // set certificate info
-  const X509CertificateInfo *ci = si->getCertificateInfo();
-  CertificateInfoPrivate* certPriv = new CertificateInfoPrivate;
-  certPriv->is_null = true;
-  if (ci)
-  {
-    certPriv->version = ci->getVersion();
-    certPriv->ku_extensions = ci->getKeyUsageExtensions();
-
-    const GooString &certSerial = ci->getSerialNumber();
-    certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
-
-    const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
-    certPriv->issuer_info.common_name = issuerInfo.commonName.c_str();
-    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName.c_str();
-    certPriv->issuer_info.email_address = issuerInfo.email.c_str();
-    certPriv->issuer_info.org_name = issuerInfo.organization.c_str();
-
-    const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
-    certPriv->subject_info.common_name = subjectInfo.commonName.c_str();
-    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName.c_str();
-    certPriv->subject_info.email_address = subjectInfo.email.c_str();
-    certPriv->subject_info.org_name = subjectInfo.organization.c_str();
-
-    X509CertificateInfo::Validity certValidity = ci->getValidity();
-    certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
-    certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);
-
-    const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
-    certPriv->public_key = QByteArray(pkInfo.publicKey.c_str(), pkInfo.publicKey.getLength());
-    certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
-    certPriv->public_key_strength = pkInfo.publicKeyStrength;
-
-    const GooString &certDer = ci->getCertificateDER();
-    certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength());
-
-    certPriv->is_null = false;
-  }
-  priv->cert_info = CertificateInfo(certPriv);
-
   return SignatureValidationInfo(priv);
 }
 
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index 2c973835..a1027625 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -1,6 +1,6 @@
 /* poppler-form.h: qt interface to poppler
  * Copyright (C) 2007-2008, Pino Toscano <pino at kde.org>
- * Copyright (C) 2008, 2011, 2016, 2017, Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2008, 2011, 2016, 2017, 2019, Albert Astals Cid <aacid at kde.org>
  * Copyright (C) 2012, Adam Reichold <adamreichold at myopera.com>
  * Copyright (C) 2016, Hanno Meyer-Thurow <h.mth at web.de>
  * Copyright (C) 2017, Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
@@ -452,7 +452,6 @@ namespace Poppler {
           Organization,
         };
 
-        CertificateInfo();
         CertificateInfo(CertificateInfoPrivate *priv);
         ~CertificateInfo();
 
commit 8e8c8417a724b3d12e310f9858d0bf02f1b49c7e
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Jan 5 19:48:41 2019 +0100

    Remove unneeded/leaky copyString calls
    
    the left hand is a std::string

diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index cafea66a..74d3eb83 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -6,7 +6,7 @@
 //
 // Copyright 2015, 2016 André Guerreiro <aguerreiro1985 at gmail.com>
 // Copyright 2015 André Esser <bepandre at hotmail.com>
-// Copyright 2015, 2016, 2018 Albert Astals Cid <aacid at kde.org>
+// Copyright 2015, 2016, 2018, 2019 Albert Astals Cid <aacid at kde.org>
 // Copyright 2015 Markus Kilås <digital at markuspage.com>
 // Copyright 2017 Sebastian Rasmussen <sebras at gmail.com>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
@@ -91,25 +91,25 @@ X509CertificateInfo::EntityInfo SignatureHandler::getEntityInfo(CERTName *entity
 
   char *dn = CERT_NameToAscii(entityName);
   if (dn) {
-      info.distinguishedName = copyString(dn);
+      info.distinguishedName = dn;
       PORT_Free(dn);
   }
 
   char *cn = CERT_GetCommonName(entityName);
   if (cn) {
-    info.commonName = copyString(cn);
+    info.commonName = cn;
     PORT_Free(cn);
   }
 
   char *email = CERT_GetCertEmailAddress(entityName);
   if (email) {
-    info.email = copyString(email);
+    info.email = email;
     PORT_Free(email);
   }
 
   char *org = CERT_GetOrgName(entityName);
   if (org) {
-    info.organization = copyString(org);
+    info.organization = org;
     PORT_Free(org);
   }
 
commit 7fde94de5bc8bcb83f347663abf4dd056a03837e
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Sat Oct 27 21:21:31 2018 +0200

    Make CertificateInfo a std::unique_ptr

diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index 1cbe0083..cafea66a 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -122,7 +122,7 @@ static GooString SECItemToGooString(const SECItem &secItem)
   return GooString((const char *)secItem.data, secItem.len);
 }
 
-X509CertificateInfo *SignatureHandler::getCertificateInfo() const
+std::unique_ptr<X509CertificateInfo> SignatureHandler::getCertificateInfo() const
 {
   if (!CMSSignerInfo)
     return nullptr;
@@ -131,7 +131,7 @@ X509CertificateInfo *SignatureHandler::getCertificateInfo() const
   if (!cert)
     return nullptr;
 
-  X509CertificateInfo *certInfo = new X509CertificateInfo;
+  auto certInfo = std::make_unique<X509CertificateInfo>();
 
   certInfo->setVersion(DER_GetInteger(&cert->version) + 1);
   certInfo->setSerialNumber(SECItemToGooString(cert->serialNumber));
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index 8302a28b..7b7665ab 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -47,7 +47,7 @@ public:
   NSSCMSVerificationStatus validateSignature();
   // Use -1 as validation_time for now
   SECErrorCodes validateCertificate(time_t validation_time);
-  X509CertificateInfo *getCertificateInfo() const;
+  std::unique_ptr<X509CertificateInfo> getCertificateInfo() const;
 
   //Translate NSS error codes
   static SignatureValidationStatus NSS_SigTranslate(NSSCMSVerificationStatus nss_code);
diff --git a/poppler/SignatureInfo.cc b/poppler/SignatureInfo.cc
index 73522857..b48ce146 100644
--- a/poppler/SignatureInfo.cc
+++ b/poppler/SignatureInfo.cc
@@ -63,7 +63,6 @@ SignatureInfo::~SignatureInfo()
   free(reason);
   free(signer_name);
   free(subject_dn);
-  delete cert_info;
 }
 
 /* GETTERS */
@@ -110,7 +109,7 @@ time_t SignatureInfo::getSigningTime()
 
 const X509CertificateInfo *SignatureInfo::getCertificateInfo() const
 {
-  return cert_info;
+  return cert_info.get();
 }
 
 /* SETTERS */
@@ -159,8 +158,7 @@ void SignatureInfo::setSigningTime(time_t signingTime)
   signing_time = signingTime;
 }
 
-void SignatureInfo::setCertificateInfo(X509CertificateInfo *certInfo)
+void SignatureInfo::setCertificateInfo(std::unique_ptr<X509CertificateInfo> certInfo)
 {
-  delete cert_info;
-  cert_info = certInfo;
+  cert_info = std::move(certInfo);
 }
diff --git a/poppler/SignatureInfo.h b/poppler/SignatureInfo.h
index f2708994..5728da56 100644
--- a/poppler/SignatureInfo.h
+++ b/poppler/SignatureInfo.h
@@ -16,6 +16,7 @@
 #ifndef SIGNATUREINFO_H
 #define SIGNATUREINFO_H
 
+#include <memory>
 #include <time.h>
 
 enum SignatureValidationStatus
@@ -70,7 +71,7 @@ public:
   void setHashAlgorithm(int);
   void setSigningTime(time_t);
   void setSubFilterSupport(bool isSupported) { sig_subfilter_supported = isSupported; }
-  void setCertificateInfo(X509CertificateInfo *);
+  void setCertificateInfo(std::unique_ptr<X509CertificateInfo>);
 
 private:
   SignatureInfo(const SignatureInfo &);
@@ -78,7 +79,7 @@ private:
 
   SignatureValidationStatus sig_status;
   CertificateValidationStatus cert_status;
-  X509CertificateInfo *cert_info;
+  std::unique_ptr<X509CertificateInfo> cert_info;
   char *signer_name;
   char *subject_dn;
   char *location;
commit 8943f7de0125152f20a64b8092ed516e08e6c1d9
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Sat Oct 27 21:09:29 2018 +0200

    Use std::string for the strings in EntityInfo

diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc
index 8d71ae0b..c33705c5 100644
--- a/poppler/CertificateInfo.cc
+++ b/poppler/CertificateInfo.cc
@@ -36,50 +36,13 @@ X509CertificateInfo::PublicKeyInfo &X509CertificateInfo::PublicKeyInfo::operator
   return *this;
 }
 
-X509CertificateInfo::EntityInfo::EntityInfo() :
-  commonName(nullptr),
-  distinguishedName(nullptr),
-  email(nullptr),
-  organization(nullptr)
-{
-}
+X509CertificateInfo::EntityInfo::EntityInfo() = default;
 
-X509CertificateInfo::EntityInfo::~EntityInfo()
-{
-  free(commonName);
-  free(distinguishedName);
-  free(email);
-  free(organization);
-}
+X509CertificateInfo::EntityInfo::~EntityInfo() = default;
 
-X509CertificateInfo::EntityInfo::EntityInfo(X509CertificateInfo::EntityInfo &&other)
-{
-  commonName = other.commonName;
-  distinguishedName = other.distinguishedName;
-  email = other.email;
-  organization = other.organization;
-  other.commonName = nullptr;
-  other.distinguishedName = nullptr;
-  other.email = nullptr;
-  other.organization = nullptr;
-}
+X509CertificateInfo::EntityInfo::EntityInfo(X509CertificateInfo::EntityInfo &&other) = default;
 
-X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo &&other)
-{
-  free(commonName);
-  free(distinguishedName);
-  free(email);
-  free(organization);
-  commonName = other.commonName;
-  distinguishedName = other.distinguishedName;
-  email = other.email;
-  organization = other.organization;
-  other.commonName = nullptr;
-  other.distinguishedName = nullptr;
-  other.email = nullptr;
-  other.organization = nullptr;
-  return *this;
-}
+X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo &&other) = default;
 
 X509CertificateInfo::X509CertificateInfo() :
   ku_extensions(KU_NONE),
diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
index 30b6204d..ec51e723 100644
--- a/poppler/CertificateInfo.h
+++ b/poppler/CertificateInfo.h
@@ -67,10 +67,10 @@ public:
     EntityInfo(const EntityInfo &) = delete;
     EntityInfo &operator=(const EntityInfo &) = delete;
 
-    char *commonName;
-    char *distinguishedName;
-    char *email;
-    char *organization;
+    std::string commonName;
+    std::string distinguishedName;
+    std::string email;
+    std::string organization;
   };
 
    struct Validity {
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index 7280c369..50425b86 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -953,16 +953,16 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
     certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
 
     const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
-    certPriv->issuer_info.common_name = issuerInfo.commonName;
-    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName;
-    certPriv->issuer_info.email_address = issuerInfo.email;
-    certPriv->issuer_info.org_name = issuerInfo.organization;
+    certPriv->issuer_info.common_name = issuerInfo.commonName.c_str();
+    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName.c_str();
+    certPriv->issuer_info.email_address = issuerInfo.email.c_str();
+    certPriv->issuer_info.org_name = issuerInfo.organization.c_str();
 
     const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
-    certPriv->subject_info.common_name = subjectInfo.commonName;
-    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName;
-    certPriv->subject_info.email_address = subjectInfo.email;
-    certPriv->subject_info.org_name = subjectInfo.organization;
+    certPriv->subject_info.common_name = subjectInfo.commonName.c_str();
+    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName.c_str();
+    certPriv->subject_info.email_address = subjectInfo.email.c_str();
+    certPriv->subject_info.org_name = subjectInfo.organization.c_str();
 
     X509CertificateInfo::Validity certValidity = ci->getValidity();
     certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
commit 0d3c6b4010629d92e7aee1a7486085d9e0ca711c
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Sat Oct 27 20:42:44 2018 +0200

    Use GooString for publicKey, cert_serial, cert_der

diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc
index e10bfddd..8d71ae0b 100644
--- a/poppler/CertificateInfo.cc
+++ b/poppler/CertificateInfo.cc
@@ -16,32 +16,23 @@
 #include <stdlib.h>
 
 X509CertificateInfo::PublicKeyInfo::PublicKeyInfo() :
-  publicKey(nullptr),
   publicKeyType(OTHERKEY),
   publicKeyStrength(0)
 {
 }
 
-X509CertificateInfo::PublicKeyInfo::~PublicKeyInfo()
-{
-  delete publicKey;
-}
-
 X509CertificateInfo::PublicKeyInfo::PublicKeyInfo(X509CertificateInfo::PublicKeyInfo &&other)
 {
-  publicKey = other.publicKey;
+  publicKey = std::move(other.publicKey);
   publicKeyType = other.publicKeyType;
   publicKeyStrength = other.publicKeyStrength;
-  other.publicKey = nullptr;
 }
 
 X509CertificateInfo::PublicKeyInfo &X509CertificateInfo::PublicKeyInfo::operator=(X509CertificateInfo::PublicKeyInfo &&other)
 {
-  delete publicKey;
-  publicKey = other.publicKey;
+  publicKey = std::move(other.publicKey);
   publicKeyType = other.publicKeyType;
   publicKeyStrength = other.publicKeyStrength;
-  other.publicKey = nullptr;
   return *this;
 }
 
@@ -91,19 +82,13 @@ X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509
 }
 
 X509CertificateInfo::X509CertificateInfo() :
-  cert_serial(nullptr),
-  cert_der(nullptr),
   ku_extensions(KU_NONE),
   cert_version(-1),
   is_self_signed(false)
 {
 }
 
-X509CertificateInfo::~X509CertificateInfo()
-{
-  delete cert_serial;
-  delete cert_der;
-}
+X509CertificateInfo::~X509CertificateInfo() = default;
 
 int X509CertificateInfo::getVersion() const
 {
@@ -112,7 +97,7 @@ int X509CertificateInfo::getVersion() const
 
 const GooString &X509CertificateInfo::getSerialNumber() const
 {
-  return *cert_serial;
+  return cert_serial;
 }
 
 const X509CertificateInfo::EntityInfo &X509CertificateInfo::getIssuerInfo() const
@@ -142,7 +127,7 @@ unsigned int X509CertificateInfo::getKeyUsageExtensions() const
 
 const GooString &X509CertificateInfo::getCertificateDER() const
 {
-  return *cert_der;
+  return cert_der;
 }
 
 bool X509CertificateInfo::getIsSelfSigned() const
@@ -155,10 +140,9 @@ void X509CertificateInfo::setVersion(int version)
   cert_version = version;
 }
 
-void X509CertificateInfo::setSerialNumber(GooString *serialNumber)
+void X509CertificateInfo::setSerialNumber(const GooString &serialNumber)
 {
-  delete cert_serial;
-  cert_serial = serialNumber;
+  cert_serial.Set(&serialNumber);
 }
 
 void X509CertificateInfo::setIssuerInfo(EntityInfo &&issuerInfo)
@@ -186,10 +170,9 @@ void X509CertificateInfo::setKeyUsageExtensions(unsigned int keyUsages)
   ku_extensions = keyUsages;
 }
 
-void X509CertificateInfo::setCertificateDER(GooString *certDer)
+void X509CertificateInfo::setCertificateDER(const GooString &certDer)
 {
-  delete cert_der;
-  cert_der = certDer;
+  cert_der.Set(&certDer);
 }
 
 void X509CertificateInfo::setIsSelfSigned(bool isSelfSigned)
diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
index 2fed9185..30b6204d 100644
--- a/poppler/CertificateInfo.h
+++ b/poppler/CertificateInfo.h
@@ -13,6 +13,7 @@
 #ifndef CERTIFICATEINFO_H
 #define CERTIFICATEINFO_H
 
+#include <memory>
 #include <time.h>
 #include "goo/GooString.h"
 
@@ -44,7 +45,6 @@ public:
 
   struct PublicKeyInfo {
     PublicKeyInfo();
-    ~PublicKeyInfo();
 
     PublicKeyInfo(PublicKeyInfo &&);
     PublicKeyInfo &operator=(PublicKeyInfo &&);
@@ -52,7 +52,7 @@ public:
     PublicKeyInfo(const PublicKeyInfo &) = delete;
     PublicKeyInfo &operator=(const PublicKeyInfo &) = delete;
 
-    GooString *publicKey;
+    GooString publicKey;
     PublicKeyType publicKeyType;
     unsigned int publicKeyStrength; // in bits
   };
@@ -93,13 +93,13 @@ public:
 
   /* SETTERS */
   void setVersion(int);
-  void setSerialNumber(GooString *);
+  void setSerialNumber(const GooString &);
   void setIssuerInfo(EntityInfo &&);
   void setValidity(Validity);
   void setSubjectInfo(EntityInfo &&);
   void setPublicKeyInfo(PublicKeyInfo &&);
   void setKeyUsageExtensions(unsigned int);
-  void setCertificateDER(GooString *);
+  void setCertificateDER(const GooString &);
   void setIsSelfSigned(bool);
 
 private:
@@ -110,8 +110,8 @@ private:
   EntityInfo subject_info;
   PublicKeyInfo public_key_info;
   Validity cert_validity;
-  GooString *cert_serial;
-  GooString *cert_der;
+  GooString cert_serial;
+  GooString cert_der;
   unsigned int ku_extensions;
   int cert_version;
   bool is_self_signed;
diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index 9c739d0d..1cbe0083 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -116,10 +116,10 @@ X509CertificateInfo::EntityInfo SignatureHandler::getEntityInfo(CERTName *entity
   return info;
 }
 
-static GooString *SECItemToGooString(const SECItem &secItem)
+static GooString SECItemToGooString(const SECItem &secItem)
 {
   // TODO do we need to handle secItem.type;
-  return new GooString((const char *)secItem.data, secItem.len);
+  return GooString((const char *)secItem.data, secItem.len);
 }
 
 X509CertificateInfo *SignatureHandler::getCertificateInfo() const
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index b5d1bb22..7280c369 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -969,7 +969,7 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
     certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);
 
     const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
-    certPriv->public_key = QByteArray(pkInfo.publicKey->c_str(), pkInfo.publicKey->getLength());
+    certPriv->public_key = QByteArray(pkInfo.publicKey.c_str(), pkInfo.publicKey.getLength());
     certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
     certPriv->public_key_strength = pkInfo.publicKeyStrength;
 
commit 119554432264010850250344c8c087c9f31216dc
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Fri Oct 26 21:02:56 2018 +0200

    Lots of changes to CertificateInfo memory handling

diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc
index dc786314..e10bfddd 100644
--- a/poppler/CertificateInfo.cc
+++ b/poppler/CertificateInfo.cc
@@ -5,6 +5,8 @@
 // This file is licensed under the GPLv2 or later
 //
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
+// Copyright 2018 Albert Astals Cid <aacid at kde.org>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -13,27 +15,94 @@
 #include <string.h>
 #include <stdlib.h>
 
-X509CertificateInfo::X509CertificateInfo()
+X509CertificateInfo::PublicKeyInfo::PublicKeyInfo() :
+  publicKey(nullptr),
+  publicKeyType(OTHERKEY),
+  publicKeyStrength(0)
+{
+}
+
+X509CertificateInfo::PublicKeyInfo::~PublicKeyInfo()
+{
+  delete publicKey;
+}
+
+X509CertificateInfo::PublicKeyInfo::PublicKeyInfo(X509CertificateInfo::PublicKeyInfo &&other)
+{
+  publicKey = other.publicKey;
+  publicKeyType = other.publicKeyType;
+  publicKeyStrength = other.publicKeyStrength;
+  other.publicKey = nullptr;
+}
+
+X509CertificateInfo::PublicKeyInfo &X509CertificateInfo::PublicKeyInfo::operator=(X509CertificateInfo::PublicKeyInfo &&other)
+{
+  delete publicKey;
+  publicKey = other.publicKey;
+  publicKeyType = other.publicKeyType;
+  publicKeyStrength = other.publicKeyStrength;
+  other.publicKey = nullptr;
+  return *this;
+}
+
+X509CertificateInfo::EntityInfo::EntityInfo() :
+  commonName(nullptr),
+  distinguishedName(nullptr),
+  email(nullptr),
+  organization(nullptr)
+{
+}
+
+X509CertificateInfo::EntityInfo::~EntityInfo()
+{
+  free(commonName);
+  free(distinguishedName);
+  free(email);
+  free(organization);
+}
+
+X509CertificateInfo::EntityInfo::EntityInfo(X509CertificateInfo::EntityInfo &&other)
+{
+  commonName = other.commonName;
+  distinguishedName = other.distinguishedName;
+  email = other.email;
+  organization = other.organization;
+  other.commonName = nullptr;
+  other.distinguishedName = nullptr;
+  other.email = nullptr;
+  other.organization = nullptr;
+}
+
+X509CertificateInfo::EntityInfo &X509CertificateInfo::EntityInfo::operator=(X509CertificateInfo::EntityInfo &&other)
+{
+  free(commonName);
+  free(distinguishedName);
+  free(email);
+  free(organization);
+  commonName = other.commonName;
+  distinguishedName = other.distinguishedName;
+  email = other.email;
+  organization = other.organization;
+  other.commonName = nullptr;
+  other.distinguishedName = nullptr;
+  other.email = nullptr;
+  other.organization = nullptr;
+  return *this;
+}
+
+X509CertificateInfo::X509CertificateInfo() :
+  cert_serial(nullptr),
+  cert_der(nullptr),
+  ku_extensions(KU_NONE),
+  cert_version(-1),
+  is_self_signed(false)
 {
-  memset(&issuer_info, 0, sizeof issuer_info);
-  memset(&subject_info, 0, sizeof subject_info);
-  cert_serial = nullptr;
-  cert_der = nullptr;
-  ku_extensions = KU_NONE;
-  cert_version = -1;
-  is_self_signed = false;
 }
 
 X509CertificateInfo::~X509CertificateInfo()
 {
-  free(issuer_info.commonName);
-  free(issuer_info.distinguishedName);
-  free(issuer_info.email);
-  free(issuer_info.organization);
-  free(subject_info.commonName);
-  free(subject_info.distinguishedName);
-  free(subject_info.email);
-  free(subject_info.organization);
+  delete cert_serial;
+  delete cert_der;
 }
 
 int X509CertificateInfo::getVersion() const
@@ -41,27 +110,27 @@ int X509CertificateInfo::getVersion() const
   return cert_version;
 }
 
-GooString *X509CertificateInfo::getSerialNumber() const
+const GooString &X509CertificateInfo::getSerialNumber() const
 {
-  return cert_serial;
+  return *cert_serial;
 }
 
-X509CertificateInfo::EntityInfo X509CertificateInfo::getIssuerInfo() const
+const X509CertificateInfo::EntityInfo &X509CertificateInfo::getIssuerInfo() const
 {
   return issuer_info;
 }
 
-X509CertificateInfo::Validity X509CertificateInfo::getValidity() const
+const X509CertificateInfo::Validity &X509CertificateInfo::getValidity() const
 {
   return cert_validity;
 }
 
-X509CertificateInfo::EntityInfo X509CertificateInfo::getSubjectInfo() const
+const X509CertificateInfo::EntityInfo &X509CertificateInfo::getSubjectInfo() const
 {
   return subject_info;
 }
 
-X509CertificateInfo::PublicKeyInfo X509CertificateInfo::getPublicKeyInfo() const
+const X509CertificateInfo::PublicKeyInfo &X509CertificateInfo::getPublicKeyInfo() const
 {
   return public_key_info;
 }
@@ -71,9 +140,9 @@ unsigned int X509CertificateInfo::getKeyUsageExtensions() const
   return ku_extensions;
 }
 
-GooString *X509CertificateInfo::getCertificateDER() const
+const GooString &X509CertificateInfo::getCertificateDER() const
 {
-  return cert_der;
+  return *cert_der;
 }
 
 bool X509CertificateInfo::getIsSelfSigned() const
@@ -88,12 +157,13 @@ void X509CertificateInfo::setVersion(int version)
 
 void X509CertificateInfo::setSerialNumber(GooString *serialNumber)
 {
+  delete cert_serial;
   cert_serial = serialNumber;
 }
 
-void X509CertificateInfo::setIssuerInfo(EntityInfo issuerInfo)
+void X509CertificateInfo::setIssuerInfo(EntityInfo &&issuerInfo)
 {
-  issuer_info = issuerInfo;
+  issuer_info = std::move(issuerInfo);
 }
 
 void X509CertificateInfo::setValidity(Validity validity)
@@ -101,14 +171,14 @@ void X509CertificateInfo::setValidity(Validity validity)
   cert_validity = validity;
 }
 
-void X509CertificateInfo::setSubjectInfo(EntityInfo subjectInfo)
+void X509CertificateInfo::setSubjectInfo(EntityInfo &&subjectInfo)
 {
-  subject_info = subjectInfo;
+  subject_info = std::move(subjectInfo);
 }
 
-void X509CertificateInfo::setPublicKeyInfo(PublicKeyInfo pkInfo)
+void X509CertificateInfo::setPublicKeyInfo(PublicKeyInfo &&pkInfo)
 {
-  public_key_info = pkInfo;
+  public_key_info = std::move(pkInfo);
 }
 
 void X509CertificateInfo::setKeyUsageExtensions(unsigned int keyUsages)
@@ -118,6 +188,7 @@ void X509CertificateInfo::setKeyUsageExtensions(unsigned int keyUsages)
 
 void X509CertificateInfo::setCertificateDER(GooString *certDer)
 {
+  delete cert_der;
   cert_der = certDer;
 }
 
diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
index b01fcf50..2fed9185 100644
--- a/poppler/CertificateInfo.h
+++ b/poppler/CertificateInfo.h
@@ -6,6 +6,7 @@
 //
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
 // Copyright 2018 Albert Astals Cid <aacid at kde.org>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -42,12 +43,30 @@ public:
   ~X509CertificateInfo();
 
   struct PublicKeyInfo {
+    PublicKeyInfo();
+    ~PublicKeyInfo();
+
+    PublicKeyInfo(PublicKeyInfo &&);
+    PublicKeyInfo &operator=(PublicKeyInfo &&);
+
+    PublicKeyInfo(const PublicKeyInfo &) = delete;
+    PublicKeyInfo &operator=(const PublicKeyInfo &) = delete;
+
     GooString *publicKey;
     PublicKeyType publicKeyType;
     unsigned int publicKeyStrength; // in bits
   };
 
   struct EntityInfo {
+    EntityInfo();
+    ~EntityInfo();
+
+    EntityInfo(EntityInfo &&);
+    EntityInfo &operator=(EntityInfo &&);
+
+    EntityInfo(const EntityInfo &) = delete;
+    EntityInfo &operator=(const EntityInfo &) = delete;
+
     char *commonName;
     char *distinguishedName;
     char *email;
@@ -55,28 +74,30 @@ public:
   };
 
    struct Validity {
+    Validity() : notBefore(0), notAfter(0) {}
+
     time_t notBefore;
     time_t notAfter;
   };
 
   /* GETTERS */
   int getVersion() const;
-  GooString *getSerialNumber() const;
-  EntityInfo getIssuerInfo() const;
-  Validity getValidity() const;
-  EntityInfo getSubjectInfo() const;
-  PublicKeyInfo getPublicKeyInfo() const;
+  const GooString &getSerialNumber() const;
+  const EntityInfo &getIssuerInfo() const;
+  const Validity &getValidity() const;
+  const EntityInfo &getSubjectInfo() const;
+  const PublicKeyInfo &getPublicKeyInfo() const;
   unsigned int getKeyUsageExtensions() const;
-  GooString *getCertificateDER() const;
+  const GooString &getCertificateDER() const;
   bool getIsSelfSigned() const;
 
   /* SETTERS */
   void setVersion(int);
   void setSerialNumber(GooString *);
-  void setIssuerInfo(EntityInfo);
+  void setIssuerInfo(EntityInfo &&);
   void setValidity(Validity);
-  void setSubjectInfo(EntityInfo);
-  void setPublicKeyInfo(PublicKeyInfo);
+  void setSubjectInfo(EntityInfo &&);
+  void setPublicKeyInfo(PublicKeyInfo &&);
   void setKeyUsageExtensions(unsigned int);
   void setCertificateDER(GooString *);
   void setIsSelfSigned(bool);
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 51caa4d4..77a52072 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -1271,7 +1271,7 @@ int FormFieldText::tokenizeDA(const GooString* da, GooList* daToks, const char*
         GooString* tok = new GooString(da, i, j - i);
         if (searchTok && !tok->cmp(searchTok))
           idx = daToks->getLength();
-	daToks->push_back(tok);
+        daToks->push_back(tok);
         i = j;
       }
     }
diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index 87ca8599..9c739d0d 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -11,6 +11,7 @@
 // Copyright 2017 Sebastian Rasmussen <sebras at gmail.com>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -81,39 +82,47 @@ time_t SignatureHandler::getSigningTime()
   return static_cast<time_t>(sTime/1000000);
 }
 
-void SignatureHandler::getEntityInfo(X509CertificateInfo::EntityInfo *info, CERTName *entityName)
+X509CertificateInfo::EntityInfo SignatureHandler::getEntityInfo(CERTName *entityName) const
 {
-  if (!info || !entityName)
-    return;
+  X509CertificateInfo::EntityInfo info;
 
-  memset(info, 0, sizeof *info);
+  if (!entityName)
+    return info;
 
   char *dn = CERT_NameToAscii(entityName);
   if (dn) {
-      info->distinguishedName = copyString(dn);
+      info.distinguishedName = copyString(dn);
       PORT_Free(dn);
   }
 
   char *cn = CERT_GetCommonName(entityName);
   if (cn) {
-    info->commonName = copyString(cn);
+    info.commonName = copyString(cn);
     PORT_Free(cn);
   }
 
   char *email = CERT_GetCertEmailAddress(entityName);
   if (email) {
-    info->email = copyString(email);
+    info.email = copyString(email);
     PORT_Free(email);
   }
 
   char *org = CERT_GetOrgName(entityName);
   if (org) {
-    info->organization = copyString(org);
+    info.organization = copyString(org);
     PORT_Free(org);
   }
+
+  return info;
+}
+
+static GooString *SECItemToGooString(const SECItem &secItem)
+{
+  // TODO do we need to handle secItem.type;
+  return new GooString((const char *)secItem.data, secItem.len);
 }
 
-X509CertificateInfo *SignatureHandler::getCertificateInfo()
+X509CertificateInfo *SignatureHandler::getCertificateInfo() const
 {
   if (!CMSSignerInfo)
     return nullptr;
@@ -123,16 +132,12 @@ X509CertificateInfo *SignatureHandler::getCertificateInfo()
     return nullptr;
 
   X509CertificateInfo *certInfo = new X509CertificateInfo;
-  if (!certInfo)
-    return nullptr;
 
   certInfo->setVersion(DER_GetInteger(&cert->version) + 1);
   certInfo->setSerialNumber(SECItemToGooString(cert->serialNumber));
 
   //issuer info
-  X509CertificateInfo::EntityInfo issuerInfo;
-  getEntityInfo(&issuerInfo, &cert->issuer);
-  certInfo->setIssuerInfo(issuerInfo);
+  certInfo->setIssuerInfo(getEntityInfo(&cert->issuer));
 
   //validity
   PRTime notBefore, notAfter;
@@ -143,9 +148,7 @@ X509CertificateInfo *SignatureHandler::getCertificateInfo()
   certInfo->setValidity(certValidity);
 
   //subject info
-  X509CertificateInfo::EntityInfo subjectInfo;
-  getEntityInfo(&subjectInfo, &cert->subject);
-  certInfo->setSubjectInfo(subjectInfo);
+  certInfo->setSubjectInfo(getEntityInfo(&cert->subject));
 
   //public key info
   X509CertificateInfo::PublicKeyInfo pkInfo;
@@ -170,7 +173,7 @@ X509CertificateInfo *SignatureHandler::getCertificateInfo()
       break;
   }
   pkInfo.publicKeyStrength = SECKEY_PublicKeyStrengthInBits(pk);
-  certInfo->setPublicKeyInfo(pkInfo);
+  certInfo->setPublicKeyInfo(std::move(pkInfo));
 
   certInfo->setKeyUsageExtensions(cert->keyUsage);
   certInfo->setCertificateDER(SECItemToGooString(cert->derCert));
@@ -473,8 +476,3 @@ CertificateValidationStatus SignatureHandler::NSS_CertTranslate(SECErrorCodes ns
       return CERTIFICATE_GENERIC_ERROR;
   }
 }
-
-GooString *SignatureHandler::SECItemToGooString(SECItem secItem)
-{
-  return new GooString((const char *)secItem.data, secItem.len);
-}
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index 5c47d24a..8302a28b 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -8,6 +8,8 @@
 // Copyright 2015 André Esser <bepandre at hotmail.com>
 // Copyright 2015, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
+// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -45,14 +47,12 @@ public:
   NSSCMSVerificationStatus validateSignature();
   // Use -1 as validation_time for now
   SECErrorCodes validateCertificate(time_t validation_time);
-  X509CertificateInfo *getCertificateInfo();
+  X509CertificateInfo *getCertificateInfo() const;
 
   //Translate NSS error codes
   static SignatureValidationStatus NSS_SigTranslate(NSSCMSVerificationStatus nss_code);
   static CertificateValidationStatus NSS_CertTranslate(SECErrorCodes nss_code);
 
-  static GooString *SECItemToGooString(SECItem secItem);
-
 private:
   SignatureHandler(const SignatureHandler &);
   SignatureHandler& operator=(const SignatureHandler &);
@@ -65,7 +65,7 @@ private:
   NSSCMSSignedData *CMS_SignedDataCreate(NSSCMSMessage * cms_msg);
   NSSCMSSignerInfo *CMS_SignerInfoCreate(NSSCMSSignedData * cms_sig_data);
   HASHContext * initHashContext();
-  void getEntityInfo(X509CertificateInfo::EntityInfo *info, CERTName *entityName);
+  X509CertificateInfo::EntityInfo getEntityInfo(CERTName *entityName) const;
 
   unsigned int hash_length;
   SECItem CMSitem;
diff --git a/poppler/SignatureInfo.cc b/poppler/SignatureInfo.cc
index 3be9160d..73522857 100644
--- a/poppler/SignatureInfo.cc
+++ b/poppler/SignatureInfo.cc
@@ -9,6 +9,7 @@
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
 // Copyright 2017, 2018 Albert Astals Cid <aacid at kde.org>
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -107,7 +108,7 @@ time_t SignatureInfo::getSigningTime()
   return signing_time;
 }
 
-X509CertificateInfo *SignatureInfo::getCertificateInfo()
+const X509CertificateInfo *SignatureInfo::getCertificateInfo() const
 {
   return cert_info;
 }
@@ -160,5 +161,6 @@ void SignatureInfo::setSigningTime(time_t signingTime)
 
 void SignatureInfo::setCertificateInfo(X509CertificateInfo *certInfo)
 {
+  delete cert_info;
   cert_info = certInfo;
 }
diff --git a/poppler/SignatureInfo.h b/poppler/SignatureInfo.h
index de790627..f2708994 100644
--- a/poppler/SignatureInfo.h
+++ b/poppler/SignatureInfo.h
@@ -9,6 +9,7 @@
 // Copyright 2015, 2017, 2018 Albert Astals Cid <aacid at kde.org>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+// Copyright 2018 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 //========================================================================
 
@@ -57,7 +58,7 @@ public:
   int getHashAlgorithm(); // Returns a NSS3 HASH_HashType or -1 if compiled without NSS3
   time_t getSigningTime();
   bool isSubfilterSupported() { return sig_subfilter_supported; }
-  X509CertificateInfo *getCertificateInfo();
+  const X509CertificateInfo *getCertificateInfo() const;
 
   /* SETTERS */
   void setSignatureValStatus(enum SignatureValidationStatus );
diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index 3794c9f2..b5d1bb22 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -8,6 +8,7 @@
  * Copyright (C) 2018, Andre Heinecke <aheinecke at intevation.de>
  * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info at kdab.com>. Work sponsored by the LiMux project of the city of Munich
  * Copyright (C) 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+ * Copyright (C) 2018 Oliver Sander <oliver.sander at tu-dresden.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -522,13 +523,20 @@ public:
   bool is_null;
 };
 
+CertificateInfo::CertificateInfo()
+  : d_ptr( nullptr )
+{
+}
+
 CertificateInfo::CertificateInfo(CertificateInfoPrivate* priv)
-  : d_ptr(priv)
-{}
+  : d_ptr( priv )
+{
+}
 
 CertificateInfo::CertificateInfo(const CertificateInfo &other)
-  : d_ptr( other.d_ptr )
-{}
+ : d_ptr( other.d_ptr )
+{
+}
 
 CertificateInfo::~CertificateInfo() = default;
 
@@ -675,7 +683,7 @@ class SignatureValidationInfoPrivate {
 public:
 	SignatureValidationInfo::SignatureStatus signature_status;
 	SignatureValidationInfo::CertificateStatus certificate_status;
-	QSharedPointer<CertificateInfo> cert_info;
+	CertificateInfo cert_info;
 
 	QByteArray signature;
 	QString signer_name;
@@ -807,7 +815,7 @@ bool SignatureValidationInfo::signsTotalDocument() const
 CertificateInfo SignatureValidationInfo::certificateInfo() const
 {
   Q_D(const SignatureValidationInfo);
-  return *(d->cert_info.data());
+  return d->cert_info;
 }
 
 SignatureValidationInfo &SignatureValidationInfo::operator=(const SignatureValidationInfo &other)
@@ -933,7 +941,7 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
   delete checkedSignature;
 
   // set certificate info
-  X509CertificateInfo* ci = si->getCertificateInfo();
+  const X509CertificateInfo *ci = si->getCertificateInfo();
   CertificateInfoPrivate* certPriv = new CertificateInfoPrivate;
   certPriv->is_null = true;
   if (ci)
@@ -941,16 +949,16 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
     certPriv->version = ci->getVersion();
     certPriv->ku_extensions = ci->getKeyUsageExtensions();
 
-    GooString *certSerial = ci->getSerialNumber();
-    certPriv->serial_number = QByteArray(certSerial->c_str(), certSerial->getLength());
+    const GooString &certSerial = ci->getSerialNumber();
+    certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());
 
-    X509CertificateInfo::EntityInfo issuerInfo = ci->getIssuerInfo();
+    const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
     certPriv->issuer_info.common_name = issuerInfo.commonName;
     certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName;
     certPriv->issuer_info.email_address = issuerInfo.email;
     certPriv->issuer_info.org_name = issuerInfo.organization;
 
-    X509CertificateInfo::EntityInfo subjectInfo = ci->getSubjectInfo();
+    const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
     certPriv->subject_info.common_name = subjectInfo.commonName;
     certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName;
     certPriv->subject_info.email_address = subjectInfo.email;
@@ -960,17 +968,17 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
     certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
     certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);
 
-    X509CertificateInfo::PublicKeyInfo pkInfo = ci->getPublicKeyInfo();
+    const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
     certPriv->public_key = QByteArray(pkInfo.publicKey->c_str(), pkInfo.publicKey->getLength());
     certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
     certPriv->public_key_strength = pkInfo.publicKeyStrength;
 
-    GooString *certDer = ci->getCertificateDER();
-    certPriv->certificate_der = QByteArray(certDer->c_str(), certDer->getLength());
+    const GooString &certDer = ci->getCertificateDER();
+    certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength());
 
     certPriv->is_null = false;
   }
-  priv->cert_info = QSharedPointer<CertificateInfo>(new CertificateInfo(certPriv));
+  priv->cert_info = CertificateInfo(certPriv);
 
   return SignatureValidationInfo(priv);
 }
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index b389e5bf..2c973835 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -7,6 +7,7 @@
  * Copyright (C) 2017, Tobias C. Berner <tcberner at freebsd.org>
  * Copyright (C) 2018, Andre Heinecke <aheinecke at intevation.de>
  * Copyright (C) 2018, Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
+ * Copyright (C) 2018, Oliver Sander <oliver.sander at tu-dresden.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -451,6 +452,7 @@ namespace Poppler {
           Organization,
         };
 
+        CertificateInfo();
         CertificateInfo(CertificateInfoPrivate *priv);
         ~CertificateInfo();
 
@@ -522,7 +524,7 @@ namespace Poppler {
         CertificateInfo(const CertificateInfo &other);
         CertificateInfo &operator=(const CertificateInfo &other);
 
-        private:
+    private:
         Q_DECLARE_PRIVATE(CertificateInfo)
 
         QSharedPointer<CertificateInfoPrivate> d_ptr;
@@ -643,17 +645,16 @@ namespace Poppler {
 
 	/**
 	  Checks whether the signature authenticates the total document
-          except for the signature itself.
-          \since 0.58
+	  except for the signature itself.
+	  \since 0.58
 	 */
         bool signsTotalDocument() const;
 
-        /**
-          The signer certificate info
-
-          \since 0.73
-         */
-        CertificateInfo certificateInfo() const;
+	/**
+	  The signer certificate info.
+	  \since 0.73
+	*/
+	CertificateInfo certificateInfo() const;
 
 	SignatureValidationInfo(const SignatureValidationInfo &other);
 	SignatureValidationInfo &operator=(const SignatureValidationInfo &other);
commit 0e2577ec4c3d08eac0b02a3e941d51082b2754c0
Author: Albert Astals Cid <aacid at kde.org>
Date:   Thu Oct 25 21:49:12 2018 +0200

    delete copy constructor and assignement

diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
index 3010d135..b01fcf50 100644
--- a/poppler/CertificateInfo.h
+++ b/poppler/CertificateInfo.h
@@ -5,6 +5,7 @@
 // This file is licensed under the GPLv2 or later
 //
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
+// Copyright 2018 Albert Astals Cid <aacid at kde.org>
 //
 //========================================================================
 
@@ -81,8 +82,8 @@ public:
   void setIsSelfSigned(bool);
 
 private:
-  X509CertificateInfo(const X509CertificateInfo &);
-  X509CertificateInfo& operator=(const X509CertificateInfo &);
+  X509CertificateInfo(const X509CertificateInfo &) = delete;
+  X509CertificateInfo& operator=(const X509CertificateInfo &) = delete;
 
   EntityInfo issuer_info;
   EntityInfo subject_info;
commit 5a12875cec4d544ea1ca2838fcf407bc2888dd10
Author: Albert Astals Cid <aacid at kde.org>
Date:   Thu Oct 25 21:38:44 2018 +0200

    Install the header file CertificateInfo.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4eb74a36..c74b9a15 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -546,6 +546,7 @@ if(ENABLE_UNSTABLE_API_ABI_HEADERS)
     poppler/PreScanOutputDev.h
     poppler/PSTokenizer.h
     poppler/Rendition.h
+    poppler/CertificateInfo.h
     poppler/Stream-CCITT.h
     poppler/Stream.h
     poppler/StructElement.h
commit 5d6e6f3d4ead5f098be84fffab5cc7d4bdefe38a
Author: Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
Date:   Tue Jul 17 17:47:34 2018 +0000

    Expose X509CertificateInfo in qt5 frontend

diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc
index 38ebf2df..3794c9f2 100644
--- a/qt5/src/poppler-form.cc
+++ b/qt5/src/poppler-form.cc
@@ -32,6 +32,7 @@
 #include <Object.h>
 #include <Link.h>
 #include <SignatureInfo.h>
+#include <CertificateInfo.h>
 
 #include "poppler-form.h"
 #include "poppler-page-private.h"
@@ -495,11 +496,186 @@ bool FormFieldChoice::canBeSpellChecked() const
   return !fwc->noSpellCheck();
 }
 
+class CertificateInfoPrivate
+{
+public:
+  struct EntityInfo
+  {
+    QString common_name;
+    QString email_address;
+    QString org_name;
+    QString distinguished_name;
+  };
+
+  EntityInfo issuer_info;
+  EntityInfo subject_info;
+  QByteArray certificate_der;
+  QByteArray serial_number;
+  QByteArray public_key;
+  QDateTime validity_start;
+  QDateTime validity_end;
+  int public_key_type;
+  int public_key_strength;
+  int ku_extensions;
+  int version;
+  bool is_self_signed;
+  bool is_null;
+};
+
+CertificateInfo::CertificateInfo(CertificateInfoPrivate* priv)
+  : d_ptr(priv)
+{}
+
+CertificateInfo::CertificateInfo(const CertificateInfo &other)
+  : d_ptr( other.d_ptr )
+{}
+
+CertificateInfo::~CertificateInfo() = default;
+
+CertificateInfo &CertificateInfo::operator=(const CertificateInfo &other)
+{
+  if ( this != &other )
+    d_ptr = other.d_ptr;
+
+  return *this;
+}
+
+bool CertificateInfo::isNull() const
+{
+  Q_D(const CertificateInfo);
+  return d->is_null;
+}
+
+int CertificateInfo::version() const
+{
+  Q_D(const CertificateInfo);
+  return d->version;
+}
+
+QByteArray CertificateInfo::serialNumber() const
+{
+  Q_D(const CertificateInfo);
+  return d->serial_number;
+}
+
+QString CertificateInfo::issuerInfo(EntityInfoKey key) const
+{
+  Q_D(const CertificateInfo);
+  switch (key)
+  {
+    case CommonName:
+      return d->issuer_info.common_name;
+    case DistinguishedName:
+      return d->issuer_info.distinguished_name;
+    case EmailAddress:
+      return d->issuer_info.email_address;
+    case Organization:
+      return d->issuer_info.org_name;
+    default:
+      return QString();
+  }
+}
+
+QString CertificateInfo::subjectInfo(EntityInfoKey key) const
+{
+  Q_D(const CertificateInfo);
+  switch (key)
+  {
+    case CommonName:
+      return d->subject_info.common_name;
+    case DistinguishedName:
+      return d->subject_info.distinguished_name;
+    case EmailAddress:
+      return d->subject_info.email_address;
+    case Organization:
+      return d->subject_info.org_name;
+    default:
+      return QString();
+  }
+}
+
+QDateTime CertificateInfo::validityStart() const
+{
+  Q_D(const CertificateInfo);
+  return d->validity_start;
+}
+
+QDateTime CertificateInfo::validityEnd() const
+{
+  Q_D(const CertificateInfo);
+  return d->validity_end;
+}
+
+CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const
+{
+  Q_D(const CertificateInfo);
+
+  KeyUsageExtensions kuExtensions = KuNone;
+  if (d->ku_extensions & KU_DIGITAL_SIGNATURE)
+    kuExtensions |= KuDigitalSignature;
+  if (d->ku_extensions & KU_NON_REPUDIATION)
+    kuExtensions |= KuNonRepudiation;
+  if (d->ku_extensions & KU_KEY_ENCIPHERMENT)
+    kuExtensions |= KuKeyEncipherment;
+  if (d->ku_extensions & KU_DATA_ENCIPHERMENT)
+    kuExtensions |= KuDataEncipherment;
+  if (d->ku_extensions & KU_KEY_AGREEMENT)
+    kuExtensions |= KuKeyAgreement;
+  if (d->ku_extensions & KU_KEY_CERT_SIGN)
+    kuExtensions |= KuKeyCertSign;
+  if (d->ku_extensions & KU_CRL_SIGN)
+    kuExtensions |= KuClrSign;
+  if (d->ku_extensions & KU_ENCIPHER_ONLY)
+    kuExtensions |= KuEncipherOnly;
+
+  return kuExtensions;
+}
+
+QByteArray CertificateInfo::publicKey() const
+{
+  Q_D(const CertificateInfo);
+  return d->public_key;
+}
+
+CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const
+{
+  Q_D(const CertificateInfo);
+  switch (d->public_key_type)
+  {
+    case RSAKEY:
+      return RsaKey;
+    case DSAKEY:
+      return DsaKey;
+    case ECKEY:
+      return EcKey;
+    default:
+      return OtherKey;
+  }
+}
+
+int CertificateInfo::publicKeyStrength() const
+{
+  Q_D(const CertificateInfo);
+  return d->public_key_strength;
+}
+
+bool CertificateInfo::isSelfSigned() const
+{
+  Q_D(const CertificateInfo);
+  return d->is_self_signed;
+}
+
+QByteArray CertificateInfo::certificateData() const
+{
+  Q_D(const CertificateInfo);
+  return d->certificate_der;
+}
 
 class SignatureValidationInfoPrivate {
 public:
 	SignatureValidationInfo::SignatureStatus signature_status;
 	SignatureValidationInfo::CertificateStatus certificate_status;
+	QSharedPointer<CertificateInfo> cert_info;
 
 	QByteArray signature;
 	QString signer_name;
@@ -628,6 +804,12 @@ bool SignatureValidationInfo::signsTotalDocument() const
   return false;
 }
 
+CertificateInfo SignatureValidationInfo::certificateInfo() const
+{
+  Q_D(const SignatureValidationInfo);
+  return *(d->cert_info.data());
+}
+
 SignatureValidationInfo &SignatureValidationInfo::operator=(const SignatureValidationInfo &other)
 {
   if ( this != &other )
@@ -750,6 +932,46 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
   }
   delete checkedSignature;
 
+  // set certificate info
+  X509CertificateInfo* ci = si->getCertificateInfo();
+  CertificateInfoPrivate* certPriv = new CertificateInfoPrivate;
+  certPriv->is_null = true;
+  if (ci)
+  {
+    certPriv->version = ci->getVersion();
+    certPriv->ku_extensions = ci->getKeyUsageExtensions();
+
+    GooString *certSerial = ci->getSerialNumber();
+    certPriv->serial_number = QByteArray(certSerial->c_str(), certSerial->getLength());
+
+    X509CertificateInfo::EntityInfo issuerInfo = ci->getIssuerInfo();
+    certPriv->issuer_info.common_name = issuerInfo.commonName;
+    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName;
+    certPriv->issuer_info.email_address = issuerInfo.email;
+    certPriv->issuer_info.org_name = issuerInfo.organization;
+
+    X509CertificateInfo::EntityInfo subjectInfo = ci->getSubjectInfo();
+    certPriv->subject_info.common_name = subjectInfo.commonName;
+    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName;
+    certPriv->subject_info.email_address = subjectInfo.email;
+    certPriv->subject_info.org_name = subjectInfo.organization;
+
+    X509CertificateInfo::Validity certValidity = ci->getValidity();
+    certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
+    certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);
+
+    X509CertificateInfo::PublicKeyInfo pkInfo = ci->getPublicKeyInfo();
+    certPriv->public_key = QByteArray(pkInfo.publicKey->c_str(), pkInfo.publicKey->getLength());
+    certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
+    certPriv->public_key_strength = pkInfo.publicKeyStrength;
+
+    GooString *certDer = ci->getCertificateDER();
+    certPriv->certificate_der = QByteArray(certDer->c_str(), certDer->getLength());
+
+    certPriv->is_null = false;
+  }
+  priv->cert_info = QSharedPointer<CertificateInfo>(new CertificateInfo(certPriv));
+
   return SignatureValidationInfo(priv);
 }
 
diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h
index 6e715bb8..b389e5bf 100644
--- a/qt5/src/poppler-form.h
+++ b/qt5/src/poppler-form.h
@@ -404,6 +404,132 @@ namespace Poppler {
     };
 
     /**
+      A helper class to store x509 certificate information.
+
+      \since 0.73
+     */
+    class CertificateInfoPrivate;
+    class POPPLER_QT5_EXPORT CertificateInfo {
+    public:
+
+        /**
+          The algorithm of public key.
+         */
+        enum PublicKeyType
+        {
+            RsaKey,
+            DsaKey,
+            EcKey,
+            OtherKey
+        };
+
+        /**
+          Certificate key usage extensions.
+         */
+        enum KeyUsageExtension
+        {
+            KuDigitalSignature = 0x80,
+            KuNonRepudiation   = 0x40,
+            KuKeyEncipherment  = 0x20,
+            KuDataEncipherment = 0x10,
+            KuKeyAgreement     = 0x08,
+            KuKeyCertSign      = 0x04,
+            KuClrSign          = 0x02,
+            KuEncipherOnly     = 0x01,
+            KuNone             = 0x00
+        };
+        Q_DECLARE_FLAGS(KeyUsageExtensions, KeyUsageExtension)
+
+        /**
+          Predefined keys for elements in an entity's distinguished name.
+         */
+        enum EntityInfoKey
+        {
+          CommonName,
+          DistinguishedName,
+          EmailAddress,
+          Organization,
+        };
+
+        CertificateInfo(CertificateInfoPrivate *priv);
+        ~CertificateInfo();
+
+        /**
+          Returns true if certificate has no contents; otherwise returns false
+         */
+        bool isNull() const;
+
+        /**
+          The certificate version string.
+         */
+        int version() const;
+
+        /**
+          The certificate serial number.
+         */
+        QByteArray serialNumber() const;
+
+        /**
+          Information about the issuer.
+         */
+        QString issuerInfo(EntityInfoKey key) const;
+
+        /**
+          Information about the subject
+         */
+        QString subjectInfo(EntityInfoKey key) const;
+
+        /**
+          The date-time when certificate becomes valid.
+         */
+        QDateTime validityStart() const;
+
+        /**
+          The date-time when certificate expires.
+         */
+        QDateTime validityEnd() const;
+
+        /**
+          The uses allowed for the certificate.
+         */
+        KeyUsageExtensions keyUsageExtensions() const;
+
+        /**
+          The public key value.
+         */
+        QByteArray publicKey() const;
+
+        /**
+          The public key type.
+         */
+        PublicKeyType publicKeyType() const;
+
+        /**
+          The strength of public key in bits.
+         */
+        int publicKeyStrength() const;
+
+        /**
+          Returns true if certificate is self-signed otherwise returns false.
+         */
+        bool isSelfSigned() const;
+
+        /**
+          The DER encoded certificate.
+         */
+        QByteArray certificateData() const;
+
+        CertificateInfo(const CertificateInfo &other);
+        CertificateInfo &operator=(const CertificateInfo &other);
+
+        private:
+        Q_DECLARE_PRIVATE(CertificateInfo)
+
+        QSharedPointer<CertificateInfoPrivate> d_ptr;
+    };
+    Q_DECLARE_OPERATORS_FOR_FLAGS(CertificateInfo::KeyUsageExtensions)
+
+    /**
       A signature validation info helper class.
 
       \since 0.51
@@ -522,6 +648,13 @@ namespace Poppler {
 	 */
         bool signsTotalDocument() const;
 
+        /**
+          The signer certificate info
+
+          \since 0.73
+         */
+        CertificateInfo certificateInfo() const;
+
 	SignatureValidationInfo(const SignatureValidationInfo &other);
 	SignatureValidationInfo &operator=(const SignatureValidationInfo &other);
 
commit a6944a73286032c2c434f78325531cdf9d3a0de2
Author: Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
Date:   Tue Jul 17 18:18:30 2018 +0000

    Add X509CertificateInfo to poppler

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6aaaa767..4eb74a36 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -395,6 +395,7 @@ set(poppler_SRCS
   poppler/ViewerPreferences.cc
   poppler/Movie.cc
   poppler/Rendition.cc
+  poppler/CertificateInfo.cc
 )
 set(poppler_LIBS ${FREETYPE_LIBRARIES})
 if(ENABLE_SPLASH)
diff --git a/poppler/CertificateInfo.cc b/poppler/CertificateInfo.cc
new file mode 100644
index 00000000..dc786314
--- /dev/null
+++ b/poppler/CertificateInfo.cc
@@ -0,0 +1,127 @@
+//========================================================================
+//
+// CertificateInfo.cc
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
+//
+//========================================================================
+
+#include "CertificateInfo.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+X509CertificateInfo::X509CertificateInfo()
+{
+  memset(&issuer_info, 0, sizeof issuer_info);
+  memset(&subject_info, 0, sizeof subject_info);
+  cert_serial = nullptr;
+  cert_der = nullptr;
+  ku_extensions = KU_NONE;
+  cert_version = -1;
+  is_self_signed = false;
+}
+
+X509CertificateInfo::~X509CertificateInfo()
+{
+  free(issuer_info.commonName);
+  free(issuer_info.distinguishedName);
+  free(issuer_info.email);
+  free(issuer_info.organization);
+  free(subject_info.commonName);
+  free(subject_info.distinguishedName);
+  free(subject_info.email);
+  free(subject_info.organization);
+}
+
+int X509CertificateInfo::getVersion() const
+{
+  return cert_version;
+}
+
+GooString *X509CertificateInfo::getSerialNumber() const
+{
+  return cert_serial;
+}
+
+X509CertificateInfo::EntityInfo X509CertificateInfo::getIssuerInfo() const
+{
+  return issuer_info;
+}
+
+X509CertificateInfo::Validity X509CertificateInfo::getValidity() const
+{
+  return cert_validity;
+}
+
+X509CertificateInfo::EntityInfo X509CertificateInfo::getSubjectInfo() const
+{
+  return subject_info;
+}
+
+X509CertificateInfo::PublicKeyInfo X509CertificateInfo::getPublicKeyInfo() const
+{
+  return public_key_info;
+}
+
+unsigned int X509CertificateInfo::getKeyUsageExtensions() const
+{
+  return ku_extensions;
+}
+
+GooString *X509CertificateInfo::getCertificateDER() const
+{
+  return cert_der;
+}
+
+bool X509CertificateInfo::getIsSelfSigned() const
+{
+  return is_self_signed;
+}
+
+void X509CertificateInfo::setVersion(int version)
+{
+  cert_version = version;
+}
+
+void X509CertificateInfo::setSerialNumber(GooString *serialNumber)
+{
+  cert_serial = serialNumber;
+}
+
+void X509CertificateInfo::setIssuerInfo(EntityInfo issuerInfo)
+{
+  issuer_info = issuerInfo;
+}
+
+void X509CertificateInfo::setValidity(Validity validity)
+{
+  cert_validity = validity;
+}
+
+void X509CertificateInfo::setSubjectInfo(EntityInfo subjectInfo)
+{
+  subject_info = subjectInfo;
+}
+
+void X509CertificateInfo::setPublicKeyInfo(PublicKeyInfo pkInfo)
+{
+  public_key_info = pkInfo;
+}
+
+void X509CertificateInfo::setKeyUsageExtensions(unsigned int keyUsages)
+{
+  ku_extensions = keyUsages;
+}
+
+void X509CertificateInfo::setCertificateDER(GooString *certDer)
+{
+  cert_der = certDer;
+}
+
+void X509CertificateInfo::setIsSelfSigned(bool isSelfSigned)
+{
+  is_self_signed = isSelfSigned;
+}
diff --git a/poppler/CertificateInfo.h b/poppler/CertificateInfo.h
new file mode 100644
index 00000000..3010d135
--- /dev/null
+++ b/poppler/CertificateInfo.h
@@ -0,0 +1,98 @@
+//========================================================================
+//
+// CertificateInfo.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at gmail.com>
+//
+//========================================================================
+
+#ifndef CERTIFICATEINFO_H
+#define CERTIFICATEINFO_H
+
+#include <time.h>
+#include "goo/GooString.h"
+
+enum CertificateKeyUsageExtension
+{
+  KU_DIGITAL_SIGNATURE = 0x80,
+  KU_NON_REPUDIATION   = 0x40,
+  KU_KEY_ENCIPHERMENT  = 0x20,
+  KU_DATA_ENCIPHERMENT = 0x10,
+  KU_KEY_AGREEMENT     = 0x08,
+  KU_KEY_CERT_SIGN     = 0x04,
+  KU_CRL_SIGN          = 0x02,
+  KU_ENCIPHER_ONLY     = 0x01,
+  KU_NONE              = 0x00
+};
+
+enum PublicKeyType
+{
+  RSAKEY,
+  DSAKEY,
+  ECKEY,
+  OTHERKEY
+};
+
+class X509CertificateInfo {
+public:
+  X509CertificateInfo();
+  ~X509CertificateInfo();
+
+  struct PublicKeyInfo {
+    GooString *publicKey;
+    PublicKeyType publicKeyType;
+    unsigned int publicKeyStrength; // in bits
+  };
+
+  struct EntityInfo {
+    char *commonName;
+    char *distinguishedName;
+    char *email;
+    char *organization;
+  };
+
+   struct Validity {
+    time_t notBefore;
+    time_t notAfter;
+  };
+
+  /* GETTERS */
+  int getVersion() const;
+  GooString *getSerialNumber() const;
+  EntityInfo getIssuerInfo() const;
+  Validity getValidity() const;
+  EntityInfo getSubjectInfo() const;
+  PublicKeyInfo getPublicKeyInfo() const;
+  unsigned int getKeyUsageExtensions() const;
+  GooString *getCertificateDER() const;
+  bool getIsSelfSigned() const;
+
+  /* SETTERS */
+  void setVersion(int);
+  void setSerialNumber(GooString *);
+  void setIssuerInfo(EntityInfo);
+  void setValidity(Validity);
+  void setSubjectInfo(EntityInfo);
+  void setPublicKeyInfo(PublicKeyInfo);
+  void setKeyUsageExtensions(unsigned int);
+  void setCertificateDER(GooString *);
+  void setIsSelfSigned(bool);
+
+private:
+  X509CertificateInfo(const X509CertificateInfo &);
+  X509CertificateInfo& operator=(const X509CertificateInfo &);
+
+  EntityInfo issuer_info;
+  EntityInfo subject_info;
+  PublicKeyInfo public_key_info;
+  Validity cert_validity;
+  GooString *cert_serial;
+  GooString *cert_der;
+  unsigned int ku_extensions;
+  int cert_version;
+  bool is_self_signed;
+};
+
+#endif
diff --git a/poppler/Form.cc b/poppler/Form.cc
index fc4ce88b..51caa4d4 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -1761,6 +1761,7 @@ SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool for
 
   cert_val_state = signature_handler.validateCertificate(validationTime);
   signature_info->setCertificateValStatus(SignatureHandler::NSS_CertTranslate(cert_val_state));
+  signature_info->setCertificateInfo(signature_handler.getCertificateInfo());
 
 #endif
   return signature_info;
diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index 116aab99..87ca8599 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -10,6 +10,7 @@
 // Copyright 2015 Markus Kilås <digital at markuspage.com>
 // Copyright 2017 Sebastian Rasmussen <sebras at gmail.com>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
+// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
 //
 //========================================================================
 
@@ -18,6 +19,8 @@
 #include "SignatureHandler.h"
 #include "goo/gmem.h"
 #include <secmod.h>
+#include <keyhi.h>
+#include <secder.h>
 
 #include <dirent.h>
 #include <Error.h>
@@ -78,6 +81,104 @@ time_t SignatureHandler::getSigningTime()
   return static_cast<time_t>(sTime/1000000);
 }
 
+void SignatureHandler::getEntityInfo(X509CertificateInfo::EntityInfo *info, CERTName *entityName)
+{
+  if (!info || !entityName)
+    return;
+
+  memset(info, 0, sizeof *info);
+
+  char *dn = CERT_NameToAscii(entityName);
+  if (dn) {
+      info->distinguishedName = copyString(dn);
+      PORT_Free(dn);
+  }
+
+  char *cn = CERT_GetCommonName(entityName);
+  if (cn) {
+    info->commonName = copyString(cn);
+    PORT_Free(cn);
+  }
+
+  char *email = CERT_GetCertEmailAddress(entityName);
+  if (email) {
+    info->email = copyString(email);
+    PORT_Free(email);
+  }
+
+  char *org = CERT_GetOrgName(entityName);
+  if (org) {
+    info->organization = copyString(org);
+    PORT_Free(org);
+  }
+}
+
+X509CertificateInfo *SignatureHandler::getCertificateInfo()
+{
+  if (!CMSSignerInfo)
+    return nullptr;
+
+  CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());
+  if (!cert)
+    return nullptr;
+
+  X509CertificateInfo *certInfo = new X509CertificateInfo;
+  if (!certInfo)
+    return nullptr;
+
+  certInfo->setVersion(DER_GetInteger(&cert->version) + 1);
+  certInfo->setSerialNumber(SECItemToGooString(cert->serialNumber));
+
+  //issuer info
+  X509CertificateInfo::EntityInfo issuerInfo;
+  getEntityInfo(&issuerInfo, &cert->issuer);
+  certInfo->setIssuerInfo(issuerInfo);
+
+  //validity
+  PRTime notBefore, notAfter;
+  CERT_GetCertTimes(cert, &notBefore, &notAfter);
+  X509CertificateInfo::Validity certValidity;
+  certValidity.notBefore = static_cast<time_t>(notBefore/1000000);
+  certValidity.notAfter = static_cast<time_t>(notAfter/1000000);
+  certInfo->setValidity(certValidity);
+
+  //subject info
+  X509CertificateInfo::EntityInfo subjectInfo;
+  getEntityInfo(&subjectInfo, &cert->subject);
+  certInfo->setSubjectInfo(subjectInfo);
+
+  //public key info
+  X509CertificateInfo::PublicKeyInfo pkInfo;
+  SECKEYPublicKey *pk = CERT_ExtractPublicKey(cert);
+  switch (pk->keyType)
+  {
+    case rsaKey:
+      pkInfo.publicKey = SECItemToGooString(pk->u.rsa.modulus);
+      pkInfo.publicKeyType = RSAKEY;
+      break;
+    case dsaKey:
+      pkInfo.publicKey = SECItemToGooString(pk->u.dsa.publicValue);
+      pkInfo.publicKeyType = DSAKEY;
+      break;
+    case ecKey:
+      pkInfo.publicKey = SECItemToGooString(pk->u.ec.publicValue);
+      pkInfo.publicKeyType = ECKEY;
+      break;
+    default:
+      pkInfo.publicKey = SECItemToGooString(cert->subjectPublicKeyInfo.subjectPublicKey);
+      pkInfo.publicKeyType = OTHERKEY;
+      break;
+  }
+  pkInfo.publicKeyStrength = SECKEY_PublicKeyStrengthInBits(pk);
+  certInfo->setPublicKeyInfo(pkInfo);
+
+  certInfo->setKeyUsageExtensions(cert->keyUsage);
+  certInfo->setCertificateDER(SECItemToGooString(cert->derCert));
+  certInfo->setIsSelfSigned(CERT_CompareName(&cert->subject, &cert->issuer) == SECEqual);
+
+  return certInfo;
+}
+
 
 GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux()
 {
@@ -96,9 +197,9 @@ GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux()
   do {
     if ((subFolder = readdir(toSearchIn)) != nullptr) {
       if (strstr(subFolder->d_name, "default") != nullptr) {
-	finalPath = homePath->append(subFolder->d_name);
-	closedir(toSearchIn);
-	return finalPath;
+        finalPath = homePath->append(subFolder->d_name);
+        closedir(toSearchIn);
+        return finalPath;
       }
     }
   } while (subFolder != nullptr);
@@ -111,7 +212,7 @@ GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux()
 /**
  * Initialise NSS
  */
-void SignatureHandler::init_nss() 
+void SignatureHandler::init_nss()
 {
   GooString *certDBPath = getDefaultFirefoxCertDB_Linux();
   bool initSuccess = false;
@@ -372,3 +473,8 @@ CertificateValidationStatus SignatureHandler::NSS_CertTranslate(SECErrorCodes ns
       return CERTIFICATE_GENERIC_ERROR;
   }
 }
+
+GooString *SignatureHandler::SECItemToGooString(SECItem secItem)
+{
+  return new GooString((const char *)secItem.data, secItem.len);
+}
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index 3b2f62b9..5c47d24a 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -16,6 +16,7 @@
 
 #include "goo/GooString.h"
 #include "SignatureInfo.h"
+#include "CertificateInfo.h"
 
 /* NSPR Headers */
 #include <nspr.h>
@@ -44,11 +45,14 @@ public:
   NSSCMSVerificationStatus validateSignature();
   // Use -1 as validation_time for now
   SECErrorCodes validateCertificate(time_t validation_time);
+  X509CertificateInfo *getCertificateInfo();
 
   //Translate NSS error codes
   static SignatureValidationStatus NSS_SigTranslate(NSSCMSVerificationStatus nss_code);
   static CertificateValidationStatus NSS_CertTranslate(SECErrorCodes nss_code);
 
+  static GooString *SECItemToGooString(SECItem secItem);
+
 private:
   SignatureHandler(const SignatureHandler &);
   SignatureHandler& operator=(const SignatureHandler &);
@@ -61,6 +65,7 @@ private:
   NSSCMSSignedData *CMS_SignedDataCreate(NSSCMSMessage * cms_msg);
   NSSCMSSignerInfo *CMS_SignerInfoCreate(NSSCMSSignedData * cms_sig_data);
   HASHContext * initHashContext();
+  void getEntityInfo(X509CertificateInfo::EntityInfo *info, CERTName *entityName);
 
   unsigned int hash_length;
   SECItem CMSitem;
diff --git a/poppler/SignatureInfo.cc b/poppler/SignatureInfo.cc
index 11e47e5b..3be9160d 100644
--- a/poppler/SignatureInfo.cc
+++ b/poppler/SignatureInfo.cc
@@ -15,6 +15,7 @@
 #include <config.h>
 
 #include "SignatureInfo.h"
+#include "CertificateInfo.h"
 #include "goo/gmem.h"
 #include <stdlib.h>
 #include <string.h>
@@ -31,6 +32,7 @@ SignatureInfo::SignatureInfo()
 {
   sig_status = SIGNATURE_NOT_VERIFIED;
   cert_status = CERTIFICATE_NOT_VERIFIED;
+  cert_info = nullptr;
   signer_name = nullptr;
   subject_dn = nullptr;
   location = nullptr;
@@ -44,6 +46,7 @@ SignatureInfo::SignatureInfo(SignatureValidationStatus sig_val_status, Certifica
 {
   sig_status = sig_val_status;
   cert_status = cert_val_status;
+  cert_info = nullptr;
   signer_name = nullptr;
   subject_dn = nullptr;
   location = nullptr;
@@ -59,6 +62,7 @@ SignatureInfo::~SignatureInfo()
   free(reason);
   free(signer_name);
   free(subject_dn);
+  delete cert_info;
 }
 
 /* GETTERS */
@@ -103,6 +107,11 @@ time_t SignatureInfo::getSigningTime()
   return signing_time;
 }
 
+X509CertificateInfo *SignatureInfo::getCertificateInfo()
+{
+  return cert_info;
+}
+
 /* SETTERS */
 
 void SignatureInfo::setSignatureValStatus(enum SignatureValidationStatus sig_val_status)
@@ -148,3 +157,8 @@ void SignatureInfo::setSigningTime(time_t signingTime)
 {
   signing_time = signingTime;
 }
+
+void SignatureInfo::setCertificateInfo(X509CertificateInfo *certInfo)
+{
+  cert_info = certInfo;
+}
diff --git a/poppler/SignatureInfo.h b/poppler/SignatureInfo.h
index f4554c60..de790627 100644
--- a/poppler/SignatureInfo.h
+++ b/poppler/SignatureInfo.h
@@ -39,6 +39,8 @@ enum CertificateValidationStatus
   CERTIFICATE_NOT_VERIFIED
 };
 
+class X509CertificateInfo;
+
 class SignatureInfo {
 public:
   SignatureInfo();
@@ -55,6 +57,7 @@ public:
   int getHashAlgorithm(); // Returns a NSS3 HASH_HashType or -1 if compiled without NSS3
   time_t getSigningTime();
   bool isSubfilterSupported() { return sig_subfilter_supported; }
+  X509CertificateInfo *getCertificateInfo();
 
   /* SETTERS */
   void setSignatureValStatus(enum SignatureValidationStatus );
@@ -66,6 +69,7 @@ public:
   void setHashAlgorithm(int);
   void setSigningTime(time_t);
   void setSubFilterSupport(bool isSupported) { sig_subfilter_supported = isSupported; }
+  void setCertificateInfo(X509CertificateInfo *);
 
 private:
   SignatureInfo(const SignatureInfo &);
@@ -73,6 +77,7 @@ private:
 
   SignatureValidationStatus sig_status;
   CertificateValidationStatus cert_status;
+  X509CertificateInfo *cert_info;
   char *signer_name;
   char *subject_dn;
   char *location;


More information about the poppler mailing list