/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014 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/signature-sha256-with-rsa.hpp"
#include "security/key-chain.hpp"
#include "security/validator.hpp"
#include "util/scheduler.hpp"
#include "identity-management-fixture.hpp"
#include "../unit-test-time-fixture.hpp"
#include "boost-test.hpp"

namespace ndn {
namespace tests {

class SignatureSha256RsaTimeFixture : public UnitTestTimeFixture
                                    , public security::IdentityManagementFixture
{
public:
  SignatureSha256RsaTimeFixture()
    : scheduler(io)
  {
  }

public:
  Scheduler scheduler;
};

BOOST_FIXTURE_TEST_SUITE(SecurityTestSignatureSha256WithRsa, SignatureSha256RsaTimeFixture)

const uint8_t sigInfo[] = {
0x16, 0x1b, // SignatureInfo
  0x1b, 0x01, // SignatureType
    0x01,
  0x1c, 0x16, // KeyLocator
    0x07, 0x14, // Name
      0x08, 0x04,
        0x74, 0x65, 0x73, 0x74,
      0x08, 0x03,
        0x6b, 0x65, 0x79,
      0x08, 0x07,
        0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
};

const uint8_t sigValue[] = {
0x17, 0x80, // SignatureValue
  0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec,
  0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6,
  0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38,
  0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6, 0x4d, 0x10, 0x1d, 0xdc,
  0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b, 0xcf,
  0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9,
  0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8,
  0x55, 0xf6, 0x1c, 0x19, 0x0b, 0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7,
  0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3,
  0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1
};


BOOST_AUTO_TEST_CASE(Decoding)
{
  Block sigInfoBlock(sigInfo, sizeof(sigInfo));
  Block sigValueBlock(sigValue, sizeof(sigValue));

  Signature sig(sigInfoBlock, sigValueBlock);
  BOOST_CHECK_NO_THROW(SignatureSha256WithRsa(sig));
  BOOST_CHECK_NO_THROW(sig.getKeyLocator());
}

BOOST_AUTO_TEST_CASE(Encoding)
{
  Name name("/test/key/locator");
  KeyLocator keyLocator(name);

  SignatureSha256WithRsa sig(keyLocator);

  BOOST_CHECK_NO_THROW(sig.getKeyLocator());

  const Block& encodeSigInfoBlock = sig.getInfo();

  Block sigInfoBlock(sigInfo, sizeof(sigInfo));

  BOOST_CHECK_EQUAL_COLLECTIONS(sigInfoBlock.wire(),
                                sigInfoBlock.wire() + sigInfoBlock.size(),
                                encodeSigInfoBlock.wire(),
                                encodeSigInfoBlock.wire() + encodeSigInfoBlock.size());

  sig.setKeyLocator(Name("/test/another/key/locator"));

  const Block& encodeSigInfoBlock2 = sig.getInfo();
  BOOST_CHECK(sigInfoBlock != encodeSigInfoBlock2);
}

BOOST_AUTO_TEST_CASE(DataSignature)
{
  Name identityName("/SecurityTestSignatureSha256WithRsa/DataSignature");
  BOOST_REQUIRE(addIdentity(identityName, RsaKeyParams()));
  shared_ptr<PublicKey> publicKey;
  BOOST_REQUIRE_NO_THROW(publicKey = m_keyChain.getPublicKeyFromTpm(
    m_keyChain.getDefaultKeyNameForIdentity(identityName)));

  Data testData("/SecurityTestSignatureSha256WithRsa/DataSignature/Data1");
  char content[5] = "1234";
  testData.setContent(reinterpret_cast<uint8_t*>(content), 5);
  BOOST_CHECK_NO_THROW(m_keyChain.signByIdentity(testData, identityName));
  Block dataBlock(testData.wireEncode().wire(), testData.wireEncode().size());

  Data testData2;
  testData2.wireDecode(dataBlock);
  BOOST_CHECK(Validator::verifySignature(testData2, *publicKey));
}

BOOST_AUTO_TEST_CASE(InterestSignature)
{
  Name identityName("/SecurityTestSignatureSha256WithRsa/InterestSignature");
  BOOST_REQUIRE(addIdentity(identityName, RsaKeyParams()));
  shared_ptr<PublicKey> publicKey;
  BOOST_REQUIRE_NO_THROW(publicKey = m_keyChain.getPublicKeyFromTpm(
    m_keyChain.getDefaultKeyNameForIdentity(identityName)));

  Interest interest("/SecurityTestSignatureSha256WithRsa/InterestSignature/Interest1");
  Interest interest11("/SecurityTestSignatureSha256WithRsa/InterestSignature/Interest1");

  scheduler.scheduleEvent(time::milliseconds(100), [&] {
      BOOST_CHECK_NO_THROW(m_keyChain.signByIdentity(interest, identityName));
    });

  advanceClocks(time::milliseconds(100));
  scheduler.scheduleEvent(time::milliseconds(100), [&] {
      BOOST_CHECK_NO_THROW(m_keyChain.signByIdentity(interest11, identityName));
    });

  advanceClocks(time::milliseconds(100));

  time::system_clock::TimePoint timestamp1 =
    time::fromUnixTimestamp(
      time::milliseconds(interest.getName().get(signed_interest::POS_TIMESTAMP).toNumber()));

  time::system_clock::TimePoint timestamp2 =
    time::fromUnixTimestamp(
      time::milliseconds(interest11.getName().get(signed_interest::POS_TIMESTAMP).toNumber()));

  BOOST_CHECK_EQUAL(time::milliseconds(100), (timestamp2 - timestamp1));

  uint64_t nonce1 = interest.getName().get(signed_interest::POS_RANDOM_VAL).toNumber();
  uint64_t nonce2 = interest11.getName().get(signed_interest::POS_RANDOM_VAL).toNumber();
  BOOST_WARN_NE(nonce1, nonce2);

  Block interestBlock(interest.wireEncode().wire(), interest.wireEncode().size());

  Interest interest2;
  interest2.wireDecode(interestBlock);
  BOOST_CHECK(Validator::verifySignature(interest2, *publicKey));
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace ndn
