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/conf/checker.t.cpp b/tests/unit-tests/security/conf/checker.t.cpp
deleted file mode 100644
index be2f9ea..0000000
--- a/tests/unit-tests/security/conf/checker.t.cpp
+++ /dev/null
@@ -1,439 +0,0 @@
-/* -*- 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, IdentityManagementV1Fixture)
-
-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, EcKeyParams());
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
-
-  Name identity2("/SecurityTestConfChecker/CustomizedCheckerTest3Wrong");
-  addIdentity(identity2, EcKeyParams());
-  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, EcKeyParams());
-  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, EcKeyParams());
-  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
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
diff --git a/tests/unit-tests/security/validator-config.t.cpp b/tests/unit-tests/security/validator-config.t.cpp
index e2fbda1..37f2cff 100644
--- a/tests/unit-tests/security/validator-config.t.cpp
+++ b/tests/unit-tests/security/validator-config.t.cpp
@@ -20,18 +20,12 @@
  */
 
 #include "security/validator-config.hpp"
-#include "security/signing-helpers.hpp"
+#include "security/v2/certificate-fetcher-offline.hpp"
 #include "util/dummy-client-face.hpp"
-#include "util/io.hpp"
-#include "util/scheduler.hpp"
-#include "lp/nack.hpp"
-#include "lp/tags.hpp"
 
 #include "boost-test.hpp"
-#include "make-interest-data.hpp"
-#include "../identity-management-time-fixture.hpp"
-
-#include <boost/logic/tribool.hpp>
+#include "identity-management-fixture.hpp"
+#include "v2/validator-config/common.hpp"
 
 namespace ndn {
 namespace security {
@@ -40,1597 +34,85 @@
 using namespace ndn::tests;
 
 BOOST_AUTO_TEST_SUITE(Security)
+BOOST_FIXTURE_TEST_SUITE(TestValidatorConfig, IdentityManagementFixture)
 
-// Needed to create Face instance
-class ValidatorConfigFixture : public IdentityManagementV1TimeFixture
+// This test only for API, actual tests are in ValidationPolicyConfig and corresponding CertificateFetchers
+
+BOOST_AUTO_TEST_CASE(Construct)
+{
+  util::DummyClientFace face;
+
+  ValidatorConfig v1(face);
+  BOOST_CHECK_EQUAL(v1.m_policyConfig.m_isConfigured, false);
+
+  ValidatorConfig v2(make_unique<v2::CertificateFetcherOffline>());
+  BOOST_CHECK_EQUAL(v2.m_policyConfig.m_isConfigured, false);
+}
+
+class ValidatorConfigFixture : public IdentityManagementFixture
 {
 public:
   ValidatorConfigFixture()
-    : m_v2KeyChain("pib-memory:", "tpm-memory:")
-    , face(nullptr, m_v2KeyChain)
-    , validator(face)
+    : path(boost::filesystem::path(UNIT_TEST_CONFIG_PATH) / "security" / "validator-config")
+    , validator(make_unique<v2::CertificateFetcherOffline>())
   {
+    boost::filesystem::create_directories(path);
+    config = R"CONF(
+        trust-anchor
+        {
+          type any
+        }
+      )CONF";
+    configFile = (this->path / "config.conf").string();
+    std::ofstream f(configFile.c_str());
+    f << config;
+  }
+
+  ~ValidatorConfigFixture()
+  {
+    boost::filesystem::remove_all(path);
   }
 
 public:
-  v2::KeyChain m_v2KeyChain;
-  Face face;
+  const boost::filesystem::path path;
+  std::string config;
+  std::string configFile;
   ValidatorConfig validator;
 };
 
-BOOST_FIXTURE_TEST_SUITE(TestValidatorConfig, ValidatorConfigFixture)
+BOOST_FIXTURE_TEST_SUITE(Loads, ValidatorConfigFixture)
 
-BOOST_AUTO_TEST_CASE(NameFilter)
+BOOST_AUTO_TEST_CASE(FromFile)
 {
-  Name identity("/TestValidatorConfig/NameFilter");
-  identity.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity), "trust-anchor-1.cert"));
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
-
-  Name dataName1("/simple/equal");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  Name dataName2("/simple/different");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity)));
-
-  std::string CONFIG_1 =
-    "rule\n"
-    "{\n"
-    "  id \"Simple Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /simple/equal\n"
-    "    relation equal\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      name ";
-
-  std::string CONFIG_2 =
-    "\n"
-    "      relation equal\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-1.cert\"\n"
-    "}\n";
-  const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
+  validator.load(configFile);
+  BOOST_CHECK_EQUAL(validator.m_policyConfig.m_isConfigured, true);
+  BOOST_CHECK_THROW(validator.load(configFile), std::logic_error);
 }
 
-BOOST_AUTO_TEST_CASE(NameFilter2)
+BOOST_AUTO_TEST_CASE(FromString)
 {
-  Name identity("/TestValidatorConfig/NameFilter2");
-  identity.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity), "trust-anchor-2.cert"));
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
-
-  Name dataName1("/simple/isPrefixOf");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  Name dataName2("/simple/notPrefixOf");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity)));
-
-  Name dataName3("/simple/isPrefixOf/anotherLevel");
-  shared_ptr<Data> data3 = make_shared<Data>(dataName3);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data3, security::signingByIdentity(identity)));
-
-  std::string CONFIG_1 =
-    "rule\n"
-    "{\n"
-    "  id \"Simple2 Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /simple/isPrefixOf\n"
-    "    relation is-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      name ";
-
-  std::string CONFIG_2 =
-    "\n"
-    "      relation equal\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-2.cert\"\n"
-    "}\n";
-  const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*data3,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
+  validator.load(config, "config-file-from-string");
+  BOOST_CHECK_EQUAL(validator.m_policyConfig.m_isConfigured, true);
+  BOOST_CHECK_THROW(validator.load(configFile), std::logic_error);
 }
 
-BOOST_AUTO_TEST_CASE(NameFilter3)
+BOOST_AUTO_TEST_CASE(FromIstream)
 {
-  Name identity("/TestValidatorConfig/NameFilter3");
-  identity.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity), "trust-anchor-3.cert"));
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
-
-  Name dataName1("/simple/isStrictPrefixOf");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  Name dataName2("/simple");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity)));
-
-  Name dataName3("/simple/isStrictPrefixOf/anotherLevel");
-  shared_ptr<Data> data3 = make_shared<Data>(dataName3);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data3, security::signingByIdentity(identity)));
-
-  std::string CONFIG_1 =
-    "rule\n"
-    "{\n"
-    "  id \"Simple3 Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /simple/isStrictPrefixOf\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      name ";
-
-  std::string CONFIG_2 =
-    "\n"
-    "      relation equal\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-3.cert\"\n"
-    "}\n";
-  const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*data3,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
+  std::istringstream is(config);
+  validator.load(is, "config-file-from-istream");
+  BOOST_CHECK_EQUAL(validator.m_policyConfig.m_isConfigured, true);
+  BOOST_CHECK_THROW(validator.load(configFile), std::logic_error);
 }
 
-BOOST_AUTO_TEST_CASE(NameFilter4)
+BOOST_AUTO_TEST_CASE(FromSection)
 {
-  Name identity("/TestValidatorConfig/NameFilter4");
-  identity.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity), "trust-anchor-4.cert"));
-  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
-
-  Name dataName1("/simple/regex");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  Name dataName2("/simple/regex-wrong");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity)));
-
-  Name dataName3("/simple/regex/correct");
-  shared_ptr<Data> data3 = make_shared<Data>(dataName3);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data3, security::signingByIdentity(identity)));
-
-  std::string CONFIG_1 =
-    "rule\n"
-    "{\n"
-    "  id \"Simple3 Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    regex ^<simple><regex>\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      name ";
-
-  std::string CONFIG_2 =
-    "\n"
-    "      relation equal\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-4.cert\"\n"
-    "}\n";
-  const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*data3,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
+  validator.load(v2::validator_config::tests::makeSection(config), "config-file-from-section");
+  BOOST_CHECK_EQUAL(validator.m_policyConfig.m_isConfigured, true);
+  BOOST_CHECK_THROW(validator.load(configFile), std::logic_error);
 }
 
-BOOST_AUTO_TEST_CASE(KeyLocatorNameChecker1)
-{
-  Name identity("/TestValidatorConfig/KeyLocatorNameChecker1");
-  identity.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity), "trust-anchor-5.cert"));
-
-  Name dataName1 = identity;
-  dataName1.append("1");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  Name dataName2 = identity;
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity)));
-
-  Name dataName3("/TestValidatorConfig/KeyLocatorNameChecker1");
-  shared_ptr<Data> data3 = make_shared<Data>(dataName3);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data3, security::signingByIdentity(identity)));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"Simple3 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"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-5.cert\"\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*data3,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-}
-
-BOOST_AUTO_TEST_CASE(FixedSignerChecker)
-{
-  Name identity("/TestValidatorConfig/FixedSignerChecker");
-
-  Name identity1 = identity;
-  identity1.append("1").appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity1), "trust-anchor-7.cert"));
-
-  Name identity2 = identity;
-  identity2.append("2").appendVersion();
-  addIdentity(identity2);
-
-  Name dataName1 = identity;
-  dataName1.append("data").appendVersion();
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity1)));
-
-  Name dataName2 = identity;
-  dataName2.append("data").appendVersion();
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity2)));
-
-  Name interestName("/TestValidatorConfig/FixedSignerChecker/fakeSigInfo/fakeSigValue");
-  shared_ptr<Interest> interest = make_shared<Interest>(interestName);
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Data Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/FixedSignerChecker\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-7.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Interest Rule\"\n"
-    "  for interest\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/FixedSignerChecker\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-7.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*interest,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-}
-
-BOOST_AUTO_TEST_CASE(MultiCheckers)
-{
-  Name identity1("/TestValidatorConfig/MultiCheckers/");
-  identity1.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity1), "trust-anchor-multi-1.cert"));
-
-  Name identity2("/TestValidatorConfig/");
-  identity2.appendVersion();
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity2), "trust-anchor-multi-2.cert"));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"Simple Rule01\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /\n"
-    "    relation is-prefix-of\n"
-    "  }\n"
-    "  checker\n" // checker 1, signer should have prefix /TestValidatorConfig/MultiCheckers
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      name /TestValidatorConfig/MultiCheckers/\n"
-    "      relation is-prefix-of\n"
-    "    }\n"
-    "  }\n"
-    "  checker\n" // checker 2, data should have same prefix of its signer
-    "  {\n"
-    "    type hierarchical\n"
-    "    sig-type rsa-sha256\n"
-    "  }\n"
-    "  checker\n" // checker 3, the signer should be identity1
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-multi-1.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-multicheckers.conf"));
-
-  ValidatorConfig validator;
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-  conf::Checker& checker0 = *validator.m_dataRules.front()->m_checkers[0];
-  conf::Checker& checker1 = *validator.m_dataRules.front()->m_checkers[1];
-  conf::Checker& checker2 = *validator.m_dataRules.front()->m_checkers[2];
-
-  auto data1 = makeData(Name(identity1).append("Test"));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity1)));
-  BOOST_CHECK_EQUAL(checker0.check(*data1), 0);
-  BOOST_CHECK_EQUAL(checker1.check(*data1), 0);
-  BOOST_CHECK_EQUAL(checker2.check(*data1), 1);
-
-  auto data2 = makeData(Name(identity2).append("Data2"));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(identity2)));
-  BOOST_CHECK_EQUAL(checker0.check(*data2), -1);
-  BOOST_CHECK_EQUAL(checker1.check(*data2), 0);
-  BOOST_CHECK_EQUAL(checker2.check(*data2), -1);
-
-  auto data3 = makeData(Name(identity2).append("Data3"));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data3, security::signingByIdentity(identity1)));
-  BOOST_CHECK_EQUAL(checker0.check(*data3), 0);
-  BOOST_CHECK_EQUAL(checker1.check(*data3), -1);
-  BOOST_CHECK_EQUAL(checker2.check(*data3), 1);
-
-  auto data4 = makeData("/Data4");
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data4, security::signingByIdentity(identity2)));
-  BOOST_CHECK_EQUAL(checker0.check(*data4), -1);
-  BOOST_CHECK_EQUAL(checker1.check(*data4), -1);
-  BOOST_CHECK_EQUAL(checker2.check(*data4), -1);
-
-  int count = 0;
-  validator.validate(*data1,
-    [&] (const shared_ptr<const Data>&) {
-      BOOST_CHECK(true);
-      count++;
-    },
-    [] (const shared_ptr<const Data>&, const std::string& str) { BOOST_CHECK(false); });
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [&] (const shared_ptr<const Data>&, const std::string& str) {
-      BOOST_CHECK(true);
-      count++;
-    });
-
-  validator.validate(*data3,
-    [&] (const shared_ptr<const Data>&) {
-      BOOST_CHECK(true);
-      count++;
-    },
-    [] (const shared_ptr<const Data>&, const std::string& str) { BOOST_CHECK(false); });
-
-  validator.validate(*data4,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [&] (const shared_ptr<const Data>&, const std::string& str) {
-      BOOST_CHECK(true);
-      count++;
-    });
-
-  BOOST_CHECK_EQUAL(count, 4);
-}
-
-BOOST_AUTO_TEST_CASE(Reset)
-{
-  Name root("/TestValidatorConfig/Reload");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(root), "trust-anchor-8.cert"));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"NRD Prefix Registration Command Rule\"\n"
-    "  for interest\n"
-    "  filter\n"
-    "  {\n"
-    "    type name\n"
-    "    regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>$\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "rule\n"
-    "{\n"
-    "  id \"Testbed Hierarchy Rule\"\n"
-    "  for data\n"
-    "  filter\n"
-    "  {\n"
-    "    type name\n"
-    "    regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type hierarchical\n"
-    "    sig-type rsa-sha256\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-8.cert\"\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-  BOOST_CHECK_EQUAL(validator.isEmpty(), false);
-
-  validator.reset();
-  BOOST_CHECK(validator.isEmpty());
-}
-
-BOOST_AUTO_TEST_CASE(TrustAnchorWildcard)
-{
-  Name identity("/TestValidatorConfig/Wildcard");
-  identity.appendVersion();
-  addIdentity(identity);
-
-  Name dataName1("/any/data");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(identity)));
-
-  std::string CONFIG =
-    "trust-anchor\n"
-    "{\n"
-    "  type any\n"
-    "}\n";
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-}
-
-BOOST_AUTO_TEST_CASE(SignedInterestTest)
-{
-  Name certName = addIdentity("/TestValidatorConfig/SignedInterestTest");
-  BOOST_REQUIRE(saveIdentityCertificate(certName, "trust-anchor-9.cert"));
-
-  Name interestName("/TestValidatorConfig/SignedInterestTest");
-  Name interestName1 = interestName;
-  interestName1.append("1");
-  shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
-  Name interestName2 = interestName;
-  interestName2.append("2");
-  shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
-
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest1, security::signingByCertificate(certName)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest2, security::signingByCertificate(certName)));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Interest Rule\"\n"
-    "  for interest\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/SignedInterestTest\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-9.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-  advanceClocks(time::milliseconds(10));
-}
-
-BOOST_AUTO_TEST_CASE(MaxKeyTest)
-{
-  Name identity("/TestValidatorConfig/MaxKeyTest");
-
-  Name identity1 = identity;
-  identity1.append("Key1");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity1), "trust-anchor-10-1.cert"));
-
-  Name identity2 = identity;
-  identity2.append("Key2");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity2), "trust-anchor-10-2.cert"));
-
-  Name identity3 = identity;
-  identity3.append("Key3");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity3), "trust-anchor-10-3.cert"));
-
-
-  Name interestName("/TestValidatorConfig/MaxKeyTest");
-  Name interestName1 = interestName;
-  interestName1.append("1");
-  shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
-  Name interestName2 = interestName;
-  interestName2.append("2");
-  shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
-  Name interestName3 = interestName;
-  interestName3.append("3");
-  shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
-
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest1, security::signingByIdentity(identity1)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest2, security::signingByIdentity(identity2)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest3, security::signingByIdentity(identity3)));
-  advanceClocks(time::milliseconds(10));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Interest Rule\"\n"
-    "  for interest\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/MaxKeyTest\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-1.cert\"\n"
-    "    }\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-2.cert\"\n"
-    "    }\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-3.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  ValidatorConfig validator(face,
-                            ValidatorConfig::DEFAULT_CERTIFICATE_CACHE,
-                            ValidatorConfig::DEFAULT_GRACE_INTERVAL,
-                            10,
-                            2,                 // Two keys can be tracked
-                            time::seconds(1)); // TTL is set to 1 sec
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest3,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  // Should succeed because identity1's key has been cleaned up due to space limit.
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-}
-
-BOOST_AUTO_TEST_CASE(MaxKeyTest2)
-{
-  Name identity("/TestValidatorConfig/MaxKeyTest");
-
-  Name identity1 = identity;
-  identity1.append("Key1");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity1), "trust-anchor-10-1.cert"));
-
-  Name identity2 = identity;
-  identity2.append("Key2");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity2), "trust-anchor-10-2.cert"));
-
-  Name identity3 = identity;
-  identity3.append("Key3");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity3), "trust-anchor-10-3.cert"));
-
-  Name identity4 = identity;
-  identity4.append("Key4");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(identity4), "trust-anchor-10-4.cert"));
-
-
-  Name interestName("/TestValidatorConfig/MaxKeyTest");
-  Name interestName1 = interestName;
-  interestName1.append("1");
-  shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
-  Name interestName2 = interestName;
-  interestName2.append("2");
-  shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
-  Name interestName3 = interestName;
-  interestName3.append("3");
-  shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
-  Name interestName4 = interestName;
-  interestName4.append("4");
-  shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
-
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest1, security::signingByIdentity(identity1)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest2, security::signingByIdentity(identity2)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest3, security::signingByIdentity(identity3)));
-  advanceClocks(time::milliseconds(10));
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest4, security::signingByIdentity(identity4)));
-  advanceClocks(time::milliseconds(10));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Interest Rule\"\n"
-    "  for interest\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/MaxKeyTest\n"
-    "    relation is-strict-prefix-of\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type rsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-1.cert\"\n"
-    "    }\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-2.cert\"\n"
-    "    }\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-3.cert\"\n"
-    "    }\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-10-4.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  ValidatorConfig validator(face,
-                            ValidatorConfig::DEFAULT_CERTIFICATE_CACHE,
-                            ValidatorConfig::DEFAULT_GRACE_INTERVAL,
-                            10,
-                            3,                 // Three keys can be tracked
-                            time::seconds(1)); // TTL is set to 1 sec
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest3,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest3,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-
-  advanceClocks(time::seconds(2));
-
-  validator.validate(*interest4,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  // Should succeed because identity1 and identity2's key has been cleaned up due to ttl limit.
-  validator.validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-
-  validator.validate(*interest3,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10));
-}
-
-BOOST_AUTO_TEST_CASE(FixedSignerChecker2)
-{
-  Name rsaIdentity("/TestValidatorConfig/FixedSignerChecker2/Rsa");
-  addIdentity(rsaIdentity, RsaKeyParams());
-
-  Name ecIdentity("/TestValidatorConfig/FixedSignerChecker2/Ec");
-  auto identity = addIdentity(ecIdentity, EcKeyParams());
-  BOOST_REQUIRE(saveIdentityCertificate(identity, "trust-anchor-11.cert"));
-
-  Name dataName("/TestValidatorConfig/FixedSignerChecker2");
-  shared_ptr<Data> dataRsa = make_shared<Data>(dataName);
-  m_keyChain.sign(*dataRsa, security::signingByIdentity(rsaIdentity));
-  shared_ptr<Data> dataEc = make_shared<Data>(dataName);
-  m_keyChain.sign(*dataEc, security::signingByIdentity(ecIdentity));
-
-  shared_ptr<Interest> interestRsa = make_shared<Interest>(dataName);
-  m_keyChain.sign(*interestRsa, security::signingByIdentity(rsaIdentity));
-  shared_ptr<Interest> interestEc = make_shared<Interest>(dataName);
-  m_keyChain.sign(*interestEc, security::signingByIdentity(ecIdentity));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Data Rule\"\n"
-    "  for data\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/FixedSignerChecker2\n"
-    "    relation equal\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type ecdsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-11.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "rule\n"
-    "{\n"
-    "  id \"FixedSignerChecker Interest Rule\"\n"
-    "  for interest\n"
-    "  filter"
-    "  {\n"
-    "    type name\n"
-    "    name /TestValidatorConfig/FixedSignerChecker2\n"
-    "    relation equal\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type fixed-signer\n"
-    "    sig-type ecdsa-sha256\n"
-    "    signer\n"
-    "    {\n"
-    "      type file\n"
-    "      file-name \"trust-anchor-11.cert\"\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  validator.validate(*dataEc,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*dataRsa,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  validator.validate(*interestEc,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-
-  validator.validate(*interestRsa,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-}
-
-
-struct FacesFixture : public ValidatorConfigFixture
-{
-  FacesFixture()
-    : face1(io, m_v2KeyChain, {true, true})
-    , face2(io, m_v2KeyChain, {true, true})
-    , readInterestOffset1(0)
-    , readDataOffset1(0)
-    , readInterestOffset2(0)
-    , readDataOffset2(0)
-  {
-  }
-
-  bool
-  passPacket()
-  {
-    bool hasPassed = false;
-
-    checkFace(face1.sentInterests, readInterestOffset1, face2, hasPassed);
-    checkFace(face1.sentData, readDataOffset1, face2, hasPassed);
-    checkFace(face2.sentInterests, readInterestOffset2, face1, hasPassed);
-    checkFace(face2.sentData, readDataOffset2, face1, hasPassed);
-
-    return hasPassed;
-  }
-
-  template<typename Packet>
-  void
-  checkFace(std::vector<Packet>& receivedPackets,
-            size_t& readPacketOffset,
-            util::DummyClientFace& receiver,
-            bool& hasPassed)
-  {
-    while (receivedPackets.size() > readPacketOffset) {
-      receiver.receive(receivedPackets[readPacketOffset]);
-      readPacketOffset++;
-      hasPassed = true;
-    }
-  }
-
-public:
-  util::DummyClientFace face1;
-  util::DummyClientFace face2;
-
-  size_t readInterestOffset1;
-  size_t readDataOffset1;
-  size_t readInterestOffset2;
-  size_t readDataOffset2;
-};
-
-BOOST_FIXTURE_TEST_CASE(HierarchicalChecker, FacesFixture)
-{
-  std::vector<v1::CertificateSubjectDescription> subjectDescription;
-
-  Name root("/TestValidatorConfig");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(root), "trust-anchor-6.cert"));
-
-
-  Name sld("/TestValidatorConfig/HierarchicalChecker");
-  addIdentity(sld);
-  advanceClocks(time::milliseconds(100));
-  Name sldKeyName = m_keyChain.generateRsaKeyPairAsDefault(sld, true);
-  shared_ptr<v1::IdentityCertificate> sldCert =
-    m_keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
-                                                  root,
-                                                  time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(7300),
-                                                  subjectDescription);
-  m_keyChain.sign(*sldCert, security::signingByIdentity(root));
-  m_keyChain.addCertificateAsIdentityDefault(*sldCert);
-
-  Name nld("/TestValidatorConfig/HierarchicalChecker/NextLevel");
-  addIdentity(nld);
-  advanceClocks(time::milliseconds(100));
-  Name nldKeyName = m_keyChain.generateRsaKeyPairAsDefault(nld, true);
-  shared_ptr<v1::IdentityCertificate> nldCert =
-    m_keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
-                                                  sld,
-                                                  time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(7300),
-                                                  subjectDescription);
-  m_keyChain.sign(*nldCert, security::signingByIdentity(sld));
-  m_keyChain.addCertificateAsIdentityDefault(*nldCert);
-
-  face1.setInterestFilter(sldCert->getName().getPrefix(-1),
-    [&] (const InterestFilter&, const Interest&) { face1.put(*sldCert); },
-    RegisterPrefixSuccessCallback(),
-    [] (const Name&, const std::string&) {});
-
-  face1.setInterestFilter(nldCert->getName().getPrefix(-1),
-    [&] (const InterestFilter&, const Interest&) { face1.put(*nldCert); },
-    RegisterPrefixSuccessCallback(),
-    [] (const Name&, const std::string&) {});
-
-  Name dataName1 = nld;
-  dataName1.append("data1");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(nld)));
-
-  Name dataName2("/ConfValidatorTest");
-  dataName2.append("data1");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(nld)));
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"Simple3 Rule\"\n"
-    "  for data\n"
-    "  checker\n"
-    "  {\n"
-    "    type hierarchical\n"
-    "    sig-type rsa-sha256\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-6.cert\"\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  auto validator = make_shared<ValidatorConfig>(&face2);
-  validator->load(CONFIG, CONFIG_PATH.c_str());
-
-  advanceClocks(time::milliseconds(2), 100);
-  validator->validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-
-  validator->validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-}
-
-BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
-{
-  advanceClocks(time::nanoseconds(1));
-
-  std::vector<v1::CertificateSubjectDescription> subjectDescription;
-
-  Name root("/TestValidatorConfig");
-  BOOST_REQUIRE(saveIdentityCertificate(addIdentity(root), "trust-anchor-8.cert"));
-
-  Name sld("/TestValidatorConfig/Nrd-1");
-  addIdentity(sld);
-  advanceClocks(time::milliseconds(100));
-  Name sldKeyName = m_keyChain.generateRsaKeyPairAsDefault(sld, true);
-  shared_ptr<v1::IdentityCertificate> sldCert =
-    m_keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
-                                                  root,
-                                                  time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(7300),
-                                                  subjectDescription);
-  m_keyChain.sign(*sldCert, security::signingByIdentity(root));
-  m_keyChain.addCertificateAsIdentityDefault(*sldCert);
-
-  Name nld("/TestValidatorConfig/Nrd-1/Nrd-2");
-  addIdentity(nld);
-  advanceClocks(time::milliseconds(100));
-  Name nldKeyName = m_keyChain.generateRsaKeyPairAsDefault(nld, true);
-  shared_ptr<v1::IdentityCertificate> nldCert =
-    m_keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
-                                                  sld,
-                                                  time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(7300),
-                                                  subjectDescription);
-  m_keyChain.sign(*nldCert, security::signingByIdentity(sld));
-  m_keyChain.addCertificateAsIdentityDefault(*nldCert);
-
-  face1.setInterestFilter(sldCert->getName().getPrefix(-1),
-    [&] (const InterestFilter&, const Interest&) { face1.put(*sldCert); },
-    RegisterPrefixSuccessCallback(),
-    [] (const Name&, const std::string&) {});
-
-  face1.setInterestFilter(nldCert->getName().getPrefix(-1),
-    [&] (const InterestFilter&, const Interest&) { face1.put(*nldCert); },
-    RegisterPrefixSuccessCallback(),
-    [] (const Name&, const std::string&) {});
-
-  advanceClocks(time::milliseconds(10));
-  Name interestName1("/localhost/nrd/register/option");
-  shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest1, security::signingByIdentity(nld)));
-
-  advanceClocks(time::milliseconds(10));
-  Name interestName2("/localhost/nrd/non-register");
-  shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest2, security::signingByIdentity(nld)));
-
-  advanceClocks(time::milliseconds(10));
-  Name interestName3("/localhost/nrd/register/option");
-  shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest3, security::signingByIdentity(root)));
-
-  advanceClocks(time::milliseconds(10));
-  Name interestName4("/localhost/nrd/register/option/timestamp/nonce/fakeSigInfo/fakeSigValue");
-  shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
-
-  const std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"NRD Prefix Registration Command Rule\"\n"
-    "  for interest\n"
-    "  filter\n"
-    "  {\n"
-    "    type name\n"
-    "    regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>$\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "rule\n"
-    "{\n"
-    "  id \"Testbed Hierarchy Rule\"\n"
-    "  for data\n"
-    "  filter\n"
-    "  {\n"
-    "    type name\n"
-    "    regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type hierarchical\n"
-    "    sig-type rsa-sha256\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type file\n"
-    "  file-name \"trust-anchor-8.cert\"\n"
-    "}\n";
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  auto validator = make_shared<ValidatorConfig>(&face2);
-  validator->load(CONFIG, CONFIG_PATH.c_str());
-
-  advanceClocks(time::milliseconds(2), 100);
-
-  // should succeed
-  validator->validate(*interest1,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-
-  // should fail
-  validator->validate(*interest2,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-
-  // should succeed
-  validator->validate(*interest3,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(false); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-
-  // should fail
-  validator->validate(*interest4,
-    [] (const shared_ptr<const Interest>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Interest>&, const std::string&) { BOOST_CHECK(true); });
-
-  do {
-    advanceClocks(time::milliseconds(2), 10);
-  } while (passPacket());
-}
-
-struct DirTestFixture : public ValidatorConfigFixture
-{
-  DirTestFixture()
-    : validator(&face, ValidatorConfig::DEFAULT_CERTIFICATE_CACHE,
-                ValidatorConfig::DEFAULT_GRACE_INTERVAL, 0)
-  {
-    certDirPath = (boost::filesystem::current_path() / std::string("test-cert-dir"));
-    boost::filesystem::create_directory(certDirPath);
-
-    firstCertPath = (boost::filesystem::current_path() /
-                     std::string("test-cert-dir") /
-                     std::string("trust-anchor-1.cert"));
-
-    secondCertPath = (boost::filesystem::current_path() /
-                      std::string("test-cert-dir") /
-                      std::string("trust-anchor-2.cert"));
-
-    firstIdentity = Name("/TestValidatorConfig/Dir/First");
-    addIdentity(firstIdentity);
-    Name firstCertName = m_keyChain.getDefaultCertificateNameForIdentity(firstIdentity);
-    firstCert = m_keyChain.getCertificate(firstCertName);
-    io::save(*firstCert, firstCertPath.string());
-
-    secondIdentity = Name("/TestValidatorConfig/Dir/Second");
-    addIdentity(secondIdentity);
-    Name secondCertName = m_keyChain.getDefaultCertificateNameForIdentity(secondIdentity);
-    secondCert = m_keyChain.getCertificate(secondCertName);
-  }
-
-  ~DirTestFixture()
-  {
-    boost::filesystem::remove_all(certDirPath);
-  }
-
-public:
-  boost::filesystem::path certDirPath;
-  boost::filesystem::path firstCertPath;
-  boost::filesystem::path secondCertPath;
-
-  Name firstIdentity;
-  Name secondIdentity;
-
-  shared_ptr<v1::IdentityCertificate> firstCert;
-  shared_ptr<v1::IdentityCertificate> secondCert;
-
-  ValidatorConfig validator;
-};
-
-BOOST_FIXTURE_TEST_CASE(TrustAnchorDir, DirTestFixture)
-{
-  advanceClocks(time::milliseconds(10));
-
-  Name dataName1("/any/data/1");
-  shared_ptr<Data> data1 = make_shared<Data>(dataName1);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data1, security::signingByIdentity(firstIdentity)));
-
-  Name dataName2("/any/data/2");
-  shared_ptr<Data> data2 = make_shared<Data>(dataName2);
-  BOOST_CHECK_NO_THROW(m_keyChain.sign(*data2, security::signingByIdentity(secondIdentity)));
-
-  std::string CONFIG =
-    "rule\n"
-    "{\n"
-    "  id \"Any Rule\"\n"
-    "  for data\n"
-    "  filter\n"
-    "  {\n"
-    "    type name\n"
-    "    regex ^<>*$\n"
-    "  }\n"
-    "  checker\n"
-    "  {\n"
-    "    type customized\n"
-    "    sig-type rsa-sha256\n"
-    "    key-locator\n"
-    "    {\n"
-    "      type name\n"
-    "      regex ^<>*$\n"
-    "    }\n"
-    "  }\n"
-    "}\n"
-    "trust-anchor\n"
-    "{\n"
-    "  type dir\n"
-    "  dir test-cert-dir\n"
-    "  refresh 1s\n"
-    "}\n";
-
-  const boost::filesystem::path CONFIG_PATH =
-    (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
-
-  validator.load(CONFIG, CONFIG_PATH.c_str());
-
-  advanceClocks(time::milliseconds(10), 20);
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10), 20);
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(false); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(true); });
-  advanceClocks(time::milliseconds(10), 20);
-
-  io::save(*secondCert, secondCertPath.string());
-  advanceClocks(time::milliseconds(10), 200);
-
-  validator.validate(*data1,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10), 20);
-
-  validator.validate(*data2,
-    [] (const shared_ptr<const Data>&) { BOOST_CHECK(true); },
-    [] (const shared_ptr<const Data>&, const std::string&) { BOOST_CHECK(false); });
-  advanceClocks(time::milliseconds(10), 20);
-}
-
-class DirectCertFetchFixture : public ValidatorConfigFixture
-{
-public:
-  DirectCertFetchFixture()
-    : clientFace(io, m_v2KeyChain, {true, true})
-    , validationResult(boost::logic::indeterminate)
-  {
-    auto certName = addIdentity(ca);
-    saveIdentityCertificate(certName, "trust-anchor-1.cert");
-    addSubCertificate(user, ca);
-
-    userCertName = m_keyChain.getDefaultCertificateNameForIdentity(user);
-    userCert = m_keyChain.getCertificate(userCertName);
-  }
-
-protected:
-  void
-  runTest(const std::function<void(const Interest&, const Interest&)> respond)
-  {
-    optional<Interest> directInterest;
-    optional<Interest> infrastructureInterest;
-    clientFace.onSendInterest.connect([&] (const Interest& interest) {
-      const Name& interestName = interest.getName();
-      if (interestName == userCert->getName().getPrefix(-1)) {
-        auto nextHopFaceIdTag = interest.getTag<lp::NextHopFaceIdTag>();
-        if (nextHopFaceIdTag != nullptr) {
-          BOOST_CHECK(!directInterest);
-          directInterest = interest;
-        }
-        else {
-          BOOST_CHECK(!infrastructureInterest);
-          infrastructureInterest = interest;
-        }
-        if (static_cast<bool>(directInterest) && static_cast<bool>(infrastructureInterest)) {
-          io.post([directInterest, infrastructureInterest, respond] {
-              respond(directInterest.value(), infrastructureInterest.value());
-            });
-          directInterest = nullopt;
-          infrastructureInterest = nullopt;
-        }
-      }
-    });
-
-    const boost::filesystem::path CONFIG_PATH =
-      (boost::filesystem::current_path() / std::string("unit-test-direct.conf"));
-    ValidatorConfig validator(&clientFace);
-    validator.load(CONFIG, CONFIG_PATH.c_str());
-    validator.setDirectCertFetchEnabled(true);
-
-    shared_ptr<Interest> interest = make_shared<Interest>(interestName);
-    interest->setTag(make_shared<lp::IncomingFaceIdTag>(123));
-    BOOST_CHECK_NO_THROW(m_keyChain.sign(*interest, security::signingByIdentity(user)));
-
-    validator.validate(*interest,
-                       [&] (const shared_ptr<const Interest>&) {
-                         BOOST_CHECK(boost::logic::indeterminate(validationResult));
-                         validationResult = true;
-                       },
-                       [&] (const shared_ptr<const Interest>&, const std::string& s) {
-                         BOOST_CHECK(boost::logic::indeterminate(validationResult));
-                         validationResult = false;
-                       });
-
-    advanceClocks(time::milliseconds(200), 60);
-
-    BOOST_CHECK(!boost::logic::indeterminate(validationResult));
-  }
-
-public:
-  util::DummyClientFace clientFace;
-  const Name ca = Name("/DirectCertFetch");
-  const Name user = Name("/DirectCertFetch/user");
-  const Name interestName = Name("/DirectCertFetch/user/tag-interest");
-  const std::string CONFIG = R"_TEXT_(
-      rule
-      {
-        id "RuleForInterest"
-        for interest
-        checker
-        {
-          type hierarchical
-          sig-type rsa-sha256
-        }
-      }
-      rule
-      {
-        id "RuleForData"
-        for data
-        filter
-        {
-          type name
-          regex ^<>*$
-        }
-        checker
-        {
-          type customized
-          sig-type rsa-sha256
-          key-locator
-        {
-          type name
-           regex ^<>*$
-          }
-        }
-      }
-      trust-anchor
-      {
-        type file
-        file-name "trust-anchor-1.cert"
-      }
-      )_TEXT_";
-  boost::logic::tribool validationResult;
-  Name userCertName;
-  shared_ptr<v1::IdentityCertificate> userCert;
-};
-
-BOOST_FIXTURE_TEST_SUITE(DirectCertFetch, DirectCertFetchFixture)
-
-BOOST_AUTO_TEST_CASE(CertFetchSuccess)
-{
-  runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) {
-      this->clientFace.receive(*userCert);
-    });
-
-  BOOST_CHECK_EQUAL(validationResult, true);
-}
-
-BOOST_AUTO_TEST_CASE(CertFetchTimeout)
-{
-  // In this test case, certificate request would time out
-  runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) { });
-
-  BOOST_CHECK_EQUAL(validationResult, false);
-}
-
-BOOST_AUTO_TEST_CASE(CertFetchNack)
-{
-  runTest([this] (const Interest& directInterest, const Interest& infrastructureInterest) {
-      lp::Nack nackInfrastructureInterest(infrastructureInterest);
-      nackInfrastructureInterest.setHeader(lp::NackHeader().setReason(lp::NackReason::NO_ROUTE));
-      this->clientFace.receive(nackInfrastructureInterest);
-    });
-
-  BOOST_CHECK_EQUAL(validationResult, false);
-}
+BOOST_AUTO_TEST_SUITE_END() // Loads
 
-BOOST_AUTO_TEST_SUITE_END() // DirectCertFetch
 BOOST_AUTO_TEST_SUITE_END() // TestValidatorConfig
 BOOST_AUTO_TEST_SUITE_END() // Security
 
diff --git a/tests/unit-tests/util/placeholders.t.cpp b/tests/unit-tests/util/placeholders.t.cpp
index 032b088..64c1dbf 100644
--- a/tests/unit-tests/util/placeholders.t.cpp
+++ b/tests/unit-tests/util/placeholders.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,9 +24,9 @@
 // interest.hpp includes common.hpp; common.hpp shouldn't be used from external program
 #include "interest.hpp"
 
-// validator-config.hpp indirectly includes <boost/property_tree/ptree.hpp>
+// util/config-file.hpp indirectly includes <boost/property_tree/ptree.hpp>
 // which in turn imports Boost placeholders
-#include "security/validator-config.hpp"
+#include "util/config-file.hpp"
 
 // It's intentional to write "using namespace",
 // to simulate an external program linked against ndn-cxx.