[poppler] poppler/SignatureHandler.cc poppler/SignatureHandler.h poppler/SignatureInfo.cc utils/pdfsig.1 utils/pdfsig.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 24 14:41:28 UTC 2019


 poppler/SignatureHandler.cc |   56 +++++++++++++++++++++++++++++---------------
 poppler/SignatureHandler.h  |    9 ++++---
 poppler/SignatureInfo.cc    |    4 +--
 utils/pdfsig.1              |   15 ++++++++++-
 utils/pdfsig.cc             |   12 +++++++--
 5 files changed, 68 insertions(+), 28 deletions(-)

New commits:
commit 7486e4995d66f1a8676f3e65e408e8cdab049f6b
Author: Albert Astals Cid <aacid at kde.org>
Date:   Wed Jan 16 22:56:42 2019 +0100

    pdfsig: add -nssdir option
    
    Contains code inspired in code by Hans-Ulrich Jüttner and Adrian Johnson

diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index f616afbb..18033b48 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -45,7 +45,7 @@ unsigned int SignatureHandler::digestLength(SECOidTag digestAlgId)
 
 char *SignatureHandler::getSignerName()
 {
-  if (!CMSSignerInfo)
+  if (!CMSSignerInfo || !NSS_IsInitialized())
       return nullptr;
 
   CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());
@@ -182,8 +182,7 @@ std::unique_ptr<X509CertificateInfo> SignatureHandler::getCertificateInfo() cons
   return certInfo;
 }
 
-
-GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux()
+static GooString *getDefaultFirefoxCertDB_Linux()
 {
   GooString * finalPath = nullptr;
   DIR *toSearchIn;
@@ -215,27 +214,45 @@ GooString *SignatureHandler::getDefaultFirefoxCertDB_Linux()
 /**
  * Initialise NSS
  */
-void SignatureHandler::init_nss()
+void SignatureHandler::setNSSDir(const GooString &nssDir)
 {
-  GooString *certDBPath = getDefaultFirefoxCertDB_Linux();
+  static bool setNssDirCalled = false;
+
+  if (NSS_IsInitialized() && nssDir.getLength() > 0) {
+    error(errInternal, 0, "You need to call setNSSDir before signature validation related operations happen");
+    return;
+  }
+
+  if (setNssDirCalled)
+    return;
+
+  setNssDirCalled = true;
+
   bool initSuccess = false;
-  if (certDBPath == nullptr) {
-    initSuccess = (NSS_Init("sql:/etc/pki/nssdb") == SECSuccess);
+  if (nssDir.getLength() > 0) {
+    initSuccess = (NSS_Init(nssDir.c_str()) == SECSuccess);
   } else {
-    initSuccess = (NSS_Init(certDBPath->c_str()) == SECSuccess);
-  }
-  if (!initSuccess) {
-    GooString homeNssDb(getenv("HOME"));
-    homeNssDb.append("/.pki/nssdb");
-    initSuccess = (NSS_Init(homeNssDb.c_str()) == SECSuccess);
+    GooString *certDBPath = getDefaultFirefoxCertDB_Linux();
+    if (certDBPath == nullptr) {
+      initSuccess = (NSS_Init("sql:/etc/pki/nssdb") == SECSuccess);
+    } else {
+      initSuccess = (NSS_Init(certDBPath->c_str()) == SECSuccess);
+    }
     if (!initSuccess) {
-      NSS_NoDB_Init(nullptr);
+      GooString homeNssDb(getenv("HOME"));
+      homeNssDb.append("/.pki/nssdb");
+      initSuccess = (NSS_Init(homeNssDb.c_str()) == SECSuccess);
+      if (!initSuccess) {
+	NSS_NoDB_Init(nullptr);
+      }
     }
+    delete certDBPath;
   }
-  //Make sure NSS root certificates module is loaded
-  SECMOD_AddNewModule("Root Certs", "libnssckbi.so", 0, 0);
 
-  delete certDBPath;
+  if (initSuccess) {
+    //Make sure NSS root certificates module is loaded
+    SECMOD_AddNewModule("Root Certs", "libnssckbi.so", 0, 0);
+  }
 }
 
 
@@ -246,7 +263,7 @@ SignatureHandler::SignatureHandler(unsigned char *p7, int p7_length)
    CMSSignerInfo(nullptr),
    temp_certs(nullptr)
 {
-  init_nss();
+  setNSSDir({});
   CMSitem.data = p7;
   CMSitem.len = p7_length;
   CMSMessage = CMS_MessageCreate(&CMSitem);
@@ -377,6 +394,9 @@ SignatureValidationStatus SignatureHandler::validateSignature()
   if (!CMSSignedData)
     return SIGNATURE_GENERIC_ERROR;
 
+  if (!NSS_IsInitialized())
+    return SIGNATURE_GENERIC_ERROR;
+
   digest_buffer = (unsigned char *)PORT_Alloc(hash_length);
   unsigned int result_len = 0;
 
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index f49d4286..40ca990c 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -49,13 +49,16 @@ public:
   CertificateValidationStatus validateCertificate(time_t validation_time);
   std::unique_ptr<X509CertificateInfo> getCertificateInfo() const;
 
+  // Initializes the NSS dir with the custom given directory
+  // calling it with an empty string means use the default firefox db, /etc/pki/nssdb, ~/.pki/nssdb
+  // If you don't want a custom NSS dir and the default entries are fine for you, not calling this function is fine
+  // If wanted, this has to be called before doing signature validation calls
+  static void setNSSDir(const GooString &nssDir);
+
 private:
   SignatureHandler(const SignatureHandler &);
   SignatureHandler& operator=(const SignatureHandler &);
 
-  void init_nss();
-
-  GooString * getDefaultFirefoxCertDB_Linux();
   unsigned int digestLength(SECOidTag digestAlgId);
   NSSCMSMessage *CMS_MessageCreate(SECItem * cms_item);
   NSSCMSSignedData *CMS_SignedDataCreate(NSSCMSMessage * cms_msg);
diff --git a/poppler/SignatureInfo.cc b/poppler/SignatureInfo.cc
index b48ce146..3ab6f91f 100644
--- a/poppler/SignatureInfo.cc
+++ b/poppler/SignatureInfo.cc
@@ -7,7 +7,7 @@
 // Copyright 2015 André Guerreiro <aguerreiro1985 at gmail.com>
 // Copyright 2015 André Esser <bepandre at hotmail.com>
 // Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
-// Copyright 2017, 2018 Albert Astals Cid <aacid at kde.org>
+// Copyright 2017-2019 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>
 //
@@ -133,7 +133,7 @@ void SignatureInfo::setSignerName(char *signerName)
 void SignatureInfo::setSubjectDN(const char *subjectDN)
 {
   free(subject_dn);
-  subject_dn = strdup(subjectDN);
+  subject_dn = subjectDN ? strdup(subjectDN) : nullptr;
 }
 
 void SignatureInfo::setLocation(const char *loc)
diff --git a/utils/pdfsig.1 b/utils/pdfsig.1
index 0a5cc62d..3567e96c 100644
--- a/utils/pdfsig.1
+++ b/utils/pdfsig.1
@@ -15,13 +15,23 @@ the time and date of the signature, the hash algorithm used for signing,
 the type of the signature as stated in the PDF and
 the signed ranges with a statement wether the total document is signed.
 .PP
-The signer certificate validation uses the trusted certificates stored in the following locations:
+The signer certificate validation uses the trusted certificates stored in the
+Network Security Services (NSS) Database. The NSS Database is searched for in the following locations:
 .IP \(bu
-The NSS Certificate database in the default Firefox profile.
+If the \-nssdir option is specified, the directory specified by this option.
+.IP \(bu
+The NSS Certificate database in the default Firefox profile. i.e. $HOME/.mozilla/firefox/*.default.
 .IP \(bu
 The NSS Certificate database in /etc/pki/nssdb.
 .SH OPTIONS
 .TP
+.B \-nssdir "[prefix]directory"
+Specify the database directory containing the certificate and key
+database files. See certutil(1) -d option for details of the
+prefix. If not specified the other search locations described in
+.B DESCRIPTION
+are used.
+.TP
 .B \-nocert
 Do not validate the certificate.
 .TP
@@ -52,3 +62,4 @@ and copyright 2005-2015 The Poppler Developers - http://poppler.freedesktop.org
 .BR pdftotext (1)
 .BR pdfseparate (1),
 .BR pdfunite (1)
+.BR certutil (1)
diff --git a/utils/pdfsig.cc b/utils/pdfsig.cc
index 82c0616b..64299690 100644
--- a/utils/pdfsig.cc
+++ b/utils/pdfsig.cc
@@ -6,10 +6,10 @@
 //
 // Copyright 2015 André Guerreiro <aguerreiro1985 at gmail.com>
 // Copyright 2015 André Esser <bepandre at hotmail.com>
-// Copyright 2015, 2017, 2018 Albert Astals Cid <aacid at kde.org>
+// Copyright 2015, 2017-2019 Albert Astals Cid <aacid at kde.org>
 // Copyright 2016 Markus Kilås <digital at markuspage.com>
-// Copyright 2017 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
-// Copyright 2017 Adrian Johnson <ajohnson at redneon.com>
+// Copyright 2017, 2019 Hans-Ulrich Jüttner <huj at froreich-bioscientia.de>
+// Copyright 2017, 2019 Adrian Johnson <ajohnson at redneon.com>
 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65 at protonmail.com>
 // Copyright 2019 Alexey Pavlov <alexpux at gmail.com>
 //
@@ -33,6 +33,7 @@
 #include "PDFDocFactory.h"
 #include "Error.h"
 #include "GlobalParams.h"
+#include "SignatureHandler.h"
 #include "SignatureInfo.h"
 #include "Win32Console.h"
 #include "numberofcharacters.h"
@@ -118,12 +119,15 @@ static void dumpSignature(int sig_num, int sigCount, FormWidgetSignature *sig_wi
     delete path;
 }
 
+static GooString nssDir;
 static bool printVersion = false;
 static bool printHelp = false;
 static bool dontVerifyCert = false;
 static bool dumpSignatures = false;
 
 static const ArgDesc argDesc[] = {
+  {"-nssdir", argGooString, &nssDir,     0,
+   "path to directory of libnss3 database"},
   {"-nocert", argFlag,     &dontVerifyCert,     0,
    "don't perform certificate validation"},
   {"-dump",   argFlag,     &dumpSignatures,     0,
@@ -171,6 +175,8 @@ int main(int argc, char *argv[])
 
   fileName = new GooString(argv[argc - 1]);
 
+  SignatureHandler::setNSSDir(nssDir);
+
   // open PDF file
   doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr);
 


More information about the poppler mailing list