//========================================================================
//
// 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 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)
      return nullptr;

  CERTCertificate *cert = NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB());
  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 = 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);
  }

  return info;
}

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

X509CertificateInfo *SignatureHandler::getCertificateInfo() const
{
  if (!CMSSignerInfo)
    return nullptr;

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

  X509CertificateInfo *certInfo = new 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;
}


GooString *SignatureHandler::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::init_nss()
{
  GooString *certDBPath = getDefaultFirefoxCertDB_Linux();
  bool initSuccess = false;
  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);
    }
  }
  //Make sure NSS root certificates module is loaded
  SECMOD_AddNewModule("Root Certs", "libnssckbi.so", 0, 0);

  delete certDBPath;
}


SignatureHandler::SignatureHandler(unsigned char *p7, int p7_length)
 : hash_context(nullptr),
   CMSMessage(nullptr),
   CMSSignedData(nullptr),
   CMSSignerInfo(nullptr),
   temp_certs(nullptr)
{
  init_nss();
  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;
  }
}

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

  if (!CMSSignedData)
    return NSSCMSVS_MalformedSignature;

  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 NSSCMSVS_GoodSignature;
    }
    else
    {
      PORT_Free(digest_buffer);
      return NSSCMSVS_DigestMismatch;
    }

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

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

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

  if (!CMSSignerInfo)
    return (SECErrorCodes) -1; //error code to avoid matching error codes defined in SECErrorCodes

  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);

  retVal = (SECErrorCodes) PORT_GetError();

  return retVal;
}


SignatureValidationStatus SignatureHandler::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;
  }
}

CertificateValidationStatus SignatureHandler::NSS_CertTranslate(SECErrorCodes nss_code)
{
  // 0 not defined in SECErrorCodes, it means success for this purpose.
  if (nss_code == (SECErrorCodes) 0)
    return CERTIFICATE_TRUSTED;

  switch(nss_code)
  {
    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;

    default:
      return CERTIFICATE_GENERIC_ERROR;
  }
}
