/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
 *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#include "ccnx-verifier.h"

namespace Ccnx {

static const size_t ROOT_KEY_DIGEST_LEN = 32;  // SHA-256
static const unsigned char ROOT_KEY_DIGEST[ROOT_KEY_DIGEST_LEN] = {0xa7, 0xd9, 0x8b, 0x81, 0xde, 0x13, 0xfc,
0x56, 0xc5, 0xa6, 0x92, 0xb4, 0x44, 0x93, 0x6e, 0x56, 0x70, 0x9d, 0x52, 0x6f, 0x70,
0xed, 0x39, 0xef, 0xb5, 0xe2, 0x3, 0x29, 0xa5, 0x53, 0x3e, 0x68};

Verifier::Verifier(CcnxWrapper *ccnx)
         : m_ccnx(ccnx)
         , m_rootKeyDigest(ROOT_KEY_DIGEST, ROOT_KEY_DIGEST_LEN)
{
}

Verifier::~Verifier()
{
}

bool
Verifier::verify(const PcoPtr &pco)
{
  if (pco->integrityChecked())
  {
    return false;
  }

  HashPtr publisherPublicKeyDigest = pco->publisherPublicKeyDigest();
  CertCache::iterator it = m_certCache.find(*publisherPublicKeyDigest);
  if (it != m_certCache.end())
  {
    CertPtr cert = it->second;
    if (cert->validity() == Cert::WITHIN_VALID_TIME_SPAN)
    {
      // integrity checked, and the key is trustworthy
      pco->setVerified(true);
      return true;
    }
    else
    {
      // delete the invalid cert cache
      m_certCache.erase(it);
    }
  }

  // keyName is the name specified in key locator, i.e. without version and segment
  Name keyName = pco->keyName();
  int keyNameSize = keyName.size();

  if (keyNameSize == 0)
  {
    return false;
  }

  // for keys, we have to make sure key name is strictly prefix of the content name
  if (pco->type() == ParsedContentObject::KEY)
  {
    Name contentName = pco->name();
    if (keyNameSize >= contentName.size() || contentName.getPartialName(0, keyNameSize) != keyName)
    {
      return false;
    }
  }
  else
  {
    // for now, user can assign any data using his key
  }

  Name metaName = keyName.getPartialName(0, keyNameSize - 1) + Name("/info") + keyName.getPartialName(keyNameSize - 1);

  Selectors selectors;

  selectors.childSelector(Selectors::RIGHT)
           .interestLifetime(1.0);

  PcoPtr keyObject = m_ccnx->get(keyName, selectors);
  PcoPtr metaObject = m_ccnx->get(metaName, selectors);
  if (!keyObject || !metaObject || !keyObject->integrityChecked() || !metaObject->integrityChecked())
  {
    return false;
  }

  HashPtr publisherKeyHashInKeyObject = keyObject->publisherPublicKeyDigest();
  HashPtr publisherKeyHashInMetaObject = metaObject->publisherPublicKeyDigest();

  // make sure key and meta are signed using the same key
  if (publisherKeyHashInKeyObject->IsZero() || ! (*publisherKeyHashInKeyObject == *publisherKeyHashInMetaObject))
  {
    return false;
  }

  CertPtr cert = boost::make_shared<Cert>(keyObject, metaObject);
  if (cert->validity() != Cert::WITHIN_VALID_TIME_SPAN)
  {
    return false;
  }

  // check pco is actually signed by this key (maybe redundant)
  if (! (*pco->publisherPublicKeyDigest() == cert->keyDigest()))
  {
    return false;
  }

  // now we only need to make sure the key is trustworthy
  if (cert->keyDigest() == m_rootKeyDigest)
  {
    // the key is the root key
    // do nothing now
  }
  else
  {
    // can not verify key
    if (!verify(keyObject))
    {
      return false;
    }
  }

  // ok, keyObject verified, because metaObject is signed by the same parent key and integrity checked
  // so metaObject is also verified
  m_certCache.insert(std::make_pair(cert->keyDigest(), cert));

  pco->setVerified(true);
  return true;
}

} // Ccnx
