security: Convert ValidatorConfig to ValidationPolicyConfig
The security API also provides a convenience ValidatorConfig helper.
Change-Id: Ic86dec4904b917361cb4740204de4b6710d2a386
Refs: #3920
diff --git a/tests/unit-tests/security/v2/validation-policy-config.t.cpp b/tests/unit-tests/security/v2/validation-policy-config.t.cpp
new file mode 100644
index 0000000..308b0fe
--- /dev/null
+++ b/tests/unit-tests/security/v2/validation-policy-config.t.cpp
@@ -0,0 +1,456 @@
+/* -*- 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/v2/validation-policy-config.hpp"
+#include "security/transform/base64-encode.hpp"
+#include "security/transform/buffer-source.hpp"
+#include "security/transform/stream-sink.hpp"
+#include "util/logger.hpp"
+#include "util/io.hpp"
+
+#include "boost-test.hpp"
+#include "validator-config/common.hpp"
+#include "validator-fixture.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+using namespace ndn::tests;
+using namespace ndn::security::v2::tests;
+
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_AUTO_TEST_SUITE(V2)
+BOOST_AUTO_TEST_SUITE(TestValidationPolicyConfig)
+
+template<typename Packet>
+class PacketName;
+
+template<>
+class PacketName<Interest>
+{
+public:
+ static std::string
+ getName()
+ {
+ return "interest";
+ }
+};
+
+template<>
+class PacketName<Data>
+{
+public:
+ static std::string
+ getName()
+ {
+ return "data";
+ }
+};
+
+template<typename PacketType>
+class ValidationPolicyConfigFixture : public HierarchicalValidatorFixture<ValidationPolicyConfig>
+{
+public:
+ ValidationPolicyConfigFixture()
+ : path(boost::filesystem::path(UNIT_TEST_CONFIG_PATH) / "security" / "v2" / "validation-policy-config")
+ {
+ boost::filesystem::create_directories(path);
+ baseConfig = R"CONF(
+ rule
+ {
+ id test-rule-id
+ for )CONF" + PacketName<Packet>::getName() + R"CONF(
+ filter
+ {
+ type name
+ name )CONF" + identity.getName().toUri() + R"CONF(
+ relation is-prefix-of
+ }
+ checker
+ {
+ type hierarchical
+ sig-type rsa-sha256
+ }
+ }
+ )CONF";
+ }
+
+ ~ValidationPolicyConfigFixture()
+ {
+ boost::filesystem::remove_all(path);
+ }
+
+public:
+ using Packet = PacketType;
+
+ const boost::filesystem::path path;
+ std::string baseConfig;
+};
+
+template<typename PacketType>
+class LoadStringWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
+{
+public:
+ LoadStringWithFileAnchor()
+ {
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
+
+ this->saveCertificate(this->identity, (this->path / "identity.ndncert").string());
+ this->policy.load(this->baseConfig + R"CONF(
+ trust-anchor
+ {
+ type file
+ file-name "trust-anchor.ndncert"
+ }
+ )CONF", (this->path / "test-config").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+ }
+};
+
+template<typename PacketType>
+class LoadFileWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
+{
+public:
+ LoadFileWithFileAnchor()
+ {
+ std::string configFile = (this->path / "config.conf").string();
+ {
+ std::ofstream config(configFile.c_str());
+ config << this->baseConfig << R"CONF(
+ trust-anchor
+ {
+ type file
+ file-name "trust-anchor.ndncert"
+ }
+ )CONF";
+ }
+ this->saveCertificate(this->identity, (this->path / "identity.ndncert").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
+
+ this->policy.load(configFile);
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+ }
+};
+
+template<typename PacketType>
+class LoadSectionWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
+{
+public:
+ LoadSectionWithFileAnchor()
+ {
+ auto section = makeSection(this->baseConfig + R"CONF(
+ trust-anchor
+ {
+ type file
+ file-name "trust-anchor.ndncert"
+ }
+ )CONF");
+
+ this->saveCertificate(this->identity, (this->path / "identity.ndncert").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
+
+ this->policy.load(section, (this->path / "test-config").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+ }
+};
+
+template<typename PacketType>
+class LoadStringWithBase64Anchor : public ValidationPolicyConfigFixture<PacketType>
+{
+public:
+ LoadStringWithBase64Anchor()
+ {
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
+
+ std::ostringstream os;
+ using namespace ndn::security::transform;
+ const auto& cert = this->identity.getDefaultKey().getDefaultCertificate();
+ bufferSource(cert.wireEncode().wire(), cert.wireEncode().size()) >> base64Encode(false) >> streamSink(os);
+
+ this->policy.load(this->baseConfig + R"CONF(
+ trust-anchor
+ {
+ type base64
+ base64-string ")CONF" + os.str() + R"CONF("
+ }
+ )CONF", (this->path / "test-config").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+ }
+};
+
+class NoRefresh
+{
+public:
+ static std::string
+ getRefreshString()
+ {
+ return "";
+ }
+};
+
+class Refresh1h
+{
+public:
+ static std::string
+ getRefreshString()
+ {
+ return "refresh 1h";
+ }
+
+ static time::milliseconds
+ getRefreshTime()
+ {
+ return time::hours(1);
+ }
+};
+
+class Refresh1m
+{
+public:
+ static std::string
+ getRefreshString()
+ {
+ return "refresh 1m";
+ }
+
+ static time::milliseconds
+ getRefreshTime()
+ {
+ return time::minutes(1);
+ }
+};
+
+class Refresh1s
+{
+public:
+ static std::string
+ getRefreshString()
+ {
+ return "refresh 1s";
+ }
+
+ static time::milliseconds
+ getRefreshTime()
+ {
+ return time::seconds(1);
+ }
+};
+
+template<typename PacketType, typename Refresh = NoRefresh>
+class LoadStringWithDirAnchor : public ValidationPolicyConfigFixture<PacketType>
+{
+public:
+ LoadStringWithDirAnchor()
+ {
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
+
+ boost::filesystem::create_directories(this->path / "keys");
+ this->saveCertificate(this->identity, (this->path / "keys" / "identity.ndncert").string());
+
+ this->policy.load(this->baseConfig + R"CONF(
+ trust-anchor
+ {
+ type dir
+ dir keys
+ )CONF" + Refresh::getRefreshString() + R"CONF(
+ }
+ )CONF", (this->path / "test-config").string());
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
+ }
+};
+
+using DataPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Data>,
+ LoadFileWithFileAnchor<Data>,
+ LoadSectionWithFileAnchor<Data>,
+ LoadStringWithBase64Anchor<Data>,
+ LoadStringWithDirAnchor<Data>,
+ LoadStringWithDirAnchor<Data, Refresh1h>,
+ LoadStringWithDirAnchor<Data, Refresh1m>,
+ LoadStringWithDirAnchor<Data, Refresh1s>
+ >;
+
+using InterestPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Interest>,
+ LoadFileWithFileAnchor<Interest>,
+ LoadSectionWithFileAnchor<Interest>,
+ LoadStringWithBase64Anchor<Interest>,
+ LoadStringWithDirAnchor<Interest>,
+ LoadStringWithDirAnchor<Interest, Refresh1h>,
+ LoadStringWithDirAnchor<Interest, Refresh1m>,
+ LoadStringWithDirAnchor<Interest, Refresh1s>
+ >;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateData, Policy, DataPolicies, Policy)
+{
+ BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 1);
+ BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
+
+ using Packet = typename Policy::Packet;
+ Packet unsignedPacket("/Security/V2/ValidatorFixture/Sub1/Sub2/Packet");
+
+ Packet packet = unsignedPacket;
+ VALIDATE_FAILURE(packet, "Unsigned");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingWithSha256());
+ VALIDATE_FAILURE(packet, "Policy doesn't accept Sha256Digest signature");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->identity));
+ VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
+ VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the policy-compliant cert");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateInterest, Policy, InterestPolicies, Policy)
+{
+ BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
+ BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 1);
+
+ using Packet = typename Policy::Packet;
+ Packet unsignedPacket("/Security/V2/ValidatorFixture/Sub1/Sub2/Packet");
+
+ Packet packet = unsignedPacket;
+ VALIDATE_FAILURE(packet, "Unsigned");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingWithSha256());
+ VALIDATE_FAILURE(packet, "Policy doesn't accept Sha256Digest signature");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->identity));
+ VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, as there is no matching rule for data");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
+}
+
+using Packets = boost::mpl::vector<Interest, Data>;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(TrustAnchorWildcard, Packet, Packets, ValidationPolicyConfigFixture<Packet>)
+{
+ this->policy.load(R"CONF(
+ trust-anchor
+ {
+ type any
+ }
+ )CONF", "test-config");
+
+ BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
+ BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, true);
+ BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
+ BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
+
+ Packet unsignedPacket("/Security/V2/ValidatorFixture/Sub1/Sub2/Packet");
+
+ Packet packet = unsignedPacket;
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingWithSha256());
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->identity));
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
+ VALIDATE_SUCCESS(packet, "Policy should accept everything");
+}
+
+using ReloadedPolicies = boost::mpl::vector<Refresh1h, Refresh1m, Refresh1s>;
+
+// Somehow, didn't work without this wrapper
+template<typename ReloadPolicy>
+class ReloadPolicyFixture : public LoadStringWithDirAnchor<Data, ReloadPolicy>
+{
+public:
+};
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateReload, Reload, ReloadedPolicies, ReloadPolicyFixture<Reload>)
+{
+ using Packet = Data;
+ Packet unsignedPacket("/Security/V2/ValidatorFixture/Sub1/Sub2/Packet");
+
+ boost::filesystem::remove(this->path / "keys" / "identity.ndncert");
+ this->advanceClocks(Reload::getRefreshTime(), 3);
+
+ Packet packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->identity));
+ VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
+
+ packet = unsignedPacket;
+ this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
+ VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestValidationPolicyConfig
+BOOST_AUTO_TEST_SUITE_END() // V2
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/v2/validator-config/checker.t.cpp b/tests/unit-tests/security/v2/validator-config/checker.t.cpp
new file mode 100644
index 0000000..12af61b
--- /dev/null
+++ b/tests/unit-tests/security/v2/validator-config/checker.t.cpp
@@ -0,0 +1,374 @@
+/* -*- 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/v2/validator-config/checker.hpp"
+#include "security/command-interest-signer.hpp"
+#include "security/v2/validation-policy.hpp"
+#include "security/v2/validation-state.hpp"
+
+#include "boost-test.hpp"
+#include "common.hpp"
+#include "identity-management-fixture.hpp"
+#include "../validator-fixture.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+using namespace ndn::tests;
+using namespace ndn::security::v2::tests;
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_AUTO_TEST_SUITE(V2)
+BOOST_AUTO_TEST_SUITE(ValidatorConfig)
+
+class CheckerFixture : public IdentityManagementFixture
+{
+public:
+ CheckerFixture()
+ {
+ names.push_back("/foo/bar");
+ names.push_back("/foo/bar/bar");
+ names.push_back("/foo");
+ names.push_back("/other/prefix");
+ }
+
+ Name
+ makeSignedInterestName(const Name& name)
+ {
+ return Name(name).append("SignatureInfo").append("SignatureValue");
+ }
+
+ Name
+ makeKeyLocatorName(const Name& name)
+ {
+ return Name(name).append("KEY").append("v=1");
+ }
+
+public:
+ std::vector<Name> names;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestChecker, CheckerFixture)
+
+class NameRelationEqual : public CheckerFixture
+{
+public:
+ NameRelationEqual()
+ : checker("/foo/bar", NameRelation::EQUAL)
+ {
+ }
+
+public:
+ NameRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false}};
+};
+
+class NameRelationIsPrefixOf : public CheckerFixture
+{
+public:
+ NameRelationIsPrefixOf()
+ : checker("/foo/bar", NameRelation::IS_PREFIX_OF)
+ {
+ }
+
+public:
+ NameRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
+ {true, true, false, false},
+ {true, true, false, false},
+ {true, true, false, false}};
+};
+
+class NameRelationIsStrictPrefixOf : public CheckerFixture
+{
+public:
+ NameRelationIsStrictPrefixOf()
+ : checker("/foo/bar", NameRelation::IS_STRICT_PREFIX_OF)
+ {
+ }
+
+public:
+ NameRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
+ {false, true, false, false},
+ {false, true, false, false},
+ {false, true, false, false}};
+};
+
+class RegexEqual : public CheckerFixture
+{
+public:
+ RegexEqual()
+ : checker(Regex("^<foo><bar>$"))
+ {
+ }
+
+public:
+ RegexChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false}};
+};
+
+class RegexIsPrefixOf : public CheckerFixture
+{
+public:
+ RegexIsPrefixOf()
+ : checker(Regex("^<foo><bar><>*$"))
+ {
+ }
+
+public:
+ RegexChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
+ {true, true, false, false},
+ {true, true, false, false},
+ {true, true, false, false}};
+};
+
+class RegexIsStrictPrefixOf : public CheckerFixture
+{
+public:
+ RegexIsStrictPrefixOf()
+ : checker(Regex("^<foo><bar><>+$"))
+ {
+ }
+
+public:
+ RegexChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
+ {false, true, false, false},
+ {false, true, false, false},
+ {false, true, false, false}};
+};
+
+class HyperRelationEqual : public CheckerFixture
+{
+public:
+ HyperRelationEqual()
+ : checker("^(<>+)$", "\\1", "^(<>+)<KEY><>$", "\\1", NameRelation::EQUAL)
+ {
+ }
+
+public:
+ HyperRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
+ {false, true, false, false},
+ {false, false, true, false},
+ {false, false, false, true}};
+};
+
+class HyperRelationIsPrefixOf : public CheckerFixture
+{
+public:
+ HyperRelationIsPrefixOf()
+ : checker("^(<>+)$", "\\1", "^(<>+)<KEY><>$", "\\1", NameRelation::IS_PREFIX_OF)
+ {
+ }
+
+public:
+ HyperRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
+ {true, true, true, false},
+ {false, false, true, false},
+ {false, false, false, true}};
+};
+
+class HyperRelationIsStrictPrefixOf : public CheckerFixture
+{
+public:
+ HyperRelationIsStrictPrefixOf()
+ : checker("^(<>+)$", "\\1", "^(<>+)<KEY><>$", "\\1", NameRelation::IS_STRICT_PREFIX_OF)
+ {
+ }
+
+public:
+ HyperRelationChecker checker;
+ std::vector<std::vector<bool>> outcomes = {{false, false, true, false},
+ {true, false, true, false},
+ {false, false, false, false},
+ {false, false, false, false}};
+};
+
+class Hierarchical : public CheckerFixture
+{
+public:
+ Hierarchical()
+ : checkerPtr(Checker::create(makeSection(R"CONF(
+ type hierarchical
+ sig-type rsa-sha256
+ )CONF"), "test-config"))
+ , checker(*checkerPtr)
+ {
+ }
+
+public:
+ std::unique_ptr<Checker> checkerPtr;
+ Checker& checker;
+
+ std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
+ {true, true, true, false},
+ {false, false, true, false},
+ {false, false, false, true}};
+};
+
+class CustomizedNameRelation : public CheckerFixture
+{
+public:
+ CustomizedNameRelation()
+ : checkerPtr(Checker::create(makeSection(R"CONF(
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ name /foo/bar
+ relation equal
+ }
+ )CONF"), "test-config"))
+ , checker(*checkerPtr)
+ {
+ }
+
+public:
+ std::unique_ptr<Checker> checkerPtr;
+ Checker& checker;
+
+ std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false}};
+};
+
+class CustomizedRegex : public CheckerFixture
+{
+public:
+ CustomizedRegex()
+ : checkerPtr(Checker::create(makeSection(R"CONF(
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ regex ^<foo><bar>$
+ }
+ )CONF"), "test-config"))
+ , checker(*checkerPtr)
+ {
+ }
+
+public:
+ std::unique_ptr<Checker> checkerPtr;
+ Checker& checker;
+
+ std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false},
+ {true, false, false, false}};
+};
+
+class CustomizedHyperRelation : public CheckerFixture
+{
+public:
+ CustomizedHyperRelation()
+ : checkerPtr(Checker::create(makeSection(R"CONF(
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ hyper-relation
+ {
+ k-regex ^(<>+)<KEY><>$
+ k-expand \\1
+ h-relation is-prefix-of
+ p-regex ^(<>+)$
+ p-expand \\1
+ }
+ }
+ )CONF"), "test-config"))
+ , checker(*checkerPtr)
+ {
+ }
+
+public:
+ std::unique_ptr<Checker> checkerPtr;
+ Checker& checker;
+
+ std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
+ {true, true, true, false},
+ {false, false, true, false},
+ {false, false, false, true}};
+};
+
+
+using Tests = boost::mpl::vector<NameRelationEqual, NameRelationIsPrefixOf, NameRelationIsStrictPrefixOf,
+ RegexEqual, RegexIsPrefixOf, RegexIsStrictPrefixOf,
+ HyperRelationEqual, HyperRelationIsPrefixOf, HyperRelationIsStrictPrefixOf,
+ Hierarchical,
+ CustomizedNameRelation, CustomizedRegex, CustomizedHyperRelation>;
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checks, T, Tests, T)
+{
+ BOOST_ASSERT(this->outcomes.size() == this->names.size());
+ for (size_t i = 0; i < this->names.size(); ++i) {
+ BOOST_ASSERT(this->outcomes[i].size() == this->names.size());
+ for (size_t j = 0; j < this->names.size(); ++j) {
+ const Name& pktName = this->names[i];
+ Name klName = this->makeKeyLocatorName(this->names[j]);
+ bool expectedOutcome = this->outcomes[i][j];
+
+ auto dataState = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->checker.check(tlv::Data, pktName, klName, dataState), expectedOutcome);
+ BOOST_CHECK_EQUAL(boost::logic::indeterminate(dataState->getOutcome()), expectedOutcome);
+ if (boost::logic::indeterminate(dataState->getOutcome()) == !expectedOutcome) {
+ BOOST_CHECK_EQUAL(dataState->getOutcome(), !expectedOutcome);
+ }
+
+ auto interestState = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->checker.check(tlv::Interest, this->makeSignedInterestName(pktName),
+ klName, interestState), expectedOutcome);
+ BOOST_CHECK_EQUAL(boost::logic::indeterminate(interestState->getOutcome()), expectedOutcome);
+ if (boost::logic::indeterminate(interestState->getOutcome()) == !expectedOutcome) {
+ BOOST_CHECK_EQUAL(interestState->getOutcome(), !expectedOutcome);
+ }
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestChecker
+BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
+BOOST_AUTO_TEST_SUITE_END() // V2
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/v2/validator-config/common.hpp b/tests/unit-tests/security/v2/validator-config/common.hpp
new file mode 100644
index 0000000..4250718
--- /dev/null
+++ b/tests/unit-tests/security/v2/validator-config/common.hpp
@@ -0,0 +1,48 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_TESTS_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
+#define NDN_TESTS_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
+
+#include <boost/property_tree/info_parser.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+inline ConfigSection
+makeSection(const std::string& config)
+{
+ std::istringstream inputStream(config);
+ ConfigSection section;
+ boost::property_tree::read_info(inputStream, section);
+ return section;
+}
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_TESTS_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
diff --git a/tests/unit-tests/security/v2/validator-config/filter.t.cpp b/tests/unit-tests/security/v2/validator-config/filter.t.cpp
new file mode 100644
index 0000000..054b99a
--- /dev/null
+++ b/tests/unit-tests/security/v2/validator-config/filter.t.cpp
@@ -0,0 +1,201 @@
+/* -*- 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/v2/validator-config/filter.hpp"
+#include "security/command-interest-signer.hpp"
+
+#include "boost-test.hpp"
+#include "common.hpp"
+#include "identity-management-fixture.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+using namespace ndn::tests;
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_AUTO_TEST_SUITE(V2)
+BOOST_AUTO_TEST_SUITE(ValidatorConfig)
+
+class FilterFixture : public IdentityManagementFixture
+{
+public:
+ Interest
+ makeSignedInterest(const Name& name)
+ {
+ Interest interest(name);
+ m_keyChain.sign(interest);
+ return interest;
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestFilter, FilterFixture)
+
+#define CHECK_FOR_MATCHES(filter, same, longer, shorter, different) \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Interest, makeSignedInterest("/foo/bar").getName()), same); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Data, Data("/foo/bar").getName()), same); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Interest, makeSignedInterest("/foo/bar/bar").getName()), longer); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Data, Data("/foo/bar/bar").getName()), longer); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Interest, makeSignedInterest("/foo").getName()), shorter); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Data, Data("/foo").getName()), shorter); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Interest, makeSignedInterest("/other/prefix").getName()), different); \
+ BOOST_CHECK_EQUAL(filter.match(tlv::Data, Data("/other/prefix").getName()), different);
+
+BOOST_AUTO_TEST_CASE(RelationName)
+{
+ RelationNameFilter f1("/foo/bar", NameRelation::EQUAL);
+ CHECK_FOR_MATCHES(f1, true, false, false, false);
+
+ RelationNameFilter f2("/foo/bar", NameRelation::IS_PREFIX_OF);
+ CHECK_FOR_MATCHES(f2, true, true, false, false);
+
+ RelationNameFilter f3("/foo/bar", NameRelation::IS_STRICT_PREFIX_OF);
+ CHECK_FOR_MATCHES(f3, false, true, false, false);
+}
+
+BOOST_AUTO_TEST_CASE(RegexName)
+{
+ RegexNameFilter f1(Regex("^<foo><bar>$"));
+ CHECK_FOR_MATCHES(f1, true, false, false, false);
+
+ RegexNameFilter f2(Regex("^<foo><bar><>*$"));
+ CHECK_FOR_MATCHES(f2, true, true, false, false);
+
+ RegexNameFilter f3(Regex("^<foo><bar><>+$"));
+ CHECK_FOR_MATCHES(f3, false, true, false, false);
+}
+
+BOOST_FIXTURE_TEST_SUITE(Create, FilterFixture)
+
+BOOST_AUTO_TEST_CASE(Errors)
+{
+ BOOST_CHECK_THROW(Filter::create(makeSection(""), "test-config"), Error);
+ BOOST_CHECK_THROW(Filter::create(makeSection("type unknown"), "test-config"), Error);
+ BOOST_CHECK_THROW(Filter::create(makeSection("type name"), "test-config"), Error);
+
+ std::string config = R"CONF(
+ type name
+ not-name-or-regex stuff
+ )CONF";
+ BOOST_CHECK_THROW(Filter::create(makeSection(config), "test-config"), Error);
+
+ config = R"CONF(
+ type name
+ name /foo/bar
+ )CONF";
+ BOOST_CHECK_THROW(Filter::create(makeSection(config), "test-config"), Error);
+
+ config = R"CONF(
+ type name
+ name /foo/bar
+ not-relation stuff
+ )CONF";
+ BOOST_CHECK_THROW(Filter::create(makeSection(config), "test-config"), Error);
+
+ config = R"CONF(
+ type name
+ name /foo/bar
+ relation equal
+ not-end stuff
+ )CONF";
+ BOOST_CHECK_THROW(Filter::create(makeSection(config), "test-config"), Error);
+
+ config = R"CONF(
+ type name
+ regex ^<foo><bar>$
+ not-end stuff
+ )CONF";
+ BOOST_CHECK_THROW(Filter::create(makeSection(config), "test-config"), Error);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter)
+{
+ std::string config = R"CONF(
+ type name
+ name /foo/bar
+ relation equal
+ )CONF";
+ auto f1 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f1), true, false, false, false);
+
+ config = R"CONF(
+ type name
+ name /foo/bar
+ relation is-prefix-of
+ )CONF";
+ auto f2 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f2), true, true, false, false);
+
+ config = R"CONF(
+ type name
+ name /foo/bar
+ relation is-strict-prefix-of
+ )CONF";
+ auto f3 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f3), false, true, false, false);
+}
+
+BOOST_AUTO_TEST_CASE(RegexFilter)
+{
+ std::string config = R"CONF(
+ type name
+ regex ^<foo><bar>$
+ )CONF";
+ auto f1 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f1), true, false, false, false);
+
+ config = R"CONF(
+ type name
+ regex ^<foo><bar><>*$
+ )CONF";
+ auto f2 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f2), true, true, false, false);
+
+ config = R"CONF(
+ type name
+ regex ^<foo><bar><>+$
+ )CONF";
+ auto f3 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f3), false, true, false, false);
+
+ config = R"CONF(
+ type name
+ regex ^<>*$
+ )CONF";
+ auto f4 = Filter::create(makeSection(config), "test-config");
+ CHECK_FOR_MATCHES((*f4), true, true, true, true);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Create
+
+BOOST_AUTO_TEST_SUITE_END() // TestFilter
+BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
+BOOST_AUTO_TEST_SUITE_END() // V2
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/v2/validator-config/name-relation.t.cpp b/tests/unit-tests/security/v2/validator-config/name-relation.t.cpp
new file mode 100644
index 0000000..cbe7084
--- /dev/null
+++ b/tests/unit-tests/security/v2/validator-config/name-relation.t.cpp
@@ -0,0 +1,79 @@
+/* -*- 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/v2/validator-config/name-relation.hpp"
+
+#include "boost-test.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_AUTO_TEST_SUITE(V2)
+BOOST_AUTO_TEST_SUITE(ValidatorConfig)
+BOOST_AUTO_TEST_SUITE(TestNameRelation)
+
+BOOST_AUTO_TEST_CASE(ToString)
+{
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(NameRelation::EQUAL), "equal");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(NameRelation::IS_PREFIX_OF),
+ "is-prefix-of");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(NameRelation::IS_STRICT_PREFIX_OF),
+ "is-strict-prefix-of");
+}
+
+BOOST_AUTO_TEST_CASE(FromString)
+{
+ BOOST_CHECK_EQUAL(getNameRelationFromString("equal"), NameRelation::EQUAL);
+ BOOST_CHECK_EQUAL(getNameRelationFromString("is-prefix-of"), NameRelation::IS_PREFIX_OF);
+ BOOST_CHECK_EQUAL(getNameRelationFromString("is-strict-prefix-of"), NameRelation::IS_STRICT_PREFIX_OF);
+ BOOST_CHECK_THROW(getNameRelationFromString("unknown"), validator_config::Error);
+}
+
+BOOST_AUTO_TEST_CASE(CheckRelation)
+{
+ BOOST_CHECK(checkNameRelation(NameRelation::EQUAL, "/prefix", "/prefix"));
+ BOOST_CHECK(!checkNameRelation(NameRelation::EQUAL, "/prefix", "/prefix/other"));
+
+ BOOST_CHECK(checkNameRelation(NameRelation::IS_PREFIX_OF, "/prefix", "/prefix"));
+ BOOST_CHECK(checkNameRelation(NameRelation::IS_PREFIX_OF, "/prefix", "/prefix/other"));
+ BOOST_CHECK(!checkNameRelation(NameRelation::IS_PREFIX_OF, "/prefix/other", "/prefix"));
+
+ BOOST_CHECK(!checkNameRelation(NameRelation::IS_STRICT_PREFIX_OF, "/prefix", "/prefix"));
+ BOOST_CHECK(checkNameRelation(NameRelation::IS_STRICT_PREFIX_OF, "/prefix", "/prefix/other"));
+ BOOST_CHECK(!checkNameRelation(NameRelation::IS_STRICT_PREFIX_OF, "/prefix/other", "/prefix"));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestNameRelation
+BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
+BOOST_AUTO_TEST_SUITE_END() // V2
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/v2/validator-config/rule.t.cpp b/tests/unit-tests/security/v2/validator-config/rule.t.cpp
new file mode 100644
index 0000000..6c2e631
--- /dev/null
+++ b/tests/unit-tests/security/v2/validator-config/rule.t.cpp
@@ -0,0 +1,209 @@
+/* -*- 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/v2/validator-config/rule.hpp"
+
+#include "boost-test.hpp"
+#include "common.hpp"
+#include "identity-management-fixture.hpp"
+#include "../validator-fixture.hpp"
+
+#include <boost/mpl/vector_c.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+namespace tests {
+
+using namespace ndn::tests;
+using namespace ndn::security::v2::tests;
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_AUTO_TEST_SUITE(V2)
+BOOST_AUTO_TEST_SUITE(ValidatorConfig)
+
+template<uint32_t PktType>
+class RuleFixture : public IdentityManagementFixture
+{
+public:
+ RuleFixture()
+ : rule(ruleId, PktType)
+ , pktName("/foo/bar")
+ {
+ if (PktType == tlv::Interest) {
+ pktName = Name("/foo/bar/SigInfo/SigValue");
+ }
+ }
+
+public:
+ const std::string ruleId = "rule-id";
+ Rule rule;
+ Name pktName;
+};
+
+using PktTypes = boost::mpl::vector_c<uint32_t, tlv::Data, tlv::Interest>;
+
+BOOST_AUTO_TEST_SUITE(TestRule)
+
+BOOST_FIXTURE_TEST_CASE(Errors, RuleFixture<tlv::Data>)
+{
+ BOOST_CHECK_THROW(rule.match(tlv::Interest, this->pktName), Error);
+
+ auto state = make_shared<DummyValidationState>();
+ BOOST_CHECK_THROW(rule.check(tlv::Interest, this->pktName, "/foo/bar", state), Error);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Constructor, PktType, PktTypes, RuleFixture<PktType::value>)
+{
+ BOOST_CHECK_EQUAL(this->rule.getId(), this->ruleId);
+ BOOST_CHECK_EQUAL(this->rule.getPktType(), PktType::value);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(EmptyRule, PktType, PktTypes, RuleFixture<PktType::value>)
+{
+ BOOST_CHECK_EQUAL(this->rule.match(PktType::value, this->pktName), true);
+
+ auto state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/foo/bar", state), false);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Filters, PktType, PktTypes, RuleFixture<PktType::value>)
+{
+ this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<foo><bar>$")));
+
+ BOOST_CHECK_EQUAL(this->rule.match(PktType::value, this->pktName), true);
+ BOOST_CHECK_EQUAL(this->rule.match(PktType::value, "/not" + this->pktName.toUri()), false);
+
+ this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<not><foo><bar>$")));
+
+ BOOST_CHECK_EQUAL(this->rule.match(PktType::value, this->pktName), true);
+ BOOST_CHECK_EQUAL(this->rule.match(PktType::value, "/not" + this->pktName.toUri()), true);
+
+ auto state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/foo/bar", state), false);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktType::value>)
+{
+ this->rule.addChecker(make_unique<HyperRelationChecker>("^(<>+)$", "\\1",
+ "^<not>?(<>+)$", "\\1",
+ NameRelation::EQUAL));
+
+ auto state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/foo/bar", state), true);
+
+ state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/not/foo/bar", state), true);
+
+ this->rule.addChecker(make_unique<HyperRelationChecker>("^(<>+)$", "\\1",
+ "^(<>+)$", "\\1",
+ NameRelation::EQUAL));
+ state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/foo/bar", state), true);
+
+ state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(this->rule.check(PktType::value, this->pktName, "/not/foo/bar", state), false);
+}
+
+BOOST_AUTO_TEST_SUITE(Create)
+
+BOOST_AUTO_TEST_CASE(Errors)
+{
+ BOOST_CHECK_THROW(Rule::create(makeSection(""), "test-config"), Error);
+
+ std::string config = R"CONF(
+ id rule-id
+ for something
+ )CONF";
+ BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
+
+ config = R"CONF(
+ id rule-id
+ for data
+ )CONF";
+ BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error); // at least one checker required
+
+ config = R"CONF(
+ id rule-id
+ for data
+ checker
+ {
+ type hierarchical
+ sig-type rsa-sha256
+ }
+ other stuff
+ )CONF";
+ BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(FilterAndChecker, PktType, PktTypes, RuleFixture<PktType::value>)
+{
+ std::string config = std::string("") + R"CONF(
+ id rule-id
+ for )CONF" + (PktType::value == tlv::Data ? "data" : "interest") + R"CONF(
+ filter
+ {
+ type name
+ regex ^<foo><bar>$
+ }
+ checker
+ {
+ type customized
+ sig-type rsa-sha256
+ key-locator
+ {
+ type name
+ hyper-relation
+ {
+ k-regex ^(<>+)$
+ k-expand \\1
+ h-relation equal
+ p-regex ^(<>+)$
+ p-expand \\1
+ }
+ }
+ }
+ )CONF";
+ auto rule = Rule::create(makeSection(config), "test-config");
+
+ BOOST_CHECK_EQUAL(rule->match(PktType::value, this->pktName), true);
+ BOOST_CHECK_EQUAL(rule->match(PktType::value, "/not" + this->pktName.toUri()), false);
+
+ auto state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(rule->check(PktType::value, this->pktName, "/foo/bar", state), true);
+
+ state = make_shared<DummyValidationState>();
+ BOOST_CHECK_EQUAL(rule->check(PktType::value, this->pktName, "/not/foo/bar", state), false);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Create
+
+BOOST_AUTO_TEST_SUITE_END() // TestRule
+BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
+BOOST_AUTO_TEST_SUITE_END() // V2
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/v2/validator-fixture.hpp b/tests/unit-tests/security/v2/validator-fixture.hpp
index fb7edda..7f52048 100644
--- a/tests/unit-tests/security/v2/validator-fixture.hpp
+++ b/tests/unit-tests/security/v2/validator-fixture.hpp
@@ -1,5 +1,5 @@
/* -*- 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).
@@ -42,6 +42,7 @@
ValidatorFixture()
: face(io, {true, true})
, validator(make_unique<ValidationPolicy>(), make_unique<CertificateFetcher>(face))
+ , policy(static_cast<ValidationPolicy&>(validator.getPolicy()))
, cache(time::days(100))
{
processInterest = [this] (const Interest& interest) {
@@ -101,6 +102,7 @@
util::DummyClientFace face;
std::function<void(const Interest& interest)> processInterest;
Validator validator;
+ ValidationPolicy& policy;
CertificateCache cache;
@@ -144,6 +146,35 @@
#define VALIDATE_SUCCESS(packet, message) this->template validate(packet, message, true, __LINE__)
#define VALIDATE_FAILURE(packet, message) this->template validate(packet, message, false, __LINE__)
+class DummyValidationState : public ValidationState
+{
+public:
+ ~DummyValidationState()
+ {
+ m_outcome = false;
+ }
+
+ void
+ fail(const ValidationError& error) override
+ {
+ // BOOST_TEST_MESSAGE(error);
+ m_outcome = false;
+ }
+
+private:
+ void
+ verifyOriginalPacket(const Certificate& trustedCert) override
+ {
+ // do nothing
+ }
+
+ void
+ bypassValidation() override
+ {
+ // do nothing
+ }
+};
+
} // namespace tests
} // namespace v2
} // namespace security