//========================================================================
//
// 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 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>
//
//========================================================================

#include <config.h>

#include "SignatureHandler.h"
#include "goo/gmem.h"
#include <secmod.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);
}


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->getCString())) == 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();
  if (certDBPath == nullptr) {
    NSS_Init("sql:/etc/pki/nssdb");
  } else {
    NSS_Init(certDBPath->getCString());
  }
  //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 (CMSSignerInfo)
    NSS_CMSSignerInfo_Destroy(CMSSignerInfo);
  if (CMSSignedData)
    NSS_CMSSignedData_Destroy(CMSSignedData);
  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 adresses 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();

  if (cert)
    CERT_DestroyCertificate(cert);

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