//========================================================================
//
// pdfsig.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2015, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright 2016 Markus Kilås <digital@markuspage.com>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
//
//========================================================================

#include "config.h"
#include <poppler-config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <time.h>
#include <hasht.h>
#include "parseargs.h"
#include "Object.h"
#include "Array.h"
#include "Page.h"
#include "PDFDoc.h"
#include "PDFDocFactory.h"
#include "Error.h"
#include "GlobalParams.h"
#include "SignatureInfo.h"
#include "Win32Console.h"

static const char * getReadableSigState(SignatureValidationStatus sig_vs)
{
  switch(sig_vs) {
    case SIGNATURE_VALID:
      return "Signature is Valid.";

    case SIGNATURE_INVALID:
      return "Signature is Invalid.";

    case SIGNATURE_DIGEST_MISMATCH:
      return "Digest Mismatch.";

    case SIGNATURE_DECODING_ERROR:
      return "Document isn't signed or corrupted data.";

    case SIGNATURE_NOT_VERIFIED:
      return "Signature has not yet been verified.";

    default:
      return "Unknown Validation Failure.";
  }
}

static const char * getReadableCertState(CertificateValidationStatus cert_vs)
{
  switch(cert_vs) {
    case CERTIFICATE_TRUSTED:
      return "Certificate is Trusted.";

    case CERTIFICATE_UNTRUSTED_ISSUER:
      return "Certificate issuer isn't Trusted.";

    case CERTIFICATE_UNKNOWN_ISSUER:
      return "Certificate issuer is unknown.";

    case CERTIFICATE_REVOKED:
      return "Certificate has been Revoked.";

    case CERTIFICATE_EXPIRED:
      return "Certificate has Expired";

    case CERTIFICATE_NOT_VERIFIED:
      return "Certificate has not yet been verified.";

    default:
      return "Unknown issue with Certificate or corrupted data.";
  }
}

static char *getReadableTime(time_t unix_time)
{
  char * time_str = (char *) gmalloc(64);
  strftime(time_str, 64, "%b %d %Y %H:%M:%S", localtime(&unix_time));
  return time_str;
}

static GBool printVersion = gFalse;
static GBool printHelp = gFalse;
static GBool dontVerifyCert = gFalse;

static const ArgDesc argDesc[] = {
  {"-nocert", argFlag,     &dontVerifyCert,     0,
   "don't perform certificate validation"},

  {"-v",      argFlag,     &printVersion,  0,
   "print copyright and version info"},
  {"-h",      argFlag,     &printHelp,     0,
   "print usage information"},
  {"-help",   argFlag,     &printHelp,     0,
   "print usage information"},
  {"-?",      argFlag,     &printHelp,     0,
   "print usage information"},
  {}
};


int main(int argc, char *argv[])
{
  PDFDoc *doc = nullptr;
  unsigned int sigCount;
  GooString * fileName = nullptr;
  SignatureInfo *sig_info = nullptr;
  char *time_str = nullptr;
  std::vector<FormWidgetSignature*> sig_widgets;
  globalParams = new GlobalParams();

  Win32Console win32Console(&argc, &argv);
  int exitCode = 99;
  GBool ok;

  ok = parseArgs(argDesc, &argc, argv);

  if (!ok || argc != 2 || printVersion || printHelp) {
    fprintf(stderr, "pdfsig version %s\n", PACKAGE_VERSION);
    fprintf(stderr, "%s\n", popplerCopyright);
    fprintf(stderr, "%s\n", xpdfCopyright);
    if (!printVersion) {
      printUsage("pdfsig", "<PDF-file>", argDesc);
    }
    if (printVersion || printHelp)
      exitCode = 0;
    goto end;
  }

  fileName = new GooString(argv[argc - 1]);

  // open PDF file
  doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr);

  if (!doc->isOk()) {
    exitCode = 1;
    goto end;
  }

  sig_widgets = doc->getSignatureWidgets();
  sigCount = sig_widgets.size();

  if (sigCount >= 1) {
    printf("Digital Signature Info of: %s\n", fileName->getCString());
  } else {
    printf("File '%s' does not contain any signatures\n", fileName->getCString());
    exitCode = 2;
    goto end;
  }

  for (unsigned int i = 0; i < sigCount; i++) {
    sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
    printf("Signature #%u:\n", i+1);
    printf("  - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
    printf("  - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
    printf("  - Signing Time: %s\n", time_str = getReadableTime(sig_info->getSigningTime()));
    printf("  - Signing Hash Algorithm: ");
    switch (sig_info->getHashAlgorithm())
    {
      case HASH_AlgMD2:
        printf("MD2\n");
        break;
      case HASH_AlgMD5:
        printf("MD5\n");
        break;
      case HASH_AlgSHA1:
        printf("SHA1\n");
        break;
      case HASH_AlgSHA256:
        printf("SHA-256\n");
        break;
      case HASH_AlgSHA384:
        printf("SHA-384\n");
        break;
      case HASH_AlgSHA512:
        printf("SHA-512\n");
        break;
      case HASH_AlgSHA224:
        printf("SHA-224\n");
        break;
      default:
        printf("unknown\n");
    }
    printf("  - Signature Type: ");
    switch (sig_widgets.at(i)->signatureType())
    {
      case adbe_pkcs7_sha1:
        printf("adbe.pkcs7.sha1\n");
        break;
      case adbe_pkcs7_detached:
        printf("adbe.pkcs7.detached\n");
        break;
      case ETSI_CAdES_detached:
        printf("ETSI.CAdES.detached\n");
        break;
      default:
        printf("unknown\n");
    }
    std::vector<Goffset> ranges = sig_widgets.at(i)->getSignedRangeBounds();
    if (ranges.size() == 4)
    {
      printf("  - Signed Ranges: [%lld - %lld], [%lld - %lld]\n",
             ranges[0], ranges[1], ranges[2], ranges[3]);
      Goffset checked_file_size;
      GooString* signature = sig_widgets.at(i)->getCheckedSignature(&checked_file_size);
      if (signature && checked_file_size == ranges[3])
      {
        printf("  - Total document signed\n");
        delete signature;
      }
      else
        printf("  - Not total document signed\n");
    }
    printf("  - Signature Validation: %s\n", getReadableSigState(sig_info->getSignatureValStatus()));
    gfree(time_str);
    if (sig_info->getSignatureValStatus() != SIGNATURE_VALID || dontVerifyCert) {
      continue;
    }
    printf("  - Certificate Validation: %s\n", getReadableCertState(sig_info->getCertificateValStatus()));
  }

  exitCode = 0;

end:
  delete globalParams;
  delete fileName;
  delete doc;

  return exitCode;
}
