/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 * @author Jeff Thompson <jefft0@remap.ucla.edu>
 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
 */

#include "certificate.hpp"
#include "../../util/time.hpp"
#include "cryptopp.hpp"
#include "../../encoding/cryptopp/asn_ext.hpp"
#include "../../encoding/buffer-stream.hpp"
#include "../../util/concepts.hpp"
#include "../../util/indented-stream.hpp"

#include <boost/algorithm/string/split.hpp>

namespace ndn {
namespace security {
namespace v1 {

BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
static_assert(std::is_base_of<tlv::Error, Certificate::Error>::value,
              "Certificate::Error must inherit from tlv::Error");

Certificate::Certificate()
  : m_notBefore(time::system_clock::TimePoint::max())
  , m_notAfter(time::system_clock::TimePoint::min())
{
}

Certificate::Certificate(const Data& data)
  // Use the copy constructor.  It clones the signature object.
  : Data(data)
{
  decode();
}

Certificate::Certificate(const Block& block)
  : Data(block)
{
  decode();
}

Certificate::~Certificate()
{
}

void
Certificate::wireDecode(const Block& wire)
{
  Data::wireDecode(wire);
  decode();
}

bool
Certificate::isTooEarly()
{
  if (time::system_clock::now() < m_notBefore)
    return true;
  else
    return false;
}

bool
Certificate::isTooLate()
{
  if (time::system_clock::now() > m_notAfter)
    return true;
  else
    return false;
}

void
Certificate::encode()
{
  // Name
  //    <key_name>/ID-CERT/<id#>
  // Content
  // DER encoded idCert:
  //
  //    idCert ::= SEQUENCE {
  //        validity            Validity,
  //        subject             Name,
  //        subjectPubKeyInfo   SubjectPublicKeyInfo,
  //        extension           Extensions OPTIONAL   }
  //
  //    Validity ::= SEQUENCE {
  //        notBefore           Time,
  //        notAfter            Time   }
  //
  //    Name ::= CHOICE {
  //        RDNSequence   }
  //
  //    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  //
  //    RelativeDistinguishedName ::=
  //        SET OF AttributeTypeAndValue
  //
  //    SubjectPublicKeyInfo ::= SEQUENCE {
  //        algorithm           AlgorithmIdentifier
  //        keybits             BIT STRING   }
  //
  //    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  //
  // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
  //
  // KeyLocator
  //    issuer’s certificate name
  // Signature

  using namespace CryptoPP;

  OBufferStream os;
  CryptoPP::FileSink sink(os);

  // idCert ::= SEQUENCE {
  //     validity            Validity,
  //     subject             Name,
  //     subjectPubKeyInfo   SubjectPublicKeyInfo,
  //     extension           Extensions OPTIONAL   }
  DERSequenceEncoder idCert(sink);
  {
    // Validity ::= SEQUENCE {
    //       notBefore           Time,
    //       notAfter            Time   }
    DERSequenceEncoder validity(idCert);
    {
      DEREncodeGeneralTime(validity, m_notBefore);
      DEREncodeGeneralTime(validity, m_notAfter);
    }
    validity.MessageEnd();

    // Name ::= CHOICE {
    //     RDNSequence   }
    //
    // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    DERSequenceEncoder name(idCert);
    {
      for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
           it != m_subjectDescriptionList.end(); ++it)
        {
          it->encode(name);
        }
    }
    name.MessageEnd();

    // SubjectPublicKeyInfo
    m_key.encode(idCert);

    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
    //
    // Extension ::= SEQUENCE {
    //        extnID      OBJECT IDENTIFIER,
    //        critical    BOOLEAN DEFAULT FALSE,
    //        extnValue   OCTET STRING  }
    if (!m_extensionList.empty())
      {
        DERSequenceEncoder extensions(idCert);
        {
          for (ExtensionList::iterator it = m_extensionList.begin();
               it != m_extensionList.end(); ++it)
            {
              it->encode(extensions);
            }
        }
        extensions.MessageEnd();
      }
  }

  idCert.MessageEnd();

  setContent(os.buf());
  setContentType(tlv::ContentType_Key);
}

void
Certificate::decode()
{
  using namespace CryptoPP;

  try {
    OBufferStream os;
    StringSource source(getContent().value(), getContent().value_size(), true);

    // idCert ::= SEQUENCE {
    //     validity            Validity,
    //     subject             Name,
    //     subjectPubKeyInfo   SubjectPublicKeyInfo,
    //     extension           Extensions OPTIONAL   }
    BERSequenceDecoder idCert(source);
    {
      // Validity ::= SEQUENCE {
      //       notBefore           Time,
      //       notAfter            Time   }
      BERSequenceDecoder validity(idCert);
      {
        BERDecodeTime(validity, m_notBefore);
        BERDecodeTime(validity, m_notAfter);
      }
      validity.MessageEnd();

      // Name ::= CHOICE {
      //     RDNSequence   }
      //
      // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
      m_subjectDescriptionList.clear();
      BERSequenceDecoder name(idCert);
      {
        while (!name.EndReached())
          {
            m_subjectDescriptionList.push_back(CertificateSubjectDescription(name));
          }
      }
      name.MessageEnd();

      // SubjectPublicKeyInfo ::= SEQUENCE {
      //     algorithm           AlgorithmIdentifier
      //     keybits             BIT STRING   }
      m_key.decode(idCert);

      // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
      //
      // Extension ::= SEQUENCE {
      //        extnID      OBJECT IDENTIFIER,
      //        critical    BOOLEAN DEFAULT FALSE,
      //        extnValue   OCTET STRING  }
      m_extensionList.clear();
      if (!idCert.EndReached())
        {
          BERSequenceDecoder extensions(idCert);
          {
            while (!extensions.EndReached())
              {
                m_extensionList.push_back(CertificateExtension(extensions));
              }
          }
          extensions.MessageEnd();
        }
    }

    idCert.MessageEnd();
  }
  catch (CryptoPP::BERDecodeErr&) {
    BOOST_THROW_EXCEPTION(Error("Certificate Decoding Error"));
  }
}

void
Certificate::printCertificate(std::ostream& oss, const std::string& indent) const
{
  util::IndentedStream os(oss, indent);

  os << "Certificate name:\n";
  os << "  " << getName() << "\n";
  os << "Validity:\n";
  {
    os << "  NotBefore: " << time::toIsoString(m_notBefore) << "\n";
    os << "  NotAfter: "  << time::toIsoString(m_notAfter)  << "\n";
  }

  os << "Subject Description:\n";
  for (const auto& description : m_subjectDescriptionList)
    os << "  " << description.getOidString() << ": " << description.getValue() << "\n";

  os << "Public key bits: ";
  switch (m_key.getKeyType()) {
  case KeyType::RSA:
    os << "(RSA)";
    break;
  case KeyType::EC:
    os << "(ECDSA)";
    break;
  default:
    os << "(Unknown key type)";
    break;
  }
  os << "\n";

  {
    util::IndentedStream os2(os, "  ");
    CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os2), true, 64);
    m_key.encode(encoder);
  }

  os << "Signature Information:\n";
  {
    os << "  Signature Type: ";
    switch (getSignature().getType()) {
    case tlv::SignatureTypeValue::DigestSha256:
      os << "DigestSha256";
      break;
    case tlv::SignatureTypeValue::SignatureSha256WithRsa:
      os << "SignatureSha256WithRsa";
      break;
    case tlv::SignatureTypeValue::SignatureSha256WithEcdsa:
      os << "SignatureSha256WithEcdsa";
      break;
    default:
      os << "Unknown Signature Type";
    }
    os << "\n";

    if (getSignature().hasKeyLocator()) {
      const KeyLocator& keyLocator = getSignature().getKeyLocator();
      os << "  Key Locator: ";
      switch (keyLocator.getType()) {
      case KeyLocator::KeyLocator_Name:
        {
          const Name& signerName = keyLocator.getName();
          if (signerName.isPrefixOf(getName()))
            os << "(Self-Signed) " << keyLocator.getName();
          else
            os << "(Name) " << keyLocator.getName();
          break;
        }
      case KeyLocator::KeyLocator_KeyDigest:
        os << "(KeyDigest)";
        break;
      case KeyLocator::KeyLocator_None:
        os << "None";
        break;
      default:
        os << "Unknown";
      }
      os << "\n";
    }
  }
}

std::ostream&
operator<<(std::ostream& os, const Certificate& cert)
{
  cert.printCertificate(os);
  return os;
}

} // namespace v1
} // namespace security
} // namespace ndn
