/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2022 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.
 */

#include "ndn-cxx/util/sha256.hpp"
#include "ndn-cxx/util/string-helper.hpp"
#include "ndn-cxx/security/impl/openssl.hpp"
#include "ndn-cxx/security/transform/digest-filter.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/security/transform/stream-source.hpp"

namespace ndn {
namespace util {

const size_t Sha256::DIGEST_SIZE;

Sha256::Sha256()
{
  reset();
}

Sha256::Sha256(std::istream& is)
  : m_output(make_unique<OBufferStream>())
  , m_isEmpty(false)
  , m_isFinalized(true)
{
  namespace tr = security::transform;

  tr::streamSource(is) >> tr::digestFilter(DigestAlgorithm::SHA256) >> tr::streamSink(*m_output);
}

void
Sha256::reset()
{
  namespace tr = security::transform;

  m_input = make_unique<tr::StepSource>();
  m_output = make_unique<OBufferStream>();
  m_isEmpty = true;
  m_isFinalized = false;

  *m_input >> tr::digestFilter(DigestAlgorithm::SHA256) >> tr::streamSink(*m_output);
}

ConstBufferPtr
Sha256::computeDigest()
{
  if (!m_isFinalized) {
    BOOST_ASSERT(m_input != nullptr);
    m_input->end();
    m_isFinalized = true;
  }

  return m_output->buf();
}

bool
Sha256::operator==(Sha256& digest)
{
  const Buffer& lhs = *computeDigest();
  const Buffer& rhs = *digest.computeDigest();

  if (lhs.size() != rhs.size()) {
    return false;
  }

  // constant-time buffer comparison to mitigate timing attacks
  return CRYPTO_memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}

Sha256&
Sha256::operator<<(Sha256& src)
{
  update(*src.computeDigest());
  return *this;
}

Sha256&
Sha256::operator<<(const std::string& str)
{
  update({reinterpret_cast<const uint8_t*>(str.data()), str.size()});
  return *this;
}

Sha256&
Sha256::operator<<(uint64_t value)
{
  update({reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t)});
  return *this;
}

Sha256&
Sha256::operator<<(span<const uint8_t> bytes)
{
  update(bytes);
  return *this;
}

void
Sha256::update(span<const uint8_t> buffer)
{
  if (m_isFinalized)
    NDN_THROW(Error("Digest has been already finalized"));

  BOOST_ASSERT(m_input != nullptr);
  m_input->write(buffer);
  m_isEmpty = false;
}

std::string
Sha256::toString()
{
  auto buf = computeDigest();
  return toHex(*buf);
}

ConstBufferPtr
Sha256::computeDigest(span<const uint8_t> buffer)
{
  Sha256 sha256;
  sha256.update(buffer);
  return sha256.computeDigest();
}

std::ostream&
operator<<(std::ostream& os, Sha256& digest)
{
  auto buf = digest.computeDigest();
  printHex(os, *buf);
  return os;
}

} // namespace util
} // namespace ndn
