/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2024 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/security/validation-policy-signed-interest.hpp"

#include "ndn-cxx/security/interest-signer.hpp"
#include "ndn-cxx/security/validation-policy-simple-hierarchy.hpp"

#include "tests/test-common.hpp"
#include "tests/unit/security/validator-fixture.hpp"

#include <boost/mp11/list.hpp>

namespace ndn::tests {

using namespace ndn::security;

BOOST_AUTO_TEST_SUITE(Security)

struct SignedInterestDefaultOptions
{
  static auto
  getOptions()
  {
    return ValidationPolicySignedInterest::Options{};
  }
};

template<class ValidationOptions, class InnerPolicy>
class SignedInterestPolicyWrapper : public ValidationPolicySignedInterest
{
public:
  SignedInterestPolicyWrapper()
    : ValidationPolicySignedInterest(make_unique<InnerPolicy>(), ValidationOptions::getOptions())
  {
  }
};

template<class ValidationOptions = SignedInterestDefaultOptions,
         class InnerPolicy = ValidationPolicySimpleHierarchy>
class ValidationPolicySignedInterestFixture
  : public HierarchicalValidatorFixture<SignedInterestPolicyWrapper<ValidationOptions, InnerPolicy>>
{
protected:
  Interest
  makeSignedInterest(const Identity& id,
                     uint32_t signingFlags = InterestSigner::WantNonce | InterestSigner::WantTime)
  {
    Interest interest(Name(id.getName()).append("CMD"));
    m_signer.makeSignedInterest(interest, signingByIdentity(id), signingFlags);
    return interest;
  }

protected:
  InterestSigner m_signer{this->m_keyChain};
  static constexpr uint32_t WantAll = InterestSigner::WantNonce |
                                      InterestSigner::WantTime |
                                      InterestSigner::WantSeqNum;
};

BOOST_FIXTURE_TEST_SUITE(TestValidationPolicySignedInterest, ValidationPolicySignedInterestFixture<>)

BOOST_AUTO_TEST_CASE(Basic)
{
  auto i1 = makeSignedInterest(identity, WantAll);
  VALIDATE_SUCCESS(i1, "Should succeed (within grace period)");
  VALIDATE_FAILURE(i1, "Should fail (replay attack)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  advanceClocks(5_ms);
  auto i2 = makeSignedInterest(identity, WantAll);
  VALIDATE_SUCCESS(i2, "Should succeed (timestamp and sequence number larger than previous)");

  Interest i3(Name(identity.getName()).append("CMD"));
  m_signer.makeSignedInterest(i3, signingWithSha256());
  VALIDATE_FAILURE(i3, "Should fail (Sha256 signature violates policy)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_AUTO_TEST_CASE(DataPassthrough)
{
  Data d1("/Security/ValidatorFixture/Sub1");
  m_keyChain.sign(d1);
  VALIDATE_SUCCESS(d1, "Should succeed (fallback on inner validation policy for data)");
}

BOOST_AUTO_TEST_CASE(InnerPolicyReject)
{
  auto i1 = makeSignedInterest(otherIdentity);
  VALIDATE_FAILURE(i1, "Should fail (inner policy should reject)");
  BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
}

template<ssize_t count>
struct MaxRecordCount
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.timestampGracePeriod = 15_s;
    options.maxRecordCount = count;
    return options;
  }
};

BOOST_FIXTURE_TEST_CASE(LimitedRecords, ValidationPolicySignedInterestFixture<MaxRecordCount<3>>)
{
  Identity id1 = addSubCertificate("/Security/ValidatorFixture/Sub1", identity);
  cache.insert(id1.getDefaultKey().getDefaultCertificate());
  Identity id2 = addSubCertificate("/Security/ValidatorFixture/Sub2", identity);
  cache.insert(id2.getDefaultKey().getDefaultCertificate());
  Identity id3 = addSubCertificate("/Security/ValidatorFixture/Sub3", identity);
  cache.insert(id3.getDefaultKey().getDefaultCertificate());
  Identity id4 = addSubCertificate("/Security/ValidatorFixture/Sub4", identity);
  cache.insert(id4.getDefaultKey().getDefaultCertificate());

  auto i1 = makeSignedInterest(id2);
  auto i2 = makeSignedInterest(id3);
  auto i3 = makeSignedInterest(id4);
  auto i00 = makeSignedInterest(id1); // signed at 0s
  advanceClocks(1_s);
  auto i01 = makeSignedInterest(id1); // signed at 1s
  advanceClocks(1_s);
  auto i02 = makeSignedInterest(id1); // signed at 2s

  VALIDATE_SUCCESS(i00, "Should succeed");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i02, "Should succeed");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i1, "Should succeed");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i2, "Should succeed");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i3, "Should succeed, forgets identity id1");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i01, "Should succeed despite timestamp is reordered, because record has been evicted");
}

BOOST_FIXTURE_TEST_CASE(UnlimitedRecords, ValidationPolicySignedInterestFixture<MaxRecordCount<-1>>)
{
  std::vector<Identity> identities;
  for (size_t i = 0; i < 20; ++i) {
    Identity id = addSubCertificate("/Security/ValidatorFixture/Sub" + to_string(i), identity);
    cache.insert(id.getDefaultKey().getDefaultCertificate());
    identities.push_back(id);
  }

  auto i1 = makeSignedInterest(identities.at(0)); // signed at 0s
  advanceClocks(1_s);
  for (size_t i = 0; i < 20; ++i) {
    auto i2 = makeSignedInterest(identities.at(i)); // signed at +1s
    VALIDATE_SUCCESS(i2, "Should succeed");
    rewindClockAfterValidation();
  }

  VALIDATE_FAILURE(i1, "Should fail (timestamp reorder)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_FIXTURE_TEST_CASE(ZeroRecords, ValidationPolicySignedInterestFixture<MaxRecordCount<0>>)
{
  auto i1 = makeSignedInterest(identity); // signed at 0s
  advanceClocks(1_s);
  auto i2 = makeSignedInterest(identity); // signed at +1s
  VALIDATE_SUCCESS(i2, "Should succeed");
  rewindClockAfterValidation();

  VALIDATE_SUCCESS(i1, "Should succeed despite timestamp reordering, as records aren't kept");
}

struct DisabledTimestampValidation
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.shouldValidateTimestamps = false;
    return options;
  }
};

template<int secs>
struct GracePeriodSeconds
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.timestampGracePeriod = time::seconds(secs);
    return options;
  }
};

BOOST_AUTO_TEST_SUITE(TimestampValidation)

BOOST_AUTO_TEST_CASE(MissingTimestamp)
{
  auto i1 = makeSignedInterest(identity, InterestSigner::WantSeqNum);
  VALIDATE_FAILURE(i1, "Should fail (timestamp missing)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_FIXTURE_TEST_CASE(Disabled, ValidationPolicySignedInterestFixture<DisabledTimestampValidation>)
{
  auto i1 = makeSignedInterest(identity); // signed at 0ms
  advanceClocks(100_ms);
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity); // signed at +100ms
  // Set i2 to have same timestamp as i1
  auto si2 = i2.getSignatureInfo();
  si2->setTime(i2.getSignatureInfo()->getTime());
  i2.setSignatureInfo(*si2);
  VALIDATE_SUCCESS(i2, "Should succeed");
}

BOOST_FIXTURE_TEST_CASE(TimestampTooOld, ValidationPolicySignedInterestFixture<GracePeriodSeconds<15>>)
{
  auto i1 = makeSignedInterest(identity); // signed at 0s
  advanceClocks(16_s); // verifying at +16s
  VALIDATE_FAILURE(i1, "Should fail (timestamp outside the grace period)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
  rewindClockAfterValidation();

  auto i2 = makeSignedInterest(identity); // signed at +16s
  VALIDATE_SUCCESS(i2, "Should succeed");
}

BOOST_FIXTURE_TEST_CASE(TimestampTooNew, ValidationPolicySignedInterestFixture<GracePeriodSeconds<15>>)
{
  auto i1 = makeSignedInterest(identity); // signed at 0s
  advanceClocks(1_s);
  auto i2 = makeSignedInterest(identity); // signed at +1s
  advanceClocks(1_s);
  auto i3 = makeSignedInterest(identity); // signed at +2s

  m_systemClock->advance(-18_s); // verifying at -16s
  VALIDATE_FAILURE(i1, "Should fail (timestamp outside the grace period)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
  rewindClockAfterValidation();

  // SignedInterestValidator should not remember i1's timestamp
  VALIDATE_FAILURE(i2, "Should fail (timestamp outside the grace period)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
  rewindClockAfterValidation();

  // SignedInterestValidator should not remember i2's timestamp, and should treat i3 as initial
  advanceClocks(18_s); // verifying at +2s
  VALIDATE_SUCCESS(i3, "Should succeed");
}

BOOST_AUTO_TEST_CASE(TimestampReorderEqual)
{
  auto i1 = makeSignedInterest(identity); // signed at 0s
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity); // signed at 0s
  auto si2 = i2.getSignatureInfo();
  si2->setTime(i1.getSignatureInfo()->getTime());
  i2.setSignatureInfo(*si2);
  VALIDATE_FAILURE(i2, "Should fail (timestamp reordered)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  advanceClocks(2_s);
  auto i3 = makeSignedInterest(identity); // signed at +2s
  VALIDATE_SUCCESS(i3, "Should succeed");
}

BOOST_AUTO_TEST_CASE(TimestampReorderNegative)
{
  auto i2 = makeSignedInterest(identity); // signed at 0ms
  advanceClocks(200_ms);
  auto i3 = makeSignedInterest(identity); // signed at +200ms
  advanceClocks(900_ms);
  auto i1 = makeSignedInterest(identity); // signed at +1100ms
  advanceClocks(300_ms);
  auto i4 = makeSignedInterest(identity); // signed at +1400ms

  m_systemClock->advance(-300_ms); // verifying at +1100ms
  VALIDATE_SUCCESS(i1, "Should succeed");
  rewindClockAfterValidation();

  m_systemClock->advance(-1100_ms); // verifying at 0ms
  VALIDATE_FAILURE(i2, "Should fail (timestamp reordered)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
  rewindClockAfterValidation();

  // SignedInterestValidator should not remember i2's timestamp
  advanceClocks(200_ms); // verifying at +200ms
  VALIDATE_FAILURE(i3, "Should fail (timestamp reordered)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
  rewindClockAfterValidation();

  advanceClocks(1200_ms); // verifying at 1400ms
  VALIDATE_SUCCESS(i4, "Should succeed");
}

using NonPositiveGracePeriods = boost::mp11::mp_list<GracePeriodSeconds<0>, GracePeriodSeconds<-1>>;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(GraceNonPositive, GracePeriod, NonPositiveGracePeriods,
                                 ValidationPolicySignedInterestFixture<GracePeriod>)
{
  auto i1 = this->makeSignedInterest(this->identity); // signed at 0ms
  auto i2 = this->makeSignedInterest(this->subIdentity); // signed at 0ms
  // ensure timestamps are exactly 0ms
  for (auto interest : {&i1, &i2}) {
    auto si = interest->getSignatureInfo();
    si->setTime(time::system_clock::now());
    interest->setSignatureInfo(*si);
  }

  VALIDATE_SUCCESS(i1, "Should succeed when validating at 0ms");
  this->rewindClockAfterValidation();

  this->advanceClocks(1_ms);
  VALIDATE_FAILURE(i2, "Should fail when validating at 1ms");
  BOOST_TEST(this->lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_AUTO_TEST_SUITE_END() // TimestampValidation

struct EnabledSeqNumValidation
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.shouldValidateSeqNums = true;
    return options;
  }
};

BOOST_AUTO_TEST_SUITE(SeqNumValidation)

// By default, sequence number validation is disabled
BOOST_AUTO_TEST_CASE(Disabled)
{
  auto i1 = makeSignedInterest(identity, WantAll); // signed at 0ms
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity, WantAll); // signed at +100ms
  // Set i2 to have same seq num as i1
  auto si2 = i2.getSignatureInfo();
  si2->setSeqNum(i2.getSignatureInfo()->getSeqNum());
  i2.setSignatureInfo(*si2);
  VALIDATE_SUCCESS(i2, "Should succeed");
}

BOOST_FIXTURE_TEST_CASE(MissingSeqNum, ValidationPolicySignedInterestFixture<EnabledSeqNumValidation>)
{
  auto i1 = makeSignedInterest(identity, InterestSigner::WantTime);
  VALIDATE_FAILURE(i1, "Should fail (sequence number missing");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_FIXTURE_TEST_CASE(SeqNumReorder, ValidationPolicySignedInterestFixture<EnabledSeqNumValidation>)
{
  auto i1 = makeSignedInterest(identity, WantAll); // seq num is i
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity, WantAll); // seq num is i+1
  auto si2 = i2.getSignatureInfo();
  si2->setSeqNum(i1.getSignatureInfo()->getSeqNum());
  i2.setSignatureInfo(*si2);
  VALIDATE_FAILURE(i2, "Should fail (sequence number reordered)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  auto i3 = makeSignedInterest(identity, WantAll); // seq num is i+2
  VALIDATE_SUCCESS(i3, "Should succeed");
}

BOOST_AUTO_TEST_SUITE_END() // SeqNumValidation

struct DisabledNonceValidation
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.shouldValidateNonces = false;
    return options;
  }
};

template<ssize_t count>
struct MaxNonceRecordCount
{
  static auto
  getOptions()
  {
    ValidationPolicySignedInterest::Options options;
    options.shouldValidateTimestamps = false;
    options.shouldValidateSeqNums = false;
    options.maxNonceRecordCount = count;
    return options;
  }
};

BOOST_AUTO_TEST_SUITE(NonceValidation)

BOOST_AUTO_TEST_CASE(MissingNonce)
{
  auto i1 = makeSignedInterest(identity, InterestSigner::WantTime); // Specifically exclude nonce
  VALIDATE_FAILURE(i1, "Should fail (nonce missing)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
}

BOOST_AUTO_TEST_CASE(DuplicateNonce)
{
  auto i1 = makeSignedInterest(identity, WantAll);
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity, WantAll);
  auto si2 = i2.getSignatureInfo();
  si2->setNonce(i1.getSignatureInfo()->getNonce());
  i2.setSignatureInfo(*si2);
  VALIDATE_FAILURE(i2, "Should fail (duplicate nonce)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  auto i3 = makeSignedInterest(identity, WantAll);
  // On the off chance that the generated nonce is identical to i1
  while (i3.getSignatureInfo()->getNonce() == i1.getSignatureInfo()->getNonce()) {
    i3 = makeSignedInterest(identity, WantAll);
  }
  VALIDATE_SUCCESS(i3, "Should succeed");
}

BOOST_FIXTURE_TEST_CASE(Disabled, ValidationPolicySignedInterestFixture<DisabledNonceValidation>)
{
  auto i1 = makeSignedInterest(identity, WantAll ^ InterestSigner::WantNonce);
  VALIDATE_SUCCESS(i1, "Should succeed");

  // Ensure still works when a nonce is present
  auto i2 = makeSignedInterest(identity, WantAll);
  VALIDATE_SUCCESS(i2, "Should succeed");

  // Ensure a duplicate still succeeds
  auto i3 = makeSignedInterest(identity, WantAll);
  auto si3 = i3.getSignatureInfo();
  si3->setNonce(i2.getSignatureInfo()->getNonce());
  i3.setSignatureInfo(*si3);
  m_keyChain.sign(i3, signingByIdentity(identity).setSignedInterestFormat(SignedInterestFormat::V03)
                                                 .setSignatureInfo(*si3));
  VALIDATE_SUCCESS(i3, "Should succeed");
}

BOOST_FIXTURE_TEST_CASE(NonceRecordLimit, ValidationPolicySignedInterestFixture<MaxNonceRecordCount<2>>)
{
  auto i1 = makeSignedInterest(identity, WantAll);
  VALIDATE_SUCCESS(i1, "Should succeed");

  auto i2 = makeSignedInterest(identity, WantAll);
  // On the off chance that the generated nonce is identical to i1
  while (i2.getSignatureInfo()->getNonce() == i1.getSignatureInfo()->getNonce()) {
    i2 = makeSignedInterest(identity, WantAll);
  }
  VALIDATE_SUCCESS(i2, "Should succeed");

  auto i3 = makeSignedInterest(identity, WantAll);
  auto si3 = i3.getSignatureInfo();
  si3->setNonce(i1.getSignatureInfo()->getNonce());
  i3.setSignatureInfo(*si3);
  m_keyChain.sign(i3, signingByIdentity(identity).setSignedInterestFormat(SignedInterestFormat::V03)
                                                 .setSignatureInfo(*si3));
  VALIDATE_FAILURE(i3, "Should fail (duplicate nonce)");
  BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);

  // Pop i1's nonce off the list
  auto i4 = makeSignedInterest(identity, WantAll);
  // On the off chance that the generated nonce is identical to i1 or i2
  while (i4.getSignatureInfo()->getNonce() == i1.getSignatureInfo()->getNonce() ||
         i4.getSignatureInfo()->getNonce() == i2.getSignatureInfo()->getNonce()) {
    i4 = makeSignedInterest(identity, WantAll);
  }
  VALIDATE_SUCCESS(i4, "Should succeed");

  // Now i3 should succeed because i1's nonce has been popped off the list
  auto i5 = makeSignedInterest(identity, WantAll);
  auto si5 = i5.getSignatureInfo();
  si5->setNonce(i1.getSignatureInfo()->getNonce());
  i5.setSignatureInfo(*si5);
  m_keyChain.sign(i5, signingByIdentity(identity).setSignedInterestFormat(SignedInterestFormat::V03)
                                                 .setSignatureInfo(*si5));
  VALIDATE_SUCCESS(i5, "Should succeed");
}

BOOST_AUTO_TEST_SUITE_END() // NonceValidation

BOOST_AUTO_TEST_SUITE_END() // TestValidationPolicySignedInterest
BOOST_AUTO_TEST_SUITE_END() // Security

} // namespace ndn::tests
