add policy checker
Change-Id: I90c50d15b1d9d97832c66ce90e39524729f12a0f
diff --git a/tests/core/identity-fixture.hpp b/tests/core/identity-fixture.hpp
new file mode 100644
index 0000000..3ea68f6
--- /dev/null
+++ b/tests/core/identity-fixture.hpp
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NSL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NSL, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_TESTS_IDENTITY_FIXTURE_HPP
+#define NSL_TESTS_IDENTITY_FIXTURE_HPP
+
+#include "unit-test-time-fixture.hpp"
+#include <ndn-cxx/security/key-chain.hpp>
+#include <vector>
+
+#include <boost/filesystem.hpp>
+
+namespace nsl {
+namespace tests {
+
+class IdentityFixture : public UnitTestTimeFixture
+{
+public:
+ IdentityFixture()
+ : m_keyChainTmpPath(boost::filesystem::path(TEST_KEYCHAIN_PATH) / "IdentityFixture")
+ , m_keyChain(std::string("pib-sqlite3:").append(m_keyChainTmpPath.string()),
+ std::string("tpm-file:").append(m_keyChainTmpPath.string()))
+ {
+ }
+
+ ~IdentityFixture()
+ {
+ for (const auto& identity : m_identities) {
+ m_keyChain.deleteIdentity(identity);
+ }
+
+ boost::filesystem::remove_all(m_keyChainTmpPath);
+ }
+ /// @brief add identity, return true if succeed.
+ bool
+ addIdentity(const Name& identity,
+ const ndn::KeyParams& params = ndn::KeyChain::DEFAULT_KEY_PARAMS)
+ {
+ try {
+ m_keyChain.createIdentity(identity, params);
+ m_identities.push_back(identity);
+ return true;
+ }
+ catch (std::runtime_error&) {
+ return false;
+ }
+ }
+
+protected:
+ boost::filesystem::path m_keyChainTmpPath;
+ ndn::KeyChain m_keyChain;
+ std::vector<Name> m_identities;
+};
+
+} // namespace tests
+} // namespace nsl
+
+#endif // NSL_TESTS_IDENTITY_FIXTURE_HPP
diff --git a/tests/core/policy-checker.t.cpp b/tests/core/policy-checker.t.cpp
new file mode 100644
index 0000000..75c2ef4
--- /dev/null
+++ b/tests/core/policy-checker.t.cpp
@@ -0,0 +1,193 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NSL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NSL, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "policy-checker.hpp"
+#include "identity-fixture.hpp"
+#include <boost/property_tree/info_parser.hpp>
+
+#include "boost-test.hpp"
+
+namespace nsl {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TestPolicyChecker, IdentityFixture)
+
+BOOST_AUTO_TEST_CASE(TimeCheck)
+{
+ const std::string CONFIG =
+ "rule \n"
+ "{ \n"
+ " id \"Simple Rule\" \n"
+ " for data \n"
+ " checker \n"
+ " { \n"
+ " type customized \n"
+ " sig-type rsa-sha256 \n"
+ " key-locator \n"
+ " { \n"
+ " type name \n"
+ " hyper-relation \n"
+ " { \n"
+ " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
+ " k-expand \\\\1\\\\2 \n"
+ " h-relation is-strict-prefix-of \n"
+ " p-regex ^(<>*)$ \n"
+ " p-expand \\\\1 \n"
+ " } \n"
+ " } \n"
+ " } \n"
+ "} \n";
+
+ std::istringstream input(CONFIG);
+ conf::ConfigSection policy;
+ BOOST_REQUIRE_NO_THROW(boost::property_tree::read_info(input, policy));
+
+ PolicyChecker policyChecker;
+ policyChecker.loadPolicy(policy);
+
+ Name identity("/test/id");
+ addIdentity(identity);
+ Name selfSignedCertName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
+ auto selfSignedCert = m_keyChain.getCertificate(selfSignedCertName);
+
+ time::system_clock::TimePoint notBefore = time::system_clock::now();
+ time::system_clock::TimePoint notAfter = time::system_clock::now() + time::seconds(10);
+ std::vector<ndn::CertificateSubjectDescription> subDesc;
+
+ auto unsignedCert =
+ m_keyChain.prepareUnsignedIdentityCertificate(selfSignedCert->getPublicKeyName(),
+ selfSignedCert->getPublicKeyInfo(),
+ identity,
+ notBefore,
+ notAfter,
+ subDesc);
+
+ m_keyChain.sign(*unsignedCert, selfSignedCertName);
+ m_keyChain.addCertificate(*unsignedCert);
+
+ time::system_clock::TimePoint dataTs1 = time::system_clock::now() + time::seconds(5);
+ time::system_clock::TimePoint dataTs2 = time::system_clock::now() + time::seconds(1);
+ time::system_clock::TimePoint dataTs3 = time::system_clock::now() + time::seconds(15);
+ time::system_clock::TimePoint dataTs4 = time::system_clock::now() - time::seconds(1);
+ time::system_clock::TimePoint keyTs1 = time::system_clock::now() + time::seconds(2);
+ time::system_clock::TimePoint keyTs2 = time::system_clock::now() - time::seconds(2);
+ Timestamp dataTimestamp1 = time::toUnixTimestamp(dataTs1).count() / 1000;
+ Timestamp dataTimestamp2 = time::toUnixTimestamp(dataTs2).count() / 1000;
+ Timestamp dataTimestamp3 = time::toUnixTimestamp(dataTs3).count() / 1000;
+ Timestamp dataTimestamp4 = time::toUnixTimestamp(dataTs4).count() / 1000;
+ Timestamp keyTimestamp1 = time::toUnixTimestamp(keyTs1).count() / 1000;
+ Timestamp keyTimestamp2 = time::toUnixTimestamp(keyTs2).count() / 1000;
+
+ Data data("/test/id/data");
+ m_keyChain.sign(data, unsignedCert->getName());
+
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp1, data, keyTimestamp1, *unsignedCert), true);
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp2, data, keyTimestamp1, *unsignedCert), false);
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp3, data, keyTimestamp1, *unsignedCert), false);
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp4, data, keyTimestamp2, *unsignedCert), false);
+}
+
+BOOST_AUTO_TEST_CASE(RuleCheck)
+{
+ const std::string CONFIG =
+ "rule \n"
+ "{ \n"
+ " id \"Simple Rule\" \n"
+ " for data \n"
+ " checker \n"
+ " { \n"
+ " type customized \n"
+ " sig-type rsa-sha256 \n"
+ " key-locator \n"
+ " { \n"
+ " type name \n"
+ " hyper-relation \n"
+ " { \n"
+ " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
+ " k-expand \\\\1\\\\2 \n"
+ " h-relation is-strict-prefix-of \n"
+ " p-regex ^(<>*)$ \n"
+ " p-expand \\\\1 \n"
+ " } \n"
+ " } \n"
+ " } \n"
+ "} \n";
+
+ std::istringstream input(CONFIG);
+ conf::ConfigSection policy;
+ BOOST_REQUIRE_NO_THROW(boost::property_tree::read_info(input, policy));
+
+ PolicyChecker policyChecker;
+ policyChecker.loadPolicy(policy);
+
+
+ Name identity("/test/id");
+ addIdentity(identity);
+ Name selfSignedCertName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
+ auto selfSignedCert = m_keyChain.getCertificate(selfSignedCertName);
+
+ time::system_clock::TimePoint notBefore = time::system_clock::now();
+ time::system_clock::TimePoint notAfter = time::system_clock::now() + time::seconds(10);
+ std::vector<ndn::CertificateSubjectDescription> subDesc;
+
+ auto unsignedCert =
+ m_keyChain.prepareUnsignedIdentityCertificate(selfSignedCert->getPublicKeyName(),
+ selfSignedCert->getPublicKeyInfo(),
+ identity,
+ notBefore,
+ notAfter,
+ subDesc);
+
+ m_keyChain.sign(*unsignedCert, selfSignedCertName);
+ m_keyChain.addCertificate(*unsignedCert);
+
+ time::system_clock::TimePoint dataTs1 = time::system_clock::now() + time::seconds(5);
+ time::system_clock::TimePoint keyTs1 = time::system_clock::now() + time::seconds(2);
+ Timestamp dataTimestamp1 = time::toUnixTimestamp(dataTs1).count() / 1000;
+ Timestamp keyTimestamp1 = time::toUnixTimestamp(keyTs1).count() / 1000;
+
+
+ Data data1("/test/id/data");
+ m_keyChain.sign(data1, unsignedCert->getName());
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp1, data1, keyTimestamp1, *unsignedCert),
+ true);
+
+ Data data2("/test/id");
+ m_keyChain.sign(data2, unsignedCert->getName());
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp1, data2, keyTimestamp1, *unsignedCert),
+ false);
+
+ Data data3("/test/wrong");
+ m_keyChain.sign(data3, unsignedCert->getName());
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp1, data3, keyTimestamp1, *unsignedCert),
+ false);
+
+ Data data4("/test");
+ m_keyChain.sign(data4, unsignedCert->getName());
+ BOOST_CHECK_EQUAL(policyChecker.check(dataTimestamp1, data4, keyTimestamp1, *unsignedCert),
+ false);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nsl
diff --git a/tests/core/unit-test-time-fixture.hpp b/tests/core/unit-test-time-fixture.hpp
new file mode 100644
index 0000000..e70d66e
--- /dev/null
+++ b/tests/core/unit-test-time-fixture.hpp
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NSL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NSL, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
+#define NSL_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
+
+#include <ndn-cxx/util/time-unit-test-clock.hpp>
+
+#include <boost/asio.hpp>
+
+namespace nsl {
+namespace tests {
+
+class UnitTestTimeFixture
+{
+public:
+ UnitTestTimeFixture()
+ : steadyClock(make_shared<ndn::time::UnitTestSteadyClock>())
+ , systemClock(make_shared<ndn::time::UnitTestSystemClock>())
+ {
+ time::setCustomClocks(steadyClock, systemClock);
+ }
+
+ ~UnitTestTimeFixture()
+ {
+ time::setCustomClocks(nullptr, nullptr);
+ }
+
+ void
+ advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1)
+ {
+ for (size_t i = 0; i < nTicks; ++i) {
+ steadyClock->advance(tick);
+ systemClock->advance(tick);
+
+ if (io.stopped())
+ io.reset();
+ io.poll();
+ }
+ }
+
+public:
+ shared_ptr<ndn::time::UnitTestSteadyClock> steadyClock;
+ shared_ptr<ndn::time::UnitTestSystemClock> systemClock;
+ boost::asio::io_service io;
+};
+
+} // namespace tests
+} // namespace nsl
+
+#endif // NSL_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP