/* -*- 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.
 */

#include "security/sec-public-info-sqlite3.hpp"
#include "security/key-chain.hpp"
#include "security/v1/cryptopp.hpp"
#include "encoding/buffer-stream.hpp"
#include "util/time.hpp"

#include "boost-test.hpp"

#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>

namespace ndn {
namespace security {
namespace tests {

class PibTmpPathFixture
{
public:
  PibTmpPathFixture()
  {
    boost::system::error_code error;
    tmpPath = boost::filesystem::temp_directory_path(error);
    BOOST_REQUIRE(boost::system::errc::success == error.value());
    tmpPath /= boost::lexical_cast<std::string>(random::generateWord32());
  }

  ~PibTmpPathFixture()
  {
    boost::filesystem::remove_all(tmpPath);
  }

public:
  boost::filesystem::path tmpPath;
};

BOOST_AUTO_TEST_SUITE(Security)
BOOST_AUTO_TEST_SUITE(TestSecPublicInfoSqlite3)

const std::string RSA_DER("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuFoDcNtffwbfFix64fw0\
hI2tKMkFrc6Ex7yw0YLMK9vGE8lXOyBl/qXabow6RCz+GldmFN6E2Qhm1+AX3Zm5\
sj3H53/HPtzMefvMQ9X7U+lK8eNMWawpRzvBh4/36VrK/awlkNIVIQ9aXj6q6BVe\
zL+zWT/WYemLq/8A1/hHWiwCtfOH1xQhGqWHJzeSgwIgOOrzxTbRaCjhAb1u2TeV\
yx/I9H/DV+AqSHCaYbB92HDcDN0kqwSnUf5H1+osE9MR5DLBLhXdSiULSgxT3Or/\
y2QgsgUK59WrjhlVMPEiHHRs15NZJbL1uQFXjgScdEarohcY3dilqotineFZCeN8\
DwIDAQAB");
const std::string ECDSA_DER("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENZpqkPJDj8uhSpffOiCbvSYMLsGB\
1Eo/WU6mrexjGvduQXjqwon/eSHFI6EgHZk8L9KfiV5XVtVsk2g5wIpJVg==");

BOOST_FIXTURE_TEST_CASE(Basic, PibTmpPathFixture)
{
  SecPublicInfoSqlite3 pib(tmpPath.generic_string());

  BOOST_CHECK(pib.doesTableExist("Identity"));
  BOOST_CHECK(pib.doesTableExist("Key"));
  BOOST_CHECK(pib.doesTableExist("Certificate"));
}

BOOST_FIXTURE_TEST_CASE(TpmLocatorTest, PibTmpPathFixture)
{
  SecPublicInfoSqlite3 pib(tmpPath.generic_string());

  BOOST_REQUIRE_THROW(pib.getTpmLocator(), SecPublicInfo::Error);
  pib.addIdentity("/test/id1");
  BOOST_CHECK(pib.doesIdentityExist("/test/id1"));

  // Pib does not have tpmInfo set yet, setTpmInfo simply set the tpmInfo.
  std::string tpmLocator("tpm-file:");
  tpmLocator.append((tmpPath / "tpm").generic_string());
  pib.setTpmLocator(tpmLocator);
  BOOST_CHECK(pib.doesIdentityExist("/test/id1"));

  BOOST_REQUIRE_NO_THROW(pib.getTpmLocator());
  BOOST_CHECK_EQUAL(tpmLocator, pib.getTpmLocator());

  // Pib has tpmInfo set, set a different tpmInfo will reset Pib content.
  std::string tpmLocator3("tpm-osxkeychain:");
  pib.setTpmLocator(tpmLocator3);
  BOOST_CHECK(!pib.doesIdentityExist("/test/id1"));
}

BOOST_AUTO_TEST_CASE(KeyTypeRsa)
{
  using namespace CryptoPP;

  OBufferStream os;
  StringSource ss(reinterpret_cast<const uint8_t*>(RSA_DER.c_str()), RSA_DER.size(),
                  true, new Base64Decoder(new FileSink(os)));

  shared_ptr<v1::PublicKey> rsaKey;
  BOOST_REQUIRE_NO_THROW(rsaKey = make_shared<v1::PublicKey>(os.buf()->buf(), os.buf()->size()));
  Name rsaKeyName("/TestSecPublicInfoSqlite3/KeyType/RSA/ksk-123");
  SecPublicInfoSqlite3 pib;
  pib.addKey(rsaKeyName, *rsaKey);

  BOOST_CHECK_EQUAL(KeyType::RSA, pib.getPublicKeyType(rsaKeyName));

  pib.deleteIdentityInfo(Name("/TestSecPublicInfoSqlite3/KeyType/RSA"));
}

BOOST_AUTO_TEST_CASE(KeyTypeEcdsa)
{
  using namespace CryptoPP;

  OBufferStream os;
  StringSource ss(reinterpret_cast<const uint8_t*>(ECDSA_DER.c_str()), ECDSA_DER.size(),
                  true, new Base64Decoder(new FileSink(os)));

  shared_ptr<v1::PublicKey> ecdsaKey;
  BOOST_REQUIRE_NO_THROW(ecdsaKey = make_shared<v1::PublicKey>(os.buf()->buf(), os.buf()->size()));
  Name ecdsaKeyName("/TestSecPublicInfoSqlite3/KeyType/ECDSA/ksk-123");
  SecPublicInfoSqlite3 pib;
  pib.addKey(ecdsaKeyName, *ecdsaKey);

  BOOST_CHECK_EQUAL(KeyType::EC, pib.getPublicKeyType(ecdsaKeyName));
  pib.deleteIdentityInfo(Name("/TestSecPublicInfoSqlite3/KeyType/ECDSA"));
}

BOOST_AUTO_TEST_CASE(KeyTypeNonExistent)
{
  Name nullKeyName("/TestSecPublicInfoSqlite3/KeyType/Null");
  SecPublicInfoSqlite3 pib;

  BOOST_CHECK_EQUAL(KeyType::NONE, pib.getPublicKeyType(nullKeyName));
}

BOOST_AUTO_TEST_SUITE_END() // TestSecPublicInfoSqlite3
BOOST_AUTO_TEST_SUITE_END() // Security

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