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

#include "boost-test.hpp"
#include "identity-management-fixture.hpp"

namespace ndn {
namespace security {
namespace conf {
namespace tests {

using namespace ndn::tests;

BOOST_AUTO_TEST_SUITE(Security)
BOOST_AUTO_TEST_SUITE(Conf)
BOOST_FIXTURE_TEST_SUITE(TestChecker, IdentityManagementFixture)

BOOST_AUTO_TEST_CASE(CustomizedCheckerTest1)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RelationKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest1");
  addIdentity(identity, RsaKeyParams());
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest1Wrong");
  addIdentity(identity2, RsaKeyParams());
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest1/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.sign(*data1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.sign(*data2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  int8_t result = 0;


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerEqual1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_EQUAL);
  CustomizedChecker checker1(tlv::SignatureSha256WithRsa, keyLocatorCheckerEqual1);

  result = checker1.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2);
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerEqual2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_EQUAL);
  CustomizedChecker checker2(tlv::SignatureSha256WithRsa, keyLocatorCheckerEqual2);

  result = checker2.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*interest1);
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerPrefix1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_IS_PREFIX_OF);
  CustomizedChecker checker3(tlv::SignatureSha256WithRsa, keyLocatorCheckerPrefix1);

  result = checker3.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker3.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerPrefix2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_IS_PREFIX_OF);
  CustomizedChecker checker4(tlv::SignatureSha256WithRsa, keyLocatorCheckerPrefix2);

  result = checker4.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker4.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);


  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerStrict1 =
    make_shared<RelationKeyLocatorNameChecker>(certName.getPrefix(-1),
                                               KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF);
  CustomizedChecker checker5(tlv::SignatureSha256WithRsa, keyLocatorCheckerStrict1);

  result = checker5.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker5.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  shared_ptr<RelationKeyLocatorNameChecker> keyLocatorCheckerStrict2 =
    make_shared<RelationKeyLocatorNameChecker>(identity,
                                               KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF);
  CustomizedChecker checker6(tlv::SignatureSha256WithRsa, keyLocatorCheckerStrict2);

  result = checker6.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker6.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(CustomizedCheckerTest2)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RegexKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest2");
  addIdentity(identity, RsaKeyParams());
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest2Wrong");
  addIdentity(identity2, RsaKeyParams());
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest2/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.sign(*data1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.sign(*data2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  int8_t result = 0;


  shared_ptr<RegexKeyLocatorNameChecker> keyLocatorCheckerRegex1 =
    make_shared<RegexKeyLocatorNameChecker>(
      Regex("^<SecurityTestConfChecker><CustomizedCheckerTest2>"));
  CustomizedChecker checker1(tlv::SignatureSha256WithRsa, keyLocatorCheckerRegex1);

  result = checker1.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2);
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(CustomizedCheckerTest3)
{
  using security::conf::CustomizedChecker;
  using security::conf::KeyLocatorChecker;
  using security::conf::RegexKeyLocatorNameChecker;

  Name identity("/SecurityTestConfChecker/CustomizedCheckerTest3");
  addIdentity(identity, EcdsaKeyParams());
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest3Wrong");
  addIdentity(identity2, EcdsaKeyParams());
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/CustomizedCheckerTest3/Data");
  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.sign(*data1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.sign(*data2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  shared_ptr<Interest> interest1 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Interest> interest2 = make_shared<Interest>(packetName);
  m_keyChain.sign(*interest2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  int8_t result = 0;


  shared_ptr<RegexKeyLocatorNameChecker> keyLocatorCheckerRegex1 =
    make_shared<RegexKeyLocatorNameChecker>(
      Regex("^<SecurityTestConfChecker><CustomizedCheckerTest3>"));
  CustomizedChecker checker1(tlv::SignatureSha256WithEcdsa, keyLocatorCheckerRegex1);

  result = checker1.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*interest1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*interest2);
  BOOST_CHECK_EQUAL(result, -1);


  CustomizedChecker checker2(tlv::SignatureSha256WithRsa, keyLocatorCheckerRegex1);

  result = checker2.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(HierarchicalCheckerTest1)
{
  using security::conf::HierarchicalChecker;

  Name identity("/SecurityTestConfChecker/HierarchicalCheckerTest1");
  addIdentity(identity, EcdsaKeyParams());
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);

  Name identity2("/SecurityTestConfChecker/HierarchicalCheckerTest1/Data");
  addIdentity(identity2, RsaKeyParams());
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);

  Name packetName("/SecurityTestConfChecker/HierarchicalCheckerTest1/Data");
  Name packetName2("/SecurityTestConfChecker");
  Name packetName3("/SecurityTestConfChecker/HierarchicalCheckerTest1");

  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.sign(*data1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data2 = make_shared<Data>(packetName2);
  m_keyChain.sign(*data2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data3 = make_shared<Data>(packetName3);
  m_keyChain.sign(*data3,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data4 = make_shared<Data>(packetName);
  m_keyChain.sign(*data4,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  shared_ptr<Data> data5 = make_shared<Data>(packetName2);
  m_keyChain.sign(*data5,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  shared_ptr<Data> data6 = make_shared<Data>(packetName3);
  m_keyChain.sign(*data6,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  int8_t result = 0;

  HierarchicalChecker checker1(tlv::SignatureSha256WithEcdsa);

  result = checker1.check(*data1);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data3);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker1.check(*data4);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data5);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker1.check(*data6);
  BOOST_CHECK_EQUAL(result, -1);


  HierarchicalChecker checker2(tlv::SignatureSha256WithRsa);

  result = checker2.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data3);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data4);
  BOOST_CHECK_EQUAL(result, 0);

  result = checker2.check(*data5);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data6);
  BOOST_CHECK_EQUAL(result, -1);
}

BOOST_AUTO_TEST_CASE(FixedSignerCheckerTest1)
{
  using security::conf::FixedSignerChecker;

  Name identity("/SecurityTestConfChecker/FixedSignerCheckerTest1");
  addIdentity(identity, EcdsaKeyParams());
  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
  shared_ptr<v1::IdentityCertificate> cert1 = m_keyChain.getCertificate(certName);

  Name identity2("/SecurityTestConfChecker/FixedSignerCheckerTest1Wrong");
  addIdentity(identity2, RsaKeyParams());
  Name certName2 = m_keyChain.getDefaultCertificateNameForIdentity(identity2);
  shared_ptr<v1::IdentityCertificate> cert2 = m_keyChain.getCertificate(certName2);

  Name packetName("/Test/Data");

  shared_ptr<Data> data1 = make_shared<Data>(packetName);
  m_keyChain.sign(*data1,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity));

  shared_ptr<Data> data2 = make_shared<Data>(packetName);
  m_keyChain.sign(*data2,
                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_ID,
                                        identity2));

  std::vector<shared_ptr<v1::IdentityCertificate> > certSet1;
  certSet1.push_back(cert1);

  std::vector<shared_ptr<v1::IdentityCertificate> > certSet2;
  certSet2.push_back(cert2);


  int8_t result = 0;

  FixedSignerChecker checker1(tlv::SignatureSha256WithEcdsa, certSet1);

  result = checker1.check(*data1);
  BOOST_CHECK_EQUAL(result, 1);

  result = checker1.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker2(tlv::SignatureSha256WithRsa, certSet1);

  result = checker2.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker2.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker3(tlv::SignatureSha256WithEcdsa, certSet2);

  result = checker3.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker3.check(*data2);
  BOOST_CHECK_EQUAL(result, -1);


  FixedSignerChecker checker4(tlv::SignatureSha256WithRsa, certSet2);

  result = checker4.check(*data1);
  BOOST_CHECK_EQUAL(result, -1);

  result = checker4.check(*data2);
  BOOST_CHECK_EQUAL(result, 1);
}

BOOST_AUTO_TEST_SUITE_END() // TestChecker
BOOST_AUTO_TEST_SUITE_END() // Conf
BOOST_AUTO_TEST_SUITE_END() // Security

} // namespace tests
} // namespace conf
} // namespace security
} // namespace ndn
