"Fossies" - the Fresh Open Source Software Archive

Member "poppler-0.82.0/utils/pdfsig.cc" (25 Oct 2019, 8416 Bytes) of package /linux/misc/poppler-0.82.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pdfsig.cc" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.76.1_vs_0.77.0.

    1 //========================================================================
    2 //
    3 // pdfsig.cc
    4 //
    5 // This file is licensed under the GPLv2 or later
    6 //
    7 // Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
    8 // Copyright 2015 André Esser <bepandre@hotmail.com>
    9 // Copyright 2015, 2017-2019 Albert Astals Cid <aacid@kde.org>
   10 // Copyright 2016 Markus Kilås <digital@markuspage.com>
   11 // Copyright 2017, 2019 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
   12 // Copyright 2017, 2019 Adrian Johnson <ajohnson@redneon.com>
   13 // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com>
   14 // Copyright 2019 Alexey Pavlov <alexpux@gmail.com>
   15 //
   16 //========================================================================
   17 
   18 #include "config.h"
   19 #include <poppler-config.h>
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <stddef.h>
   23 #include <string.h>
   24 #include <time.h>
   25 #include <hasht.h>
   26 #include <fstream>
   27 #include "parseargs.h"
   28 #include "Object.h"
   29 #include "Array.h"
   30 #include "goo/gbasename.h"
   31 #include "Page.h"
   32 #include "PDFDoc.h"
   33 #include "PDFDocFactory.h"
   34 #include "Error.h"
   35 #include "GlobalParams.h"
   36 #include "SignatureHandler.h"
   37 #include "SignatureInfo.h"
   38 #include "Win32Console.h"
   39 #include "numberofcharacters.h"
   40 #include <libgen.h>
   41 
   42 static const char * getReadableSigState(SignatureValidationStatus sig_vs)
   43 {
   44   switch(sig_vs) {
   45     case SIGNATURE_VALID:
   46       return "Signature is Valid.";
   47 
   48     case SIGNATURE_INVALID:
   49       return "Signature is Invalid.";
   50 
   51     case SIGNATURE_DIGEST_MISMATCH:
   52       return "Digest Mismatch.";
   53 
   54     case SIGNATURE_DECODING_ERROR:
   55       return "Document isn't signed or corrupted data.";
   56 
   57     case SIGNATURE_NOT_VERIFIED:
   58       return "Signature has not yet been verified.";
   59 
   60     default:
   61       return "Unknown Validation Failure.";
   62   }
   63 }
   64 
   65 static const char * getReadableCertState(CertificateValidationStatus cert_vs)
   66 {
   67   switch(cert_vs) {
   68     case CERTIFICATE_TRUSTED:
   69       return "Certificate is Trusted.";
   70 
   71     case CERTIFICATE_UNTRUSTED_ISSUER:
   72       return "Certificate issuer isn't Trusted.";
   73 
   74     case CERTIFICATE_UNKNOWN_ISSUER:
   75       return "Certificate issuer is unknown.";
   76 
   77     case CERTIFICATE_REVOKED:
   78       return "Certificate has been Revoked.";
   79 
   80     case CERTIFICATE_EXPIRED:
   81       return "Certificate has Expired";
   82 
   83     case CERTIFICATE_NOT_VERIFIED:
   84       return "Certificate has not yet been verified.";
   85 
   86     default:
   87       return "Unknown issue with Certificate or corrupted data.";
   88   }
   89 }
   90 
   91 static char *getReadableTime(time_t unix_time)
   92 {
   93   char * time_str = (char *) gmalloc(64);
   94   strftime(time_str, 64, "%b %d %Y %H:%M:%S", localtime(&unix_time));
   95   return time_str;
   96 }
   97 
   98 static void dumpSignature(int sig_num, int sigCount, FormWidgetSignature *sig_widget, const char *filename)
   99 {
  100     const GooString *signature = sig_widget->getSignature();
  101     if (!signature) {
  102         printf("Cannot dump signature #%d\n", sig_num);
  103         return;
  104     }
  105 
  106     const int sigCountLength = numberOfCharacters(sigCount);
  107     // We want format to be {0:s}.sig{1:Xd} where X is sigCountLength
  108     // since { is the magic character to replace things we need to put it twice where
  109     // we don't want it to be replaced
  110     GooString *format = GooString::format("{{0:s}}.sig{{1:{0:d}d}}", sigCountLength);
  111     GooString *path = GooString::format(format->c_str(), gbasename(filename).c_str(), sig_num);
  112     printf("Signature #%d (%u bytes) => %s\n", sig_num, signature->getLength(), path->c_str());
  113     std::ofstream outfile(path->c_str(), std::ofstream::binary);
  114     outfile.write(signature->c_str(), signature->getLength());
  115     outfile.close();
  116     delete format;
  117     delete path;
  118 }
  119 
  120 static GooString nssDir;
  121 static bool printVersion = false;
  122 static bool printHelp = false;
  123 static bool dontVerifyCert = false;
  124 static bool dumpSignatures = false;
  125 
  126 static const ArgDesc argDesc[] = {
  127   {"-nssdir", argGooString, &nssDir,     0,
  128    "path to directory of libnss3 database"},
  129   {"-nocert", argFlag,     &dontVerifyCert,     0,
  130    "don't perform certificate validation"},
  131   {"-dump",   argFlag,     &dumpSignatures,     0,
  132    "dump all signatures into current directory"},
  133 
  134   {"-v",      argFlag,     &printVersion,  0,
  135    "print copyright and version info"},
  136   {"-h",      argFlag,     &printHelp,     0,
  137    "print usage information"},
  138   {"-help",   argFlag,     &printHelp,     0,
  139    "print usage information"},
  140   {"-?",      argFlag,     &printHelp,     0,
  141    "print usage information"},
  142   {}
  143 };
  144 
  145 
  146 int main(int argc, char *argv[])
  147 {
  148   PDFDoc *doc = nullptr;
  149   unsigned int sigCount;
  150   GooString * fileName = nullptr;
  151   SignatureInfo *sig_info = nullptr;
  152   char *time_str = nullptr;
  153   std::vector<FormWidgetSignature*> sig_widgets;
  154   globalParams = new GlobalParams();
  155 
  156   Win32Console win32Console(&argc, &argv);
  157   int exitCode = 99;
  158   bool ok;
  159 
  160   ok = parseArgs(argDesc, &argc, argv);
  161 
  162   if (!ok || argc != 2 || printVersion || printHelp) {
  163     fprintf(stderr, "pdfsig version %s\n", PACKAGE_VERSION);
  164     fprintf(stderr, "%s\n", popplerCopyright);
  165     fprintf(stderr, "%s\n", xpdfCopyright);
  166     if (!printVersion) {
  167       printUsage("pdfsig", "<PDF-file>", argDesc);
  168     }
  169     if (printVersion || printHelp)
  170       exitCode = 0;
  171     goto end;
  172   }
  173 
  174   fileName = new GooString(argv[argc - 1]);
  175 
  176   SignatureHandler::setNSSDir(nssDir);
  177 
  178   // open PDF file
  179   doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr);
  180 
  181   if (!doc->isOk()) {
  182     exitCode = 1;
  183     goto end;
  184   }
  185 
  186   sig_widgets = doc->getSignatureWidgets();
  187   sigCount = sig_widgets.size();
  188 
  189   if (sigCount >= 1) {
  190     if (dumpSignatures) {
  191       printf("Dumping Signatures: %u\n", sigCount);
  192       for (unsigned int i = 0; i < sigCount; i++) {
  193         dumpSignature(i, sigCount, sig_widgets.at(i), fileName->c_str());
  194       }
  195       goto end;
  196     } else {
  197       printf("Digital Signature Info of: %s\n", fileName->c_str());
  198     }
  199   } else {
  200     printf("File '%s' does not contain any signatures\n", fileName->c_str());
  201     exitCode = 2;
  202     goto end;
  203   }
  204 
  205   for (unsigned int i = 0; i < sigCount; i++) {
  206     sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
  207     printf("Signature #%u:\n", i+1);
  208     printf("  - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
  209     printf("  - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
  210     printf("  - Signing Time: %s\n", time_str = getReadableTime(sig_info->getSigningTime()));
  211     printf("  - Signing Hash Algorithm: ");
  212     switch (sig_info->getHashAlgorithm())
  213     {
  214       case HASH_AlgMD2:
  215         printf("MD2\n");
  216         break;
  217       case HASH_AlgMD5:
  218         printf("MD5\n");
  219         break;
  220       case HASH_AlgSHA1:
  221         printf("SHA1\n");
  222         break;
  223       case HASH_AlgSHA256:
  224         printf("SHA-256\n");
  225         break;
  226       case HASH_AlgSHA384:
  227         printf("SHA-384\n");
  228         break;
  229       case HASH_AlgSHA512:
  230         printf("SHA-512\n");
  231         break;
  232       case HASH_AlgSHA224:
  233         printf("SHA-224\n");
  234         break;
  235       default:
  236         printf("unknown\n");
  237     }
  238     printf("  - Signature Type: ");
  239     switch (sig_widgets.at(i)->signatureType())
  240     {
  241       case adbe_pkcs7_sha1:
  242         printf("adbe.pkcs7.sha1\n");
  243         break;
  244       case adbe_pkcs7_detached:
  245         printf("adbe.pkcs7.detached\n");
  246         break;
  247       case ETSI_CAdES_detached:
  248         printf("ETSI.CAdES.detached\n");
  249         break;
  250       default:
  251         printf("unknown\n");
  252     }
  253     std::vector<Goffset> ranges = sig_widgets.at(i)->getSignedRangeBounds();
  254     if (ranges.size() == 4)
  255     {
  256       printf("  - Signed Ranges: [%lld - %lld], [%lld - %lld]\n",
  257              ranges[0], ranges[1], ranges[2], ranges[3]);
  258       Goffset checked_file_size;
  259       GooString* signature = sig_widgets.at(i)->getCheckedSignature(&checked_file_size);
  260       if (signature && checked_file_size == ranges[3]) {
  261         printf("  - Total document signed\n");
  262       } else {
  263         printf("  - Not total document signed\n");
  264       }
  265       delete signature;
  266     }
  267     printf("  - Signature Validation: %s\n", getReadableSigState(sig_info->getSignatureValStatus()));
  268     gfree(time_str);
  269     if (sig_info->getSignatureValStatus() != SIGNATURE_VALID || dontVerifyCert) {
  270       continue;
  271     }
  272     printf("  - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
  273   }
  274 
  275   exitCode = 0;
  276 
  277 end:
  278   delete fileName;
  279   delete doc;
  280   delete globalParams;
  281 
  282   return exitCode;
  283 }