//========================================================================
//
// SignatureHandler.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2015, 2016 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2015, 2016, 2018, 2019 Albert Astals Cid <aacid@kde.org>
// Copyright 2015 Markus Kilås <digital@markuspage.com>
// Copyright 2017 Sebastian Rasmussen <sebras@gmail.com>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
// Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com>
// Copyright 2018 Oliver Sander <oliver.sander@tu-dresden.de>
//
//========================================================================

#include <config.h>

#include "SignatureHandler.h"
#include "goo/gmem.h"
#include <secmod.h>
#include <keyhi.h>
#include <secder.h>

#include <dirent.h>
#include <Error.h>

unsigned int SignatureHandler::digestLength(SECOidTag digestAlgId)
{
  switch(digestAlgId){
    case SEC_OID_SHA1:
      return 20;
    case SEC_OID_SHA256:
      return 32;
    case SEC_OID_SHA384:
      return 48;
    case SEC_OID_SHA512:
      return 64;
    default:
      printf("ERROR: Unrecognized Hash ID\n");
      return 0;
  }
}

char *SignatureHandler::getSignerName()
{
  if (!CMSSignerInfo || !NSS_IsInitialized())
      return nullptr;

  CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());

  if (!cert)
      return nullptr;

  return CERT_GetCommonName(&cert->subject);
}

const char * SignatureHandler::getSignerSubjectDN()
{
  if (!CMSSignerInfo)
    return nullptr;

  CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());
  if (!cert)
    return nullptr;
  return cert->subjectName;
}

HASH_HashType SignatureHandler::getHashAlgorithm()
{
  if (hash_context && hash_context->hashobj)
  {
    return hash_context->hashobj->type;
  }
  return HASH_AlgNULL;
}

time_t SignatureHandler::getSigningTime()
{
  PRTime sTime; // time in microseconds since the epoch

  if (NSS_CMSSignerInfo_GetSigningTime (CMSSignerInfo, &sTime) != SECSuccess)
    return 0;

  return static_cast<time_t>(sTime/1000000);
}

X509CertificateInfo::EntityInfo SignatureHandler::getEntityInfo(CERTName *entityName) const
{
  X509CertificateInfo::EntityInfo info;

  if (!entityName)
    return info;

  char *dn = CERT_NameToAscii(entityName);
  if (dn) {
      info.distinguishedName = dn;
      PORT_Free(dn);
  }

  char *cn = CERT_GetCommonName(entityName);
  if (cn) {
    info.commonName = cn;
    PORT_Free(cn);
  }

  char *email = CERT_GetCertEmailAddress(entityName);
  if (email) {
    info.email = email;
    PORT_Free(email);
  }

  char *org = CERT_GetOrgName(entityName);
  if (org) {
    info.organization = org;
    PORT_Free(org);
  }

  return info;
}

static GooString SECItemToGooString(const SECItem &secItem)
{
  // TODO do we need to handle secItem.type;
  return GooString((const char *)secItem.data, secItem.len);
}

std::unique_ptr<X509CertificateInfo> SignatureHandler::getCertificateInfo() const
{
  if (!CMSSignerInfo)
    return nullptr;

  CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());
  if (!cert)
    return nullptr;

  auto certInfo = std::make_unique<X509CertificateInfo>();

  certInfo->setVersion(DER_GetInteger(&cert->version) + 1);
  certInfo->setSerialNumber(SECItemToGooString(cert->serialNumber));

  //issuer info
  certInfo->setIssuerInfo(getEntityInfo(&cert->issuer));

  //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
  certInfo->setSubjectInfo(getEntityInfo(&cert->subject));

  //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(std::move(pkInfo));

  certInfo->setKeyUsageExtensions(cert->keyUsage);
  certInfo->setCertificateDER(SECItemToGooString(cert->derCert));
  certInfo->setIsSelfSigned(CERT_CompareName(&cert->subject, &cert->issuer) == SECEqual);

  return certInfo;
}

static GooString *getDefaultFirefoxCertDB_Linux()
{
  GooString * finalPath = nullptr;
  DIR *toSearchIn;
  struct dirent *subFolder;

  GooString * homePath = new GooString(getenv("HOME"));
  homePath = homePath->append("/.mozilla/firefox/");

  if ((toSearchIn = opendir(homePath->c_str())) == nullptr) {
    error(errInternal, 0, "couldn't find default Firefox Folder");
    delete homePath;
    return nullptr;
  }
  do {
    if ((subFolder = readdir(toSearchIn)) != nullptr) {
      if (strstr(subFolder->d_name, "default") != nullptr) {
        finalPath = homePath->append(subFolder->d_name);
        closedir(toSearchIn);
        return finalPath;
      }
    }
  } while (subFolder != nullptr);

  closedir(toSearchIn);
  delete homePath;
  return nullptr;
}

/**
 * Initialise NSS
 */
void SignatureHandler::setNSSDir(const GooString &nssDir)
{
  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 (nssDir.getLength() > 0) {
    initSuccess = (NSS_Init(nssDir.c_str()) == SECSuccess);
  } else {
    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) {
      GooString homeNssDb(getenv("HOME"));
      homeNssDb.append("/.pki/nssdb");
      initSuccess = (NSS_Init(homeNssDb.c_str()) == SECSuccess);
      if (!initSuccess) {
	NSS_NoDB_Init(nullptr);
      }
    }
    delete certDBPath;
  }

  if (initSuccess) {
    //Make sure NSS root certificates module is loaded
    SECMOD_AddNewModule("Root Certs", "libnssckbi.so", 0, 0);
  }
}


SignatureHandler::SignatureHandler(unsigned char *p7, int p7_length)
 : hash_context(nullptr),
   CMSMessage(nullptr),
   CMSSignedData(nullptr),
   CMSSignerInfo(nullptr),
   temp_certs(nullptr)
{
  setNSSDir({});
  CMSitem.data = p7;
  CMSitem.len = p7_length;
  CMSMessage = CMS_MessageCreate(&CMSitem);
  CMSSignedData = CMS_SignedDataCreate(CMSMessage);
  if (CMSSignedData) {
    CMSSignerInfo = CMS_SignerInfoCreate(CMSSignedData);
    hash_context = initHashContext();
  }
}

HASHContext * SignatureHandler::initHashContext()
{

  SECItem usedAlgorithm = NSS_CMSSignedData_GetDigestAlgs(CMSSignedData)[0]->algorithm;
  hash_length = digestLength(SECOID_FindOIDTag(&usedAlgorithm));
  HASH_HashType hashType;
  hashType    = HASH_GetHashTypeByOidTag(SECOID_FindOIDTag(&usedAlgorithm));
  return HASH_Create(hashType);
}

void SignatureHandler::updateHash(unsigned char * data_block, int data_len)
{
  if (hash_context) {
    HASH_Update(hash_context, data_block, data_len);
  }
}

SignatureHandler::~SignatureHandler()
{
  SECITEM_FreeItem(&CMSitem, PR_FALSE);
  if (CMSMessage)
    NSS_CMSMessage_Destroy(CMSMessage);

  if (hash_context)
    HASH_Destroy(hash_context);

  free(temp_certs);

  if (NSS_Shutdown()!=SECSuccess)
    fprintf(stderr, "Detail: %s\n", PR_ErrorToString(PORT_GetError(), PR_LANGUAGE_I_DEFAULT));
}

NSSCMSMessage *SignatureHandler::CMS_MessageCreate(SECItem * cms_item)
{
  if (cms_item->data){
    return NSS_CMSMessage_CreateFromDER(cms_item, nullptr, nullptr /* Content callback */
                        , nullptr, nullptr /*Password callback*/
                        , nullptr, nullptr /*Decrypt callback*/);
  } else {
    return nullptr;
  }
}

NSSCMSSignedData *SignatureHandler::CMS_SignedDataCreate(NSSCMSMessage * cms_msg)
{
  if (!NSS_CMSMessage_IsSigned(cms_msg)) {
    error(errInternal, 0, "Input couldn't be parsed as a CMS signature");
    return nullptr;
  }

  NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(cms_msg, 0);
  if (!cinfo) {
    error(errInternal, 0, "Error in NSS_CMSMessage_ContentLevel");
    return nullptr;
  }

  NSSCMSSignedData *signedData = (NSSCMSSignedData*) NSS_CMSContentInfo_GetContent(cinfo);
  if (!signedData) {
    error(errInternal, 0, "CError in NSS_CMSContentInfo_GetContent()");
    return nullptr;
  }

  if (signedData->rawCerts)
  {
    size_t i;
    for (i = 0; signedData->rawCerts[i]; ++i) {} // just count the length of the certificate chain

    // tempCerts field needs to be filled for complete memory release by NSSCMSSignedData_Destroy
    signedData->tempCerts = (CERTCertificate **) gmallocn( i+1, sizeof(CERTCertificate *));
    memset(signedData->tempCerts, 0, (i+1) * sizeof(CERTCertificate *));
    // store the addresses of these temporary certificates for future release
    for (i = 0; signedData->rawCerts[i]; ++i)
      signedData->tempCerts[i] = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), signedData->rawCerts[i], nullptr, 0, 0);

    temp_certs = signedData->tempCerts;
    return signedData;
  } else {
    return nullptr;
  }
}

NSSCMSSignerInfo *SignatureHandler::CMS_SignerInfoCreate(NSSCMSSignedData * cms_sig_data)
{
  NSSCMSSignerInfo *signerInfo = NSS_CMSSignedData_GetSignerInfo(cms_sig_data, 0);
  if (!signerInfo) {
    printf("Error in NSS_CMSSignedData_GetSignerInfo()\n");
    return nullptr;
  } else {
    return signerInfo;
  }
}

static SignatureValidationStatus NSS_SigTranslate(NSSCMSVerificationStatus nss_code)
{
  switch(nss_code)
  {
    case NSSCMSVS_GoodSignature:
      return SIGNATURE_VALID;

    case NSSCMSVS_BadSignature:
      return SIGNATURE_INVALID;

    case NSSCMSVS_DigestMismatch:
      return SIGNATURE_DIGEST_MISMATCH;

    case NSSCMSVS_ProcessingError:
      return SIGNATURE_DECODING_ERROR;

    default:
      return SIGNATURE_GENERIC_ERROR;
  }
}

SignatureValidationStatus SignatureHandler::validateSignature()
{
  unsigned char *digest_buffer = nullptr;

  if (!CMSSignedData)
    return SIGNATURE_GENERIC_ERROR;

  if (!NSS_IsInitialized())
    return SIGNATURE_GENERIC_ERROR;

  if (!hash_context)
    return SIGNATURE_GENERIC_ERROR;

  digest_buffer = (unsigned char *)PORT_Alloc(hash_length);
  unsigned int result_len = 0;

  HASH_End(hash_context, digest_buffer, &result_len, hash_length);

  SECItem digest;
  digest.data = digest_buffer;
  digest.len = hash_length;

  if ((NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB())) == nullptr)
    CMSSignerInfo->verificationStatus = NSSCMSVS_SigningCertNotFound;

  SECItem * content_info_data = CMSSignedData->contentInfo.content.data;
  if (content_info_data != nullptr && content_info_data->data != nullptr)
  {
    /*
      This means it's not a detached type signature
      so the digest is contained in SignedData->contentInfo
    */
    if (memcmp(digest.data, content_info_data->data, hash_length) == 0
        && digest.len == content_info_data->len)
    {
      PORT_Free(digest_buffer);
      return SIGNATURE_VALID;
    }
    else
    {
      PORT_Free(digest_buffer);
      return SIGNATURE_DIGEST_MISMATCH;
    }

  }
  else if (NSS_CMSSignerInfo_Verify(CMSSignerInfo, &digest, nullptr) != SECSuccess)
  {

    PORT_Free(digest_buffer);
    return NSS_SigTranslate(CMSSignerInfo->verificationStatus);
  }
  else
  {
    PORT_Free(digest_buffer);
    return SIGNATURE_VALID;
  }
}

CertificateValidationStatus SignatureHandler::validateCertificate(time_t validation_time)
{
  CERTCertificate *cert;

  if (!CMSSignerInfo)
    return CERTIFICATE_GENERIC_ERROR;

  if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB())) == nullptr)
    CMSSignerInfo->verificationStatus = NSSCMSVS_SigningCertNotFound;

  PRTime vTime = 0; // time in microseconds since the epoch, special value 0 means now
  if (validation_time > 0)
    vTime = 1000000*(PRTime)validation_time;
  CERTValInParam inParams[3];
  inParams[0].type = cert_pi_revocationFlags;
  inParams[0].value.pointer.revocation = CERT_GetClassicOCSPEnabledSoftFailurePolicy();
  inParams[1].type = cert_pi_date;
  inParams[1].value.scalar.time = vTime;
  inParams[2].type = cert_pi_end;

  CERT_PKIXVerifyCert(cert, certificateUsageEmailSigner, inParams, nullptr,
                CMSSignerInfo->cmsg->pwfn_arg);

  switch(PORT_GetError())
  {
    // 0 not defined in SECErrorCodes, it means success for this purpose.
    case 0:
      return CERTIFICATE_TRUSTED;

    case SEC_ERROR_UNKNOWN_ISSUER:
      return CERTIFICATE_UNKNOWN_ISSUER;

    case SEC_ERROR_UNTRUSTED_ISSUER:
      return CERTIFICATE_UNTRUSTED_ISSUER;

    case SEC_ERROR_REVOKED_CERTIFICATE:
      return CERTIFICATE_REVOKED;

    case SEC_ERROR_EXPIRED_CERTIFICATE:
      return CERTIFICATE_EXPIRED;
  }

  return CERTIFICATE_GENERIC_ERROR;
}
