diff --git a/src/security/conf/checker.hpp b/src/security/conf/checker.hpp
deleted file mode 100644
index b928906..0000000
--- a/src/security/conf/checker.hpp
+++ /dev/null
@@ -1,483 +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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_CONF_CHECKER_HPP
-#define NDN_SECURITY_CONF_CHECKER_HPP
-
-#include "common.hpp"
-
-#include "key-locator-checker.hpp"
-#include "../../util/io.hpp"
-#include "../validator.hpp"
-#include "../v1/identity-certificate.hpp"
-
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace security {
-namespace conf {
-
-class Checker
-{
-public:
-  typedef function<void(const shared_ptr<const Interest>&)> OnInterestChecked;
-  typedef function<void(const shared_ptr<const Interest>&,
-                        const std::string&)> OnInterestCheckFailed;
-  typedef function<void(const shared_ptr<const Data>&)> OnDataChecked;
-  typedef function<void(const shared_ptr<const Data>&, const std::string&)> OnDataCheckFailed;
-
-  virtual
-  ~Checker()
-  {
-  }
-
-  /**
-   * @brief check if data satisfies condition defined in the specific checker implementation
-   *
-   * @param data Data packet
-   * @retval -1 if data is immediately invalid
-   * @retval  1 if data is immediately valid
-   * @retval  0 if further signature verification is needed.
-   */
-  virtual int8_t
-  check(const Data& data) = 0;
-
-  /**
-   * @brief check if interest satisfies condition defined in the specific checker implementation
-   *
-   * @param interest Interest packet
-   * @retval -1 if interest is immediately invalid
-   * @retval  1 if interest is immediately valid
-   * @retval  0 if further signature verification is needed.
-   */
-  virtual int8_t
-  check(const Interest& interest) = 0;
-};
-
-class CustomizedChecker : public Checker
-{
-public:
-  CustomizedChecker(uint32_t sigType,
-                    shared_ptr<KeyLocatorChecker> keyLocatorChecker)
-    : m_sigType(sigType)
-    , m_keyLocatorChecker(keyLocatorChecker)
-  {
-    switch (sigType) {
-      case tlv::SignatureSha256WithRsa:
-      case tlv::SignatureSha256WithEcdsa: {
-        if (!static_cast<bool>(m_keyLocatorChecker))
-          BOOST_THROW_EXCEPTION(Error("Strong signature requires KeyLocatorChecker"));
-        return;
-      }
-      case tlv::DigestSha256:
-        return;
-      default:
-        BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
-    }
-  }
-
-  int8_t
-  check(const Data& data) override
-  {
-    return check(data, data.getSignature());
-  }
-
-  int8_t
-  check(const Interest& interest) override
-  {
-    try {
-      const Name& interestName = interest.getName();
-      Signature signature(interestName[command_interest::POS_SIG_INFO].blockFromValue(),
-                          interestName[command_interest::POS_SIG_VALUE].blockFromValue());
-      return check(interest, signature);
-    }
-    catch (const Signature::Error& e) {
-      // Invalid signature
-      return -1;
-    }
-    catch (const tlv::Error& e) {
-      // Cannot decode signature related TLVs
-      return -1;
-    }
-  }
-
-private:
-  template<class Packet>
-  int8_t
-  check(const Packet& packet, const Signature& signature)
-  {
-    if (m_sigType != signature.getType()) {
-      // Signature type does not match
-      return -1;
-    }
-
-    if (signature.getType() == tlv::DigestSha256)
-      return 0;
-
-    try {
-      switch (signature.getType()) {
-        case tlv::SignatureSha256WithRsa:
-        case tlv::SignatureSha256WithEcdsa: {
-          if (!signature.hasKeyLocator()) {
-            // Missing KeyLocator in SignatureInfo
-            return -1;
-          }
-          break;
-        }
-        default: {
-          // Unsupported signature type
-          return -1;
-        }
-      }
-    }
-    catch (const KeyLocator::Error& e) {
-      // Cannot decode KeyLocator
-      return -1;
-    }
-    catch (const tlv::Error& e) {
-      // Cannot decode signature
-      return -1;
-    }
-
-    std::string failInfo;
-    if (m_keyLocatorChecker->check(packet, signature.getKeyLocator(), failInfo))
-      return 0;
-    else {
-      return -1;
-    }
-  }
-
-private:
-  uint32_t m_sigType;
-  shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
-};
-
-class HierarchicalChecker : public CustomizedChecker
-{
-public:
-  explicit
-  HierarchicalChecker(uint32_t sigType)
-    : CustomizedChecker(sigType,
-        make_shared<HyperKeyLocatorNameChecker>("^(<>*)$", "\\1",
-                                                "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                                "\\1\\2",
-                                                KeyLocatorChecker::RELATION_IS_PREFIX_OF))
-  {
-  }
-};
-
-class FixedSignerChecker : public Checker
-{
-public:
-  FixedSignerChecker(uint32_t sigType,
-                     const std::vector<shared_ptr<v1::IdentityCertificate>>& signers)
-    : m_sigType(sigType)
-  {
-    for (std::vector<shared_ptr<v1::IdentityCertificate>>::const_iterator it = signers.begin();
-         it != signers.end(); it++)
-      m_signers[(*it)->getName().getPrefix(-1)] = (*it);
-
-    if (sigType != tlv::SignatureSha256WithRsa &&
-        sigType != tlv::SignatureSha256WithEcdsa) {
-      BOOST_THROW_EXCEPTION(Error("FixedSigner is only meaningful for strong signature type"));
-    }
-  }
-
-  int8_t
-  check(const Data& data) override
-  {
-    return check(data, data.getSignature());
-  }
-
-  int8_t
-  check(const Interest& interest) override
-  {
-    try {
-      const Name& interestName = interest.getName();
-      Signature signature(interestName[command_interest::POS_SIG_INFO].blockFromValue(),
-                          interestName[command_interest::POS_SIG_VALUE].blockFromValue());
-      return check(interest, signature);
-    }
-    catch (const Signature::Error& e) {
-      // Invalid signature
-      return -1;
-    }
-    catch (const tlv::Error& e) {
-      // Cannot decode signature related TLVs
-      return -1;
-    }
-  }
-
-private:
-  template<class Packet>
-  int8_t
-  check(const Packet& packet, const Signature& signature)
-  {
-    if (m_sigType != signature.getType()) {
-      // Signature type does not match
-      return -1;
-    }
-
-    if (signature.getType() == tlv::DigestSha256) {
-      // FixedSigner does not allow Sha256 signature type
-      return -1;
-    }
-
-    try {
-      switch (signature.getType()) {
-        case tlv::SignatureSha256WithRsa:
-        case tlv::SignatureSha256WithEcdsa: {
-          if (!signature.hasKeyLocator()) {
-            // Missing KeyLocator in SignatureInfo
-            return -1;
-          }
-          break;
-        }
-
-        default: {
-          // Unsupported signature type
-          return -1;
-        }
-      }
-
-      const Name& keyLocatorName = signature.getKeyLocator().getName();
-
-      if (m_signers.find(keyLocatorName) == m_signers.end()) {
-        // Signer is not in the fixed signer list
-        return -1;
-      }
-
-      if (Validator::verifySignature(packet, signature,
-                                     m_signers[keyLocatorName]->getPublicKeyInfo())) {
-        return 1;
-      }
-      else {
-        // Signature cannot be validated
-        return -1;
-      }
-    }
-    catch (const KeyLocator::Error& e) {
-      // KeyLocator does not have name
-      return -1;
-    }
-    catch (const tlv::Error& e) {
-      // Cannot decode signature
-      return -1;
-    }
-  }
-
-private:
-  typedef std::map<Name, shared_ptr<v1::IdentityCertificate>> SignerList;
-  uint32_t m_sigType;
-  SignerList m_signers;
-};
-
-class CheckerFactory
-{
-public:
-  /**
-   * @brief create a checker from configuration file.
-   *
-   * @param configSection The section containing the definition of checker.
-   * @param configFilename The configuration file name.
-   * @return a shared pointer to the created checker.
-   */
-  static shared_ptr<Checker>
-  create(const ConfigSection& configSection, const std::string& configFilename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-
-    // Get checker.type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.type>"));
-
-    std::string type = propertyIt->second.data();
-
-    if (boost::iequals(type, "customized"))
-      return createCustomizedChecker(configSection, configFilename);
-    else if (boost::iequals(type, "hierarchical"))
-      return createHierarchicalChecker(configSection, configFilename);
-    else if (boost::iequals(type, "fixed-signer"))
-      return createFixedSignerChecker(configSection, configFilename);
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported checker type: " + type));
-  }
-
-private:
-  static shared_ptr<Checker>
-  createCustomizedChecker(const ConfigSection& configSection,
-                          const std::string& configFilename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-    propertyIt++;
-
-    // Get checker.sig-type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
-
-    std::string sigType = propertyIt->second.data();
-    propertyIt++;
-
-    // Get checker.key-locator
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator>"));
-
-    shared_ptr<KeyLocatorChecker> keyLocatorChecker =
-      KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
-    propertyIt++;
-
-    if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
-
-    return make_shared<CustomizedChecker>(getSigType(sigType), keyLocatorChecker);
-  }
-
-  static shared_ptr<Checker>
-  createHierarchicalChecker(const ConfigSection& configSection,
-                            const std::string& configFilename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-    propertyIt++;
-
-    // Get checker.sig-type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
-
-    std::string sigType = propertyIt->second.data();
-    propertyIt++;
-
-    if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
-
-    return make_shared<HierarchicalChecker>(getSigType(sigType));
-  }
-
-  static shared_ptr<Checker>
-  createFixedSignerChecker(const ConfigSection& configSection,
-                           const std::string& configFilename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-    propertyIt++;
-
-    // Get checker.sig-type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
-
-    std::string sigType = propertyIt->second.data();
-    propertyIt++;
-
-    std::vector<shared_ptr<v1::IdentityCertificate>> signers;
-    for (; propertyIt != configSection.end(); propertyIt++) {
-      if (!boost::iequals(propertyIt->first, "signer"))
-        BOOST_THROW_EXCEPTION(Error("Expect <checker.signer> but get <checker." +
-                                    propertyIt->first + ">"));
-
-      signers.push_back(getSigner(propertyIt->second, configFilename));
-    }
-
-    if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
-
-    return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
-                                                                 signers));
-  }
-
-  static shared_ptr<v1::IdentityCertificate>
-  getSigner(const ConfigSection& configSection, const std::string& configFilename)
-  {
-    using namespace boost::filesystem;
-
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-
-    // Get checker.signer.type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.type>"));
-
-    std::string type = propertyIt->second.data();
-    propertyIt++;
-
-    if (boost::iequals(type, "file")) {
-      // Get checker.signer.file-name
-      if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
-        BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.file-name>"));
-
-      path certfilePath = absolute(propertyIt->second.data(),
-                                   path(configFilename).parent_path());
-      propertyIt++;
-
-      if (propertyIt != configSection.end())
-        BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
-
-      shared_ptr<v1::IdentityCertificate> idCert
-        = io::load<v1::IdentityCertificate>(certfilePath.c_str());
-
-      if (static_cast<bool>(idCert))
-        return idCert;
-      else
-        BOOST_THROW_EXCEPTION(Error("Cannot read certificate from file: " +
-                                    certfilePath.native()));
-    }
-    else if (boost::iequals(type, "base64")) {
-      // Get checker.signer.base64-string
-      if (propertyIt == configSection.end() ||
-          !boost::iequals(propertyIt->first, "base64-string"))
-        BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.base64-string>"));
-
-      std::stringstream ss(propertyIt->second.data());
-      propertyIt++;
-
-      if (propertyIt != configSection.end())
-        BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
-
-      shared_ptr<v1::IdentityCertificate> idCert = io::load<v1::IdentityCertificate>(ss);
-
-      if (static_cast<bool>(idCert))
-        return idCert;
-      else
-        BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from string"));
-    }
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported checker.signer type: " + type));
-  }
-
-  static uint32_t
-  getSigType(const std::string& sigType)
-  {
-    if (boost::iequals(sigType, "rsa-sha256"))
-      return tlv::SignatureSha256WithRsa;
-    else if (boost::iequals(sigType, "ecdsa-sha256"))
-      return tlv::SignatureSha256WithEcdsa;
-    else if (boost::iequals(sigType, "sha256"))
-      return tlv::DigestSha256;
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
-  }
-};
-
-} // namespace conf
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_CONF_CHECKER_HPP
diff --git a/src/security/conf/filter.hpp b/src/security/conf/filter.hpp
deleted file mode 100644
index 2ebc4e6..0000000
--- a/src/security/conf/filter.hpp
+++ /dev/null
@@ -1,238 +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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_CONF_FILTER_HPP
-#define NDN_SECURITY_CONF_FILTER_HPP
-
-#include "../../common.hpp"
-#include "../../data.hpp"
-#include "../../interest.hpp"
-#include "../../util/regex.hpp"
-#include "../security-common.hpp"
-#include <boost/algorithm/string.hpp>
-
-#include "common.hpp"
-
-namespace ndn {
-namespace security {
-namespace conf {
-
-/**
- * @brief Filter is one of the classes used by ValidatorConfig.
- *
- * The ValidatorConfig class consists of a set of rules.
- * The Filter class is a part of a rule and is used to match packet.
- * Matched packets will be checked against the checkers defined in the rule.
- */
-
-class Filter
-{
-public:
-
-  virtual
-  ~Filter()
-  {
-  }
-
-  bool
-  match(const Data& data)
-  {
-    return matchName(data.getName());
-  }
-
-  bool
-  match(const Interest& interest)
-  {
-    if (interest.getName().size() < command_interest::MIN_SIZE)
-      return false;
-
-    Name unsignedName = interest.getName().getPrefix(-command_interest::MIN_SIZE);
-    return matchName(unsignedName);
-  }
-
-protected:
-  virtual bool
-  matchName(const Name& name) = 0;
-};
-
-class RelationNameFilter : public Filter
-{
-public:
-  enum Relation
-    {
-      RELATION_EQUAL,
-      RELATION_IS_PREFIX_OF,
-      RELATION_IS_STRICT_PREFIX_OF
-    };
-
-  RelationNameFilter(const Name& name, Relation relation)
-    : m_name(name)
-    , m_relation(relation)
-  {
-  }
-
-  virtual
-  ~RelationNameFilter()
-  {
-  }
-
-protected:
-  virtual bool
-  matchName(const Name& name)
-  {
-    switch (m_relation)
-      {
-      case RELATION_EQUAL:
-        return (name == m_name);
-      case RELATION_IS_PREFIX_OF:
-        return m_name.isPrefixOf(name);
-      case RELATION_IS_STRICT_PREFIX_OF:
-        return (m_name.isPrefixOf(name) && m_name.size() < name.size());
-      default:
-        return false;
-      }
-  }
-
-private:
-  Name m_name;
-  Relation m_relation;
-};
-
-class RegexNameFilter : public Filter
-{
-public:
-  explicit
-  RegexNameFilter(const Regex& regex)
-    : m_regex(regex)
-  {
-  }
-
-  virtual
-  ~RegexNameFilter()
-  {
-  }
-
-protected:
-  virtual bool
-  matchName(const Name& name)
-  {
-    return m_regex.match(name);
-  }
-
-private:
-  Regex m_regex;
-};
-
-class FilterFactory
-{
-public:
-  static shared_ptr<Filter>
-  create(const ConfigSection& configSection)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <filter.type>!"));
-
-    std::string type = propertyIt->second.data();
-
-    if (boost::iequals(type, "name"))
-      return createNameFilter(configSection);
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported filter.type: " + type));
-  }
-private:
-  static shared_ptr<Filter>
-  createNameFilter(const ConfigSection& configSection)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-    propertyIt++;
-
-    if (propertyIt == configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect more properties for filter(name)"));
-
-    if (boost::iequals(propertyIt->first, "name"))
-      {
-        // Get filter.name
-        Name name;
-        try
-          {
-            name = Name(propertyIt->second.data());
-          }
-        catch (Name::Error& e)
-          {
-            BOOST_THROW_EXCEPTION(Error("Wrong filter.name: " + propertyIt->second.data()));
-          }
-
-        propertyIt++;
-
-        // Get filter.relation
-        if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
-          BOOST_THROW_EXCEPTION(Error("Expect <filter.relation>!"));
-
-        std::string relationString = propertyIt->second.data();
-        propertyIt++;
-
-        RelationNameFilter::Relation relation;
-        if (boost::iequals(relationString, "equal"))
-          relation = RelationNameFilter::RELATION_EQUAL;
-        else if (boost::iequals(relationString, "is-prefix-of"))
-          relation = RelationNameFilter::RELATION_IS_PREFIX_OF;
-        else if (boost::iequals(relationString, "is-strict-prefix-of"))
-          relation = RelationNameFilter::RELATION_IS_STRICT_PREFIX_OF;
-        else
-          BOOST_THROW_EXCEPTION(Error("Unsupported relation: " + relationString));
-
-
-        if (propertyIt != configSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of filter!"));
-
-        return make_shared<RelationNameFilter>(name, relation);
-      }
-    else if (boost::iequals(propertyIt->first, "regex"))
-      {
-        std::string regexString = propertyIt->second.data();
-        propertyIt++;
-
-        if (propertyIt != configSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of filter!"));
-
-        try
-          {
-            return shared_ptr<RegexNameFilter>(new RegexNameFilter(regexString));
-          }
-        catch (Regex::Error& e)
-          {
-            BOOST_THROW_EXCEPTION(Error("Wrong filter.regex: " + regexString));
-          }
-      }
-    else
-      BOOST_THROW_EXCEPTION(Error("Wrong filter(name) properties"));
-  }
-};
-
-} // namespace conf
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_CONF_FILTER_HPP
diff --git a/src/security/conf/key-locator-checker.hpp b/src/security/conf/key-locator-checker.hpp
deleted file mode 100644
index 04f43e0..0000000
--- a/src/security/conf/key-locator-checker.hpp
+++ /dev/null
@@ -1,389 +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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP
-#define NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP
-
-#include "../../common.hpp"
-#include "../../data.hpp"
-#include "../../interest.hpp"
-#include "../../util/regex.hpp"
-#include "../security-common.hpp"
-#include <boost/algorithm/string.hpp>
-
-#include "common.hpp"
-
-namespace ndn {
-namespace security {
-namespace conf {
-
-class KeyLocatorCheckerFactory;
-
-/**
- * @brief KeyLocatorChecker is one of the classes used by ValidatorConfig.
- *
- * The ValidatorConfig class consists of a set of rules.
- * The KeyLocatorChecker class is part of a rule and is used to check if the KeyLocator field of a
- * packet satisfy the requirements.
- */
-
-
-class KeyLocatorChecker
-{
-public:
-  enum Relation {
-    RELATION_EQUAL,
-    RELATION_IS_PREFIX_OF,
-    RELATION_IS_STRICT_PREFIX_OF
-  };
-
-  virtual
-  ~KeyLocatorChecker()
-  {
-  }
-
-  bool
-  check(const Data& data,
-        const KeyLocator& keyLocator,
-        std::string& failInfo)
-  {
-    return check(data.getName(), keyLocator, failInfo);
-  }
-
-  bool
-  check(const Interest& interest,
-        const KeyLocator& keyLocator,
-        std::string& failInfo)
-  {
-    if (interest.getName().size() < command_interest::MIN_SIZE)
-      {
-        failInfo = "No Signature";
-        return false;
-      }
-
-    Name signedName = interest.getName().getPrefix(-command_interest::MIN_SIZE);
-    return check(signedName, keyLocator, failInfo);
-  }
-
-protected:
-
-  virtual bool
-  check(const Name& packetName,
-        const KeyLocator& keyLocator,
-        std::string& failInfo) = 0;
-
-  bool
-  checkRelation(const Relation& relation, const Name& name1, const Name& name2)
-  {
-    switch (relation)
-      {
-      case RELATION_EQUAL:
-        return (name1 == name2);
-      case RELATION_IS_PREFIX_OF:
-        return name1.isPrefixOf(name2);
-      case RELATION_IS_STRICT_PREFIX_OF:
-        return (name1.isPrefixOf(name2) && name1 != name2);
-      default:
-        return false;
-      }
-  }
-};
-
-class RelationKeyLocatorNameChecker : public KeyLocatorChecker
-{
-public:
-  RelationKeyLocatorNameChecker(const Name& name,
-                                const KeyLocatorChecker::Relation& relation)
-    : m_name(name)
-    , m_relation(relation)
-  {
-  }
-
-protected:
-  virtual bool
-  check(const Name& packetName,
-        const KeyLocator& keyLocator,
-        std::string& failInfo)
-  {
-    try
-      {
-        if (checkRelation(m_relation, m_name, keyLocator.getName()))
-          return true;
-
-        failInfo = "KeyLocatorChecker failed!";
-        return false;
-      }
-    catch (KeyLocator::Error& e)
-      {
-        failInfo = "KeyLocator does not have name";
-        return false;
-      }
-  }
-
-private:
-  Name m_name;
-  KeyLocatorChecker::Relation m_relation;
-};
-
-class RegexKeyLocatorNameChecker : public KeyLocatorChecker
-{
-public:
-  explicit
-  RegexKeyLocatorNameChecker(const Regex& regex)
-    : m_regex(regex)
-  {
-  }
-
-protected:
-  virtual bool
-  check(const Name& packetName,
-        const KeyLocator& keyLocator,
-        std::string& failInfo)
-  {
-    try
-      {
-        if (m_regex.match(keyLocator.getName()))
-          return true;
-
-        failInfo = "KeyLocatorChecker failed!";
-        return false;
-      }
-    catch (KeyLocator::Error& e)
-      {
-        failInfo = "KeyLocator does not have name";
-        return false;
-      }
-  }
-
-private:
-  Regex m_regex;
-};
-
-class HyperKeyLocatorNameChecker : public KeyLocatorChecker
-{
-public:
-  HyperKeyLocatorNameChecker(const std::string& pExpr, const std::string pExpand,
-                             const std::string& kExpr, const std::string kExpand,
-                             const Relation& hyperRelation)
-    : m_hyperPRegex(new Regex(pExpr, pExpand))
-    , m_hyperKRegex(new Regex(kExpr, kExpand))
-    , m_hyperRelation(hyperRelation)
-  {
-  }
-
-protected:
-  virtual bool
-  check(const Name& packetName,
-        const KeyLocator& keyLocator,
-        std::string& failInfo)
-  {
-    try
-      {
-        if (m_hyperPRegex->match(packetName) &&
-            m_hyperKRegex->match(keyLocator.getName()) &&
-            checkRelation(m_hyperRelation,
-                          m_hyperKRegex->expand(),
-                          m_hyperPRegex->expand()))
-          return true;
-
-        failInfo = "KeyLocatorChecker failed!";
-        return false;
-      }
-    catch (KeyLocator::Error& e)
-      {
-        failInfo = "KeyLocator does not have name";
-        return false;
-      }
-
-  }
-
-private:
-  shared_ptr<Regex> m_hyperPRegex;
-  shared_ptr<Regex> m_hyperKRegex;
-  Relation m_hyperRelation;
-};
-
-
-class KeyLocatorCheckerFactory
-{
-public:
-  static shared_ptr<KeyLocatorChecker>
-  create(const ConfigSection& configSection, const std::string& filename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-
-    // Get checker.key-locator.type
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.type>!"));
-
-    std::string type = propertyIt->second.data();
-
-    if (boost::iequals(type, "name"))
-      return createKeyLocatorNameChecker(configSection, filename);
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator.type: " + type));
-  }
-
-private:
-  static shared_ptr<KeyLocatorChecker>
-  createKeyLocatorNameChecker(const ConfigSection& configSection,
-                              const std::string& filename)
-  {
-    ConfigSection::const_iterator propertyIt = configSection.begin();
-    propertyIt++;
-
-    if (propertyIt == configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect more checker.key-locator properties"));
-
-    if (boost::iequals(propertyIt->first, "name"))
-      {
-        Name name;
-        try
-          {
-            name = Name(propertyIt->second.data());
-          }
-        catch (Name::Error& e)
-          {
-            BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.name: " +
-                                        propertyIt->second.data()));
-          }
-        propertyIt++;
-
-        if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.relation>!"));
-
-        std::string relationString = propertyIt->second.data();
-        propertyIt++;
-
-        KeyLocatorChecker::Relation relation;
-        if (boost::iequals(relationString, "equal"))
-          relation = KeyLocatorChecker::RELATION_EQUAL;
-        else if (boost::iequals(relationString, "is-prefix-of"))
-          relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
-        else if (boost::iequals(relationString, "is-strict-prefix-of"))
-          relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
-        else
-          BOOST_THROW_EXCEPTION(Error("Unsupported relation: " + relationString));
-
-        if (propertyIt != configSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator!"));
-
-        return shared_ptr<RelationKeyLocatorNameChecker>
-          (new RelationKeyLocatorNameChecker(name, relation));
-      }
-    else if (boost::iequals(propertyIt->first, "regex"))
-      {
-        std::string regexString = propertyIt->second.data();
-        propertyIt++;
-
-        if (propertyIt != configSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator!"));
-
-        try
-          {
-            return shared_ptr<RegexKeyLocatorNameChecker>
-              (new RegexKeyLocatorNameChecker(regexString));
-          }
-        catch (Regex::Error& e)
-          {
-            BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.regex: " + regexString));
-          }
-      }
-    else if (boost::iequals(propertyIt->first, "hyper-relation"))
-      {
-        const ConfigSection& hSection = propertyIt->second;
-
-        ConfigSection::const_iterator hPropertyIt = hSection.begin();
-
-        // Get k-regex
-        if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-regex>!"));
-
-        std::string kRegex = hPropertyIt->second.data();
-        hPropertyIt++;
-
-        // Get k-expand
-        if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-expand>!"));
-
-        std::string kExpand = hPropertyIt->second.data();
-        hPropertyIt++;
-
-        // Get h-relation
-        if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.h-relation>!"));
-
-        std::string hRelation = hPropertyIt->second.data();
-        hPropertyIt++;
-
-        // Get p-regex
-        if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-regex>!"));
-
-        std::string pRegex = hPropertyIt->second.data();
-        hPropertyIt++;
-
-        // Get p-expand
-        if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand"))
-          BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-expand>!"));
-
-        std::string pExpand = hPropertyIt->second.data();
-        hPropertyIt++;
-
-        if (hPropertyIt != hSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator.hyper-relation!"));
-
-        KeyLocatorChecker::Relation relation;
-        if (boost::iequals(hRelation, "equal"))
-          relation = KeyLocatorChecker::RELATION_EQUAL;
-        else if (boost::iequals(hRelation, "is-prefix-of"))
-          relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
-        else if (boost::iequals(hRelation, "is-strict-prefix-of"))
-          relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
-        else
-          BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator.hyper-relation.h-relation: "
-                                      + hRelation));
-
-        try
-          {
-            return shared_ptr<HyperKeyLocatorNameChecker>
-              (new HyperKeyLocatorNameChecker(pRegex, pExpand,
-                                              kRegex, kExpand,
-                                              relation));
-          }
-        catch (Regex::Error& e)
-          {
-            BOOST_THROW_EXCEPTION(Error("Invalid regex for key-locator.hyper-relation"));
-          }
-      }
-    else
-      BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator"));
-  }
-};
-
-
-} // namespace conf
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP
diff --git a/src/security/conf/rule.hpp b/src/security/conf/rule.hpp
deleted file mode 100644
index 03af661..0000000
--- a/src/security/conf/rule.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Zhiyi Zhang <zhangzhiyi1919@gmail.com>
- */
-
-#ifndef NDN_SECURITY_CONF_RULE_HPP
-#define NDN_SECURITY_CONF_RULE_HPP
-
-#include "filter.hpp"
-#include "checker.hpp"
-
-
-namespace ndn {
-namespace security {
-namespace conf {
-
-template<class Packet>
-class Rule
-{
-public:
-  explicit
-  Rule(const std::string& id)
-    : m_id(id)
-  {
-  }
-
-  virtual
-  ~Rule()
-  {
-  }
-
-  const std::string&
-  getId()
-  {
-    return m_id;
-  }
-
-  void
-  addFilter(const shared_ptr<Filter>& filter)
-  {
-    m_filters.push_back(filter);
-  }
-
-  void
-  addChecker(const shared_ptr<Checker>& checker)
-  {
-    m_checkers.push_back(checker);
-  }
-
-  bool
-  match(const Packet& packet)
-  {
-    if (m_filters.empty())
-      return true;
-
-    for (FilterList::iterator it = m_filters.begin();
-         it != m_filters.end(); it++)
-      {
-        if (!(*it)->match(packet))
-          return false;
-      }
-
-    return true;
-  }
-
-  /**
-   * @brief check if packet satisfies certain condition
-   *
-   * @param packet The packet
-   * @param onValidated Callback function which is called when packet is immediately valid
-   * @param onValidationFailed Call function which is called when packet is immediately invalid
-   * @return -1 if packet is immediately invalid (onValidationFailed has been called)
-   *          1 if packet is immediately valid (onValidated has been called)
-   *          0 if further signature verification is needed.
-   */
-  template<class ValidatedCallback, class ValidationFailureCallback>
-  int8_t
-  check(const Packet& packet,
-        const ValidatedCallback& onValidated,
-        const ValidationFailureCallback& onValidationFailed)
-  {
-    bool hasPendingResult = false;
-    for (CheckerList::iterator it = m_checkers.begin(); it != m_checkers.end(); it++) {
-      int8_t result = (*it)->check(packet);
-      if (result > 0) {
-        onValidated(packet.shared_from_this());
-        return result;
-      }
-      else if (result == 0)
-        hasPendingResult = true;
-    }
-    if (hasPendingResult) {
-      return 0;
-    }
-    else {
-      onValidationFailed(packet.shared_from_this(), "Packet cannot pass any checkers.");
-      return -1;
-    }
-  }
-
-NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef std::vector<shared_ptr<Filter>> FilterList;
-  typedef std::vector<shared_ptr<Checker>> CheckerList;
-
-  std::string m_id;
-  FilterList m_filters;
-  CheckerList m_checkers;
-};
-
-} // namespace conf
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_CONF_RULE_HPP
diff --git a/src/security/v2/trust-anchor-group.cpp b/src/security/v2/trust-anchor-group.cpp
index 24f5b9e..6d702ab 100644
--- a/src/security/v2/trust-anchor-group.cpp
+++ b/src/security/v2/trust-anchor-group.cpp
@@ -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).
@@ -96,6 +96,8 @@
     BOOST_THROW_EXCEPTION(std::runtime_error("Refresh period for the dynamic group must be positive"));
   }
 
+  NDN_LOG_TRACE("Create dynamic trust anchor group " << id << " for file/dir " << path
+                << " with refresh time " << refreshPeriod);
   refresh();
 }
 
diff --git a/src/security/v2/validation-policy-config.cpp b/src/security/v2/validation-policy-config.cpp
new file mode 100644
index 0000000..ba87a23
--- /dev/null
+++ b/src/security/v2/validation-policy-config.cpp
@@ -0,0 +1,314 @@
+/* -*- 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 "validation-policy-config.hpp"
+#include "validator.hpp"
+#include "../../util/io.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/property_tree/info_parser.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+ValidationPolicyConfig::ValidationPolicyConfig()
+  : m_shouldBypass(false)
+  , m_isConfigured(false)
+{
+}
+
+void
+ValidationPolicyConfig::load(const std::string& filename)
+{
+  std::ifstream inputFile;
+  inputFile.open(filename.c_str());
+  if (!inputFile.good() || !inputFile.is_open()) {
+    std::string msg = "Failed to read configuration file: ";
+    msg += filename;
+    BOOST_THROW_EXCEPTION(Error(msg));
+  }
+  load(inputFile, filename);
+  inputFile.close();
+}
+
+void
+ValidationPolicyConfig::load(const std::string& input, const std::string& filename)
+{
+  std::istringstream inputStream(input);
+  load(inputStream, filename);
+}
+
+void
+ValidationPolicyConfig::load(std::istream& input, const std::string& filename)
+{
+  ConfigSection tree;
+  try {
+    boost::property_tree::read_info(input, tree);
+  }
+  catch (const boost::property_tree::info_parser_error& error) {
+    std::stringstream msg;
+    msg << "Failed to parse configuration file";
+    msg << " " << filename;
+    msg << " " << error.message() << " line " << error.line();
+    BOOST_THROW_EXCEPTION(Error(msg.str()));
+  }
+
+  load(tree, filename);
+}
+
+void
+ValidationPolicyConfig::load(const ConfigSection& configSection,
+                             const std::string& filename)
+{
+  if (m_isConfigured) {
+    BOOST_THROW_EXCEPTION(std::logic_error("ValidationPolicyConfig can be configured only once"));
+  }
+  m_isConfigured = true;
+
+  BOOST_ASSERT(!filename.empty());
+
+  if (configSection.begin() == configSection.end()) {
+    std::string msg = "Error processing configuration file";
+    msg += ": ";
+    msg += filename;
+    msg += " no data";
+    BOOST_THROW_EXCEPTION(Error(msg));
+  }
+
+  for (const auto& subSection : configSection) {
+    const std::string& sectionName = subSection.first;
+    const ConfigSection& section = subSection.second;
+
+    if (boost::iequals(sectionName, "rule")) {
+      auto rule = Rule::create(section, filename);
+      if (rule->getPktType() == tlv::Data) {
+        m_dataRules.push_back(std::move(rule));
+      }
+      else if (rule->getPktType() == tlv::Interest) {
+        m_interestRules.push_back(std::move(rule));
+      }
+    }
+    else if (boost::iequals(sectionName, "trust-anchor")) {
+      processConfigTrustAnchor(section, filename);
+    }
+    else {
+      std::string msg = "Error processing configuration file";
+      msg += " ";
+      msg += filename;
+      msg += " unrecognized section: " + sectionName;
+      BOOST_THROW_EXCEPTION(Error(msg));
+    }
+  }
+}
+
+void
+ValidationPolicyConfig::processConfigTrustAnchor(const ConfigSection& configSection, const std::string& filename)
+{
+  using namespace boost::filesystem;
+
+  ConfigSection::const_iterator propertyIt = configSection.begin();
+
+  // Get trust-anchor.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+  propertyIt++;
+
+  if (boost::iequals(type, "file")) {
+    // Get trust-anchor.file
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name")) {
+      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.file-name>"));
+    }
+
+    std::string file = propertyIt->second.data();
+    propertyIt++;
+
+    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of trust-anchor!"));
+    }
+
+    m_validator->loadAnchor(filename, absolute(file, path(filename).parent_path()).string(),
+                            refresh, false);
+    return;
+  }
+  else if (boost::iequals(type, "base64")) {
+    // Get trust-anchor.base64-string
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "base64-string"))
+      BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.base64-string>"));
+
+    std::stringstream ss(propertyIt->second.data());
+    propertyIt++;
+
+    // Check other stuff
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expecting the end of trust-anchor"));
+
+    auto idCert = io::load<Certificate>(ss);
+    if (idCert != nullptr) {
+      m_validator->loadAnchor("", std::move(*idCert));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from base64-string"));
+    }
+
+    return;
+  }
+  else if (boost::iequals(type, "dir")) {
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "dir"))
+      BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.dir>"));
+
+    std::string dirString(propertyIt->second.data());
+    propertyIt++;
+
+    time::nanoseconds refresh = getRefreshPeriod(propertyIt, configSection.end());
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expecting the end of trust-anchor"));
+    }
+
+    path dirPath = absolute(dirString, path(filename).parent_path());
+    m_validator->loadAnchor(dirString, dirPath.string(), refresh, true);
+    return;
+  }
+  else if (boost::iequals(type, "any")) {
+    m_shouldBypass = true;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported trust-anchor.type: " + type));
+  }
+}
+
+time::nanoseconds
+ValidationPolicyConfig::getRefreshPeriod(ConfigSection::const_iterator& it,
+                                         const ConfigSection::const_iterator& end)
+{
+  time::nanoseconds refresh = time::nanoseconds::max();
+  if (it == end) {
+    return refresh;
+  }
+
+  if (!boost::iequals(it->first, "refresh")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <trust-anchor.refresh>"));
+  }
+
+  std::string inputString = it->second.data();
+  ++it;
+
+  char unit = inputString[inputString.size() - 1];
+  std::string refreshString = inputString.substr(0, inputString.size() - 1);
+
+  uint32_t refreshPeriod = 0;
+
+  try {
+    refreshPeriod = boost::lexical_cast<uint32_t>(refreshString);
+  }
+  catch (const boost::bad_lexical_cast&) {
+    BOOST_THROW_EXCEPTION(Error("Bad number: " + refreshString));
+  }
+
+  if (refreshPeriod == 0) {
+    return getDefaultRefreshPeriod();
+  }
+
+  switch (unit) {
+    case 'h':
+      return time::duration_cast<time::nanoseconds>(time::hours(refreshPeriod));
+    case 'm':
+      return time::duration_cast<time::nanoseconds>(time::minutes(refreshPeriod));
+    case 's':
+      return time::duration_cast<time::nanoseconds>(time::seconds(refreshPeriod));
+    default:
+      BOOST_THROW_EXCEPTION(Error(std::string("Wrong time unit: ") + unit));
+  }
+}
+
+time::nanoseconds
+ValidationPolicyConfig::getDefaultRefreshPeriod()
+{
+  return time::duration_cast<time::nanoseconds>(time::seconds(3600));
+}
+
+void
+ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
+                                    const ValidationContinuation& continueValidation)
+{
+  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");
+
+  if (m_shouldBypass) {
+    return continueValidation(nullptr, state);
+  }
+
+  Name klName = getKeyLocatorName(data, *state);
+  if (!state->getOutcome()) { // already failed
+    return;
+  }
+
+  for (const auto& rule : m_dataRules) {
+    if (rule->match(tlv::Data, data.getName())) {
+      if (rule->check(tlv::Data, data.getName(), klName, state)) {
+        return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+      }
+      // rule->check calls state->fail(...) if the check fails
+      return;
+    }
+  }
+
+  return state->fail({ValidationError::POLICY_ERROR, "No rule matched for data `" + data.getName().toUri() + "`"});
+}
+
+void
+ValidationPolicyConfig::checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
+                                    const ValidationContinuation& continueValidation)
+{
+  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");
+
+  if (m_shouldBypass) {
+    return continueValidation(nullptr, state);
+  }
+
+  Name klName = getKeyLocatorName(interest, *state);
+  if (!state->getOutcome()) { // already failed
+    return;
+  }
+
+  for (const auto& rule : m_interestRules) {
+    if (rule->match(tlv::Interest, interest.getName())) {
+      if (rule->check(tlv::Interest, interest.getName(), klName, state)) {
+        return continueValidation(make_shared<CertificateRequest>(Interest(klName)), state);
+      }
+      // rule->check calls state->fail(...) if the check fails
+      return;
+    }
+  }
+
+  return state->fail({ValidationError::POLICY_ERROR, "No rule matched for interest `" + interest.getName().toUri() + "`"});
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validation-policy-config.hpp b/src/security/v2/validation-policy-config.hpp
new file mode 100644
index 0000000..7690cc1
--- /dev/null
+++ b/src/security/v2/validation-policy-config.hpp
@@ -0,0 +1,99 @@
+/* -*- 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_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
+#define NDN_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
+
+#include "validation-policy.hpp"
+#include "validator-config/rule.hpp"
+#include "validator-config/common.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+/**
+ * @brief The validator which can be set up via a configuration file.
+ *
+ * @note For command Interest validation, this policy must be combined with
+ *       @p ValidationPolicyCommandInterest, in order to guard against replay attacks.
+ * @note This policy does not support inner policies (a sole policy or a terminal inner policy)
+ * @sa https://named-data.net/doc/ndn-cxx/current/tutorials/security-validator-config.html
+ */
+class ValidationPolicyConfig : public ValidationPolicy
+{
+public:
+  ValidationPolicyConfig();
+
+  void
+  load(const std::string& filename);
+
+  void
+  load(const std::string& input, const std::string& filename);
+
+  void
+  load(std::istream& input, const std::string& filename);
+
+  void
+  load(const ConfigSection& configSection, const std::string& filename);
+
+protected:
+  void
+  checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
+              const ValidationContinuation& continueValidation) override;
+
+  void
+  checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
+              const ValidationContinuation& continueValidation) override;
+
+private:
+  void
+  processConfigTrustAnchor(const ConfigSection& section, const std::string& filename);
+
+  time::nanoseconds
+  getRefreshPeriod(ConfigSection::const_iterator& it, const ConfigSection::const_iterator& end);
+
+  time::nanoseconds
+  getDefaultRefreshPeriod();
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /** @brief whether to always bypass validation
+   *
+   *  This is set to true when 'any' is specified as a trust anchor.
+   *  It causes all packets to bypass validation.
+   */
+  bool m_shouldBypass;
+  bool m_isConfigured;
+
+  std::vector<unique_ptr<Rule>> m_dataRules;
+  std::vector<unique_ptr<Rule>> m_interestRules;
+};
+
+} // namespace validator_config
+
+using validator_config::ValidationPolicyConfig;
+
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATION_POLICY_CONFIG_HPP
diff --git a/src/security/v2/validation-policy.hpp b/src/security/v2/validation-policy.hpp
index 351ffed..d7a261b 100644
--- a/src/security/v2/validation-policy.hpp
+++ b/src/security/v2/validation-policy.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).
@@ -65,6 +65,20 @@
   void
   setInnerPolicy(unique_ptr<ValidationPolicy> innerPolicy);
 
+  /**
+   * @brief Check if inner policy is set
+   */
+  bool
+  hasInnerPolicy() const
+  {
+    return m_innerPolicy != nullptr;
+  }
+
+  /**
+   * @brief Return the inner policy
+   *
+   * If the inner policy was not set, behavior is undefined.
+   */
   ValidationPolicy&
   getInnerPolicy();
 
diff --git a/src/security/v2/validator-config/checker.cpp b/src/security/v2/validator-config/checker.cpp
new file mode 100644
index 0000000..47415af
--- /dev/null
+++ b/src/security/v2/validator-config/checker.cpp
@@ -0,0 +1,334 @@
+/* -*- 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 "checker.hpp"
+#include "security/v2/validation-state.hpp"
+#include "security/verification-helpers.hpp"
+#include "security/pib/key.hpp"
+#include "util/logger.hpp"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+bool
+Checker::check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
+
+  if (pktType == tlv::Interest) {
+    if (pktName.size() < signed_interest::MIN_SIZE)
+      return false;
+
+    return checkNames(pktName.getPrefix(-signed_interest::MIN_SIZE), klName, state);
+  }
+  else {
+    return checkNames(pktName, klName, state);
+  }
+}
+
+NameRelationChecker::NameRelationChecker(const Name& name, const NameRelation& relation)
+  : m_name(name)
+  , m_relation(relation)
+{
+}
+
+bool
+NameRelationChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  // pktName not used in this check
+  Name identity = extractIdentityFromKeyName(klName);
+  bool result = checkNameRelation(m_relation, m_name, identity);
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: name relation " << m_name << " " << m_relation
+       << " for packet " << pktName << " is invalid"
+       << " (KeyLocator=" << klName << ", identity=" << identity << ")";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+  return result;
+}
+
+RegexChecker::RegexChecker(const Regex& regex)
+  : m_regex(regex)
+{
+}
+
+bool
+RegexChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  // pktName not used in this check
+  Name identity = extractIdentityFromKeyName(klName);
+  bool result = m_regex.match(identity);
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: regex " << m_regex << " for packet " << pktName << " is invalid"
+       << " (KeyLocator=" << klName << ", identity=" << identity << ")";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+
+  return result;
+}
+
+HyperRelationChecker::HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
+                                           const std::string& klNameExpr, const std::string klNameExpand,
+                                           const NameRelation& hyperRelation)
+  : m_hyperPRegex(pktNameExpr, pktNameExpand)
+  , m_hyperKRegex(klNameExpr, klNameExpand)
+  , m_hyperRelation(hyperRelation)
+{
+}
+
+bool
+HyperRelationChecker::checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state)
+{
+  if (!m_hyperPRegex.match(pktName) || !m_hyperKRegex.match(klName)) {
+    std::ostringstream os;
+    os << "Packet " << pktName << " (" << "KeyLocator=" << klName << ") does not match "
+       << "the hyper relation rule pkt=" << m_hyperPRegex << ", key=" << m_hyperKRegex;
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+    return false;
+  }
+
+  bool result = checkNameRelation(m_hyperRelation, m_hyperKRegex.expand(), m_hyperPRegex.expand());
+  if (!result) {
+    std::ostringstream os;
+    os << "KeyLocator check failed: hyper relation " << m_hyperRelation
+       << " pkt=" << m_hyperPRegex << ", key=" << m_hyperKRegex
+       << " of packet " << pktName << " (KeyLocator=" << klName << ") is invalid";
+    state->fail({ValidationError::POLICY_ERROR, os.str()});
+  }
+  return result;
+}
+
+unique_ptr<Checker>
+Checker::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get checker.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "customized")) {
+    return createCustomizedChecker(configSection, configFilename);
+  }
+  else if (boost::iequals(type, "hierarchical")) {
+    return createHierarchicalChecker(configSection, configFilename);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker type: " + type));
+  }
+}
+
+unique_ptr<Checker>
+Checker::createCustomizedChecker(const ConfigSection& configSection,
+                                        const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  // TODO implement restrictions based on signature type (outside this checker)
+
+  if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
+    // ignore sig-type
+    propertyIt++;
+  }
+
+  // Get checker.key-locator
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator>"));
+  }
+
+  auto checker = createKeyLocatorChecker(propertyIt->second, configFilename);
+  propertyIt++;
+
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
+  }
+
+  return checker;
+}
+
+unique_ptr<Checker>
+Checker::createHierarchicalChecker(const ConfigSection& configSection,
+                                          const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  // TODO implement restrictions based on signature type (outside this checker)
+
+  if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
+    // ignore sig-type
+    propertyIt++;
+  }
+
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
+  }
+
+  return make_unique<HyperRelationChecker>("^(<>*)$",        "\\1",
+                                           "^(<>*)<KEY><>$", "\\1",
+                                           NameRelation::IS_PREFIX_OF);
+}
+
+///
+
+unique_ptr<Checker>
+Checker::createKeyLocatorChecker(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get checker.key-locator.type
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
+    BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.type>"));
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "name"))
+    return createKeyLocatorNameChecker(configSection, configFilename);
+  else
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator.type: " + type));
+}
+
+unique_ptr<Checker>
+Checker::createKeyLocatorNameChecker(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  if (propertyIt == configSection.end())
+    BOOST_THROW_EXCEPTION(Error("Expect more checker.key-locator properties"));
+
+  if (boost::iequals(propertyIt->first, "name")) {
+    Name name;
+    try {
+      name = Name(propertyIt->second.data());
+    }
+    catch (const Name::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.name: " + propertyIt->second.data()));
+    }
+    propertyIt++;
+
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.relation>"));
+    }
+
+    std::string relationString = propertyIt->second.data();
+    propertyIt++;
+
+    NameRelation relation = getNameRelationFromString(relationString);
+
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator"));
+    }
+    return make_unique<NameRelationChecker>(name, relation);
+  }
+  else if (boost::iequals(propertyIt->first, "regex")) {
+    std::string regexString = propertyIt->second.data();
+    propertyIt++;
+
+    if (propertyIt != configSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator"));
+    }
+
+    try {
+      return make_unique<RegexChecker>(regexString);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid checker.key-locator.regex: " + regexString));
+    }
+  }
+  else if (boost::iequals(propertyIt->first, "hyper-relation")) {
+    const ConfigSection& hSection = propertyIt->second;
+
+    ConfigSection::const_iterator hPropertyIt = hSection.begin();
+
+    // Get k-regex
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-regex>"));
+    }
+
+    std::string kRegex = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get k-expand
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.k-expand>"));
+    }
+
+    std::string kExpand = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get h-relation
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.h-relation>"));
+    }
+
+    std::string hRelation = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get p-regex
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-regex>"));
+    }
+
+    std::string pRegex = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    // Get p-expand
+    if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator.hyper-relation.p-expand>"));
+    }
+
+    std::string pExpand = hPropertyIt->second.data();
+    hPropertyIt++;
+
+    if (hPropertyIt != hSection.end()) {
+      BOOST_THROW_EXCEPTION(Error("Expect the end of checker.key-locator.hyper-relation"));
+    }
+
+    NameRelation relation = getNameRelationFromString(hRelation);
+    try {
+      return make_unique<HyperRelationChecker>(pRegex, pExpand, kRegex, kExpand, relation);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Invalid regex for key-locator.hyper-relation"));
+    }
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported checker.key-locator"));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/checker.hpp b/src/security/v2/validator-config/checker.hpp
new file mode 100644
index 0000000..390dc08
--- /dev/null
+++ b/src/security/v2/validator-config/checker.hpp
@@ -0,0 +1,136 @@
+/* -*- 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_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
+
+#include "common.hpp"
+#include "name-relation.hpp"
+#include "../../../name.hpp"
+#include "../../../util/regex.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+
+class ValidationState;
+
+namespace validator_config {
+
+class Checker : noncopyable
+{
+public:
+  virtual
+  ~Checker() = default;
+
+  /**
+   * @brief Check if packet name ane KeyLocator satisfy the checker's conditions
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet's name
+   * @param klName  KeyLocator's name
+   * @param state Validation state
+   *
+   * @retval false data is immediately invalid. Will call state::fail() with proper code and message.
+   * @retval true  further signature verification is needed.
+   */
+  bool
+  check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state);
+
+  /**
+   * @brief create a checker from configuration section
+   *
+   * @param configSection The section containing the definition of checker.
+   * @param configFilename The configuration file name.
+   * @return a checker created from configuration
+   */
+  static unique_ptr<Checker>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  static unique_ptr<Checker>
+  createCustomizedChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createHierarchicalChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createKeyLocatorChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+  static unique_ptr<Checker>
+  createKeyLocatorNameChecker(const ConfigSection& configSection, const std::string& configFilename);
+
+protected:
+  virtual bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) = 0;
+};
+
+class NameRelationChecker : public Checker
+{
+public:
+  NameRelationChecker(const Name& name, const NameRelation& relation);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Name m_name;
+  NameRelation m_relation;
+};
+
+class RegexChecker : public Checker
+{
+public:
+  explicit
+  RegexChecker(const Regex& regex);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Regex m_regex;
+};
+
+class HyperRelationChecker : public Checker
+{
+public:
+  HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
+                       const std::string& klNameExpr, const std::string klNameExpand,
+                       const NameRelation& hyperRelation);
+
+protected:
+  bool
+  checkNames(const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) override;
+
+private:
+  Regex m_hyperPRegex;
+  Regex m_hyperKRegex;
+  NameRelation m_hyperRelation;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_CHECKER_HPP
diff --git a/src/security/conf/common.hpp b/src/security/v2/validator-config/common.hpp
similarity index 75%
rename from src/security/conf/common.hpp
rename to src/security/v2/validator-config/common.hpp
index 3c79b7b..1663e5a 100644
--- a/src/security/conf/common.hpp
+++ b/src/security/v2/validator-config/common.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2014 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).
  *
@@ -21,31 +21,28 @@
  * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
  */
 
-#ifndef NDN_SECURITY_CONF_COMMON_HPP
-#define NDN_SECURITY_CONF_COMMON_HPP
+#ifndef NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
 
-#include "../../common.hpp"
-#include <string>
+#include "../../../common.hpp"
 #include <boost/property_tree/ptree.hpp>
 
 namespace ndn {
 namespace security {
-namespace conf {
+namespace v2 {
+namespace validator_config {
 
 typedef boost::property_tree::ptree ConfigSection;
 
 class Error : public std::runtime_error
 {
 public:
-  explicit
-  Error(const std::string& what)
-    : std::runtime_error(what)
-  {
-  }
+  using std::runtime_error::runtime_error;
 };
 
-} // namespace conf
+} // namespace validator_config
+} // namespace v2
 } // namespace security
 } // namespace ndn
 
-#endif // NDN_SECURITY_CONF_COMMON_HPP
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_COMMON_HPP
diff --git a/src/security/v2/validator-config/filter.cpp b/src/security/v2/validator-config/filter.cpp
new file mode 100644
index 0000000..baeba1d
--- /dev/null
+++ b/src/security/v2/validator-config/filter.cpp
@@ -0,0 +1,149 @@
+/* -*- 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 "filter.hpp"
+
+#include "data.hpp"
+#include "interest.hpp"
+#include "util/regex.hpp"
+#include "security/security-common.hpp"
+
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+bool
+Filter::match(uint32_t pktType, const Name& pktName)
+{
+  BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
+
+  if (pktType == tlv::Interest) {
+    if (pktName.size() < signed_interest::MIN_SIZE)
+      return false;
+
+    return matchName(pktName.getPrefix(-signed_interest::MIN_SIZE));
+  }
+  else {
+    return matchName(pktName);
+  }
+}
+
+RelationNameFilter::RelationNameFilter(const Name& name, NameRelation relation)
+  : m_name(name)
+  , m_relation(relation)
+{
+}
+
+bool
+RelationNameFilter::matchName(const Name& name)
+{
+  return checkNameRelation(m_relation, m_name, name);
+}
+
+RegexNameFilter::RegexNameFilter(const Regex& regex)
+  : m_regex(regex)
+{
+}
+
+bool
+RegexNameFilter::matchName(const Name& name)
+{
+  return m_regex.match(name);
+}
+
+unique_ptr<Filter>
+Filter::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type")) {
+    BOOST_THROW_EXCEPTION(Error("Expect <filter.type>"));
+  }
+
+  std::string type = propertyIt->second.data();
+
+  if (boost::iequals(type, "name"))
+    return createNameFilter(configSection, configFilename);
+  else
+    BOOST_THROW_EXCEPTION(Error("Unsupported filter.type: " + type));
+}
+
+unique_ptr<Filter>
+Filter::createNameFilter(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+  propertyIt++;
+
+  if (propertyIt == configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expect more properties for filter(name)"));
+  }
+
+  if (boost::iequals(propertyIt->first, "name")) {
+    // Get filter.name
+    Name name;
+    try {
+      name = Name(propertyIt->second.data());
+    }
+    catch (const Name::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Wrong filter.name: " + propertyIt->second.data()));
+    }
+
+    propertyIt++;
+
+    // Get filter.relation
+    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation")) {
+      BOOST_THROW_EXCEPTION(Error("Expect <filter.relation>"));
+    }
+
+    NameRelation relation = getNameRelationFromString(propertyIt->second.data());
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expect the end of filter"));
+
+    return make_unique<RelationNameFilter>(name, relation);
+  }
+  else if (boost::iequals(propertyIt->first, "regex")) {
+    std::string regexString = propertyIt->second.data();
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      BOOST_THROW_EXCEPTION(Error("Expect the end of filter"));
+
+    try {
+      return make_unique<RegexNameFilter>(regexString);
+    }
+    catch (const Regex::Error& e) {
+      BOOST_THROW_EXCEPTION(Error("Wrong filter.regex: " + regexString));
+    }
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Wrong filter(name) properties"));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/filter.hpp b/src/security/v2/validator-config/filter.hpp
new file mode 100644
index 0000000..cbd5275
--- /dev/null
+++ b/src/security/v2/validator-config/filter.hpp
@@ -0,0 +1,142 @@
+/* -*- 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_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
+
+#include "common.hpp"
+#include "name-relation.hpp"
+#include "../../../interest.hpp"
+#include "../../../data.hpp"
+#include "../../../util/regex.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+/**
+ * @brief Filter is one of the classes used by ValidatorConfig.
+ *
+ * The ValidatorConfig class consists of a set of rules.
+ * The Filter class is a part of a rule and is used to match packet.
+ * Matched packets will be checked against the checkers defined in the rule.
+ */
+class Filter : noncopyable
+{
+public:
+  virtual
+  ~Filter() = default;
+
+  bool
+  match(uint32_t pktType, const Name& pktName);
+
+public:
+  /**
+   * @brief Create a filter from the configuration section
+   *
+   * @param configSection The section containing the definition of filter.
+   * @param configFilename The configuration file name.
+   * @return a filter created from configuration
+   */
+  static unique_ptr<Filter>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  static unique_ptr<Filter>
+  createNameFilter(const ConfigSection& configSection, const std::string& configFilename);
+
+private:
+  virtual bool
+  matchName(const Name& pktName) = 0;
+};
+
+/**
+ * @brief Check that name is in relation to the packet name
+ *
+ * The following configuration
+ * @code
+ * filter
+ * {
+ *   type name
+ *   name /example
+ *   relation is-prefix-of
+ * }
+ * @endcode
+ *
+ * creates
+ * @code
+ * RelationNameFilter("/example", RelationNameFilter::RELATION_IS_PREFIX_OF);
+ * @endcode
+ */
+class RelationNameFilter : public Filter
+{
+public:
+  RelationNameFilter(const Name& name, NameRelation relation);
+
+private:
+  bool
+  matchName(const Name& pktName) override;
+
+private:
+  Name m_name;
+  NameRelation m_relation;
+};
+
+/**
+ * @brief Filter to check that packet name matches the specified regular expression
+ *
+ * The following configuration
+ * @code
+ * filter
+ * {
+ *   type name
+ *   regex ^[^<KEY>]*<KEY><>*<ksk-.*>$
+ * }
+ * @endcode
+ *
+ * creates
+ * @code
+ * RegexNameFilter("^[^<KEY>]*<KEY><>*<ksk-.*>$");
+ * @endcode
+ *
+ * @sa Regex
+ */
+class RegexNameFilter : public Filter
+{
+public:
+  explicit
+  RegexNameFilter(const Regex& regex);
+
+private:
+  bool
+  matchName(const Name& pktName) override;
+
+private:
+  Regex m_regex;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_FILTER_HPP
diff --git a/src/security/v2/validator-config/name-relation.cpp b/src/security/v2/validator-config/name-relation.cpp
new file mode 100644
index 0000000..ad65e9a
--- /dev/null
+++ b/src/security/v2/validator-config/name-relation.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 "name-relation.hpp"
+
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+std::ostream&
+operator<<(std::ostream& os, NameRelation relation)
+{
+  switch (relation)  {
+    case NameRelation::EQUAL:
+      return os << "equal";
+    case NameRelation::IS_PREFIX_OF:
+      return os << "is-prefix-of";
+    case NameRelation::IS_STRICT_PREFIX_OF:
+      return os << "is-strict-prefix-of";
+  }
+  return os;
+}
+
+bool
+checkNameRelation(NameRelation relation, const Name& name1, const Name& name2)
+{
+  switch (relation)  {
+    case NameRelation::EQUAL:
+      return name1 == name2;
+    case NameRelation::IS_PREFIX_OF:
+      return name1.isPrefixOf(name2);
+    case NameRelation::IS_STRICT_PREFIX_OF:
+      return name1.isPrefixOf(name2) && name1.size() < name2.size();
+  }
+  return false;
+}
+
+NameRelation
+getNameRelationFromString(const std::string& relationString)
+{
+  if (boost::iequals(relationString, "equal")) {
+    return NameRelation::EQUAL;
+  }
+  else if (boost::iequals(relationString, "is-prefix-of")) {
+    return NameRelation::IS_PREFIX_OF;
+  }
+  else if (boost::iequals(relationString, "is-strict-prefix-of")) {
+    return NameRelation::IS_STRICT_PREFIX_OF;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unsupported relation: " + relationString));
+  }
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/name-relation.hpp b/src/security/v2/validator-config/name-relation.hpp
new file mode 100644
index 0000000..5aa0dcf
--- /dev/null
+++ b/src/security/v2/validator-config/name-relation.hpp
@@ -0,0 +1,60 @@
+/* -*- 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_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
+
+#include "common.hpp"
+#include "../../../name.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+enum class NameRelation {
+  EQUAL,
+  IS_PREFIX_OF,
+  IS_STRICT_PREFIX_OF
+};
+
+std::ostream&
+operator<<(std::ostream& os, NameRelation relation);
+
+/**
+ * @brief check whether @p name1 and @p name2 satisfies @p relation
+ */
+bool
+checkNameRelation(NameRelation relation, const Name& name1, const Name& name2);
+
+/**
+ * @brief convert @p relationString to NameRelation
+ * @throw Error if @p relationString cannot be converted
+ */
+NameRelation
+getNameRelationFromString(const std::string& relationString);
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_NAME_RELATION_HPP
diff --git a/src/security/v2/validator-config/rule.cpp b/src/security/v2/validator-config/rule.cpp
new file mode 100644
index 0000000..93b8df4
--- /dev/null
+++ b/src/security/v2/validator-config/rule.cpp
@@ -0,0 +1,169 @@
+/* -*- 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 "rule.hpp"
+#include "util/logger.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+
+NDN_LOG_INIT(ndn.security.validator_config.Rule);
+
+namespace ndn {
+namespace security {
+namespace v2 {
+namespace validator_config {
+
+Rule::Rule(const std::string& id, uint32_t pktType)
+  : m_id(id)
+  , m_pktType(pktType)
+{
+}
+
+void
+Rule::addFilter(unique_ptr<Filter> filter)
+{
+  m_filters.push_back(std::move(filter));
+}
+
+void
+Rule::addChecker(unique_ptr<Checker> checker)
+{
+  m_checkers.push_back(std::move(checker));
+}
+
+bool
+Rule::match(uint32_t pktType, const Name& pktName) const
+{
+  NDN_LOG_TRACE("Trying to match " << pktName);
+  if (pktType != m_pktType) {
+    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
+                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+  }
+
+  if (m_filters.empty()) {
+    return true;
+  }
+
+  bool retval = false;
+  for (const auto& filter : m_filters) {
+    retval |= filter->match(pktType, pktName);
+    if (retval) {
+      break;
+    }
+  }
+  return retval;
+}
+
+bool
+Rule::check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) const
+{
+  NDN_LOG_TRACE("Trying to check " << pktName << " with keyLocator " << klName);
+
+  if (pktType != m_pktType) {
+    BOOST_THROW_EXCEPTION(Error("Invalid packet type supplied (" +
+                                to_string(pktType) + " != " + to_string(m_pktType) + ")"));
+  }
+
+  bool hasPendingResult = false;
+  for (const auto& checker : m_checkers) {
+    bool result = checker->check(pktType, pktName, klName, state);
+    if (!result) {
+      return result;
+    }
+    hasPendingResult = true;
+  }
+
+  return hasPendingResult;
+}
+
+unique_ptr<Rule>
+Rule::create(const ConfigSection& configSection, const std::string& configFilename)
+{
+  auto propertyIt = configSection.begin();
+
+  // Get rule.id
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "id")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <rule.id>"));
+  }
+
+  std::string ruleId = propertyIt->second.data();
+  propertyIt++;
+
+  // Get rule.for
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "for")) {
+    BOOST_THROW_EXCEPTION(Error("Expecting <rule.for> in rule: " + ruleId));
+  }
+
+  std::string usage = propertyIt->second.data();
+  propertyIt++;
+
+  bool isForData = false;
+  if (boost::iequals(usage, "data")) {
+    isForData = true;
+  }
+  else if (boost::iequals(usage, "interest")) {
+    isForData = false;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Unrecognized <rule.for>: " + usage + " in rule: " + ruleId));
+  }
+
+  auto rule = make_unique<Rule>(ruleId, isForData ? tlv::Data : tlv::Interest);
+
+  // Get rule.filter(s)
+  for (; propertyIt != configSection.end(); propertyIt++) {
+    if (!boost::iequals(propertyIt->first, "filter")) {
+      if (boost::iequals(propertyIt->first, "checker")) {
+        break;
+      }
+      BOOST_THROW_EXCEPTION(Error("Expecting <rule.filter> in rule: " + ruleId));
+    }
+
+    rule->addFilter(Filter::create(propertyIt->second, configFilename));
+  }
+
+  // Get rule.checker(s)
+  bool hasCheckers = false;
+  for (; propertyIt != configSection.end(); propertyIt++) {
+    if (!boost::iequals(propertyIt->first, "checker")) {
+      BOOST_THROW_EXCEPTION(Error("Expecting <rule.checker> in rule: " + ruleId));
+    }
+
+    rule->addChecker(Checker::create(propertyIt->second, configFilename));
+    hasCheckers = true;
+  }
+
+  // Check other stuff
+  if (propertyIt != configSection.end()) {
+    BOOST_THROW_EXCEPTION(Error("Expecting the end of rule: " + ruleId));
+  }
+
+  if (!hasCheckers) {
+    BOOST_THROW_EXCEPTION(Error("No <rule.checker> is specified in rule: " + ruleId));
+  }
+
+  return rule;
+}
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v2/validator-config/rule.hpp b/src/security/v2/validator-config/rule.hpp
new file mode 100644
index 0000000..66d6d6a
--- /dev/null
+++ b/src/security/v2/validator-config/rule.hpp
@@ -0,0 +1,113 @@
+/* -*- 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_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
+#define NDN_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
+
+#include "filter.hpp"
+#include "checker.hpp"
+
+namespace ndn {
+namespace security {
+namespace v2 {
+
+class ValidationState;
+
+namespace validator_config {
+
+class Rule : noncopyable
+{
+public:
+  Rule(const std::string& id, uint32_t pktType);
+
+  const std::string&
+  getId() const
+  {
+    return m_id;
+  }
+
+  uint32_t
+  getPktType() const
+  {
+    return m_pktType;
+  }
+
+  void
+  addFilter(unique_ptr<Filter> filter);
+
+  void
+  addChecker(unique_ptr<Checker> checker);
+
+  /**
+   * @brief check if the packet name matches rule's filter
+   *
+   * If no filters were added, the rule matches everything.
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet name, for signed Interests the last two components are not removed
+   * @retval true  If at least one filter matches @p pktName
+   * @retval false If none of the filters match @p pktName
+   *
+   * @throw Error the supplied pktType doesn't match one for which the rule is designed
+   */
+  bool
+  match(uint32_t pktType, const Name& pktName) const;
+
+  /**
+   * @brief check if packet satisfies rule's condition
+   *
+   * @param pktType tlv::Interest or tlv::Data
+   * @param pktName packet name, for signed Interests the last two components are not removed
+   * @param klName KeyLocator name
+   * @param state Validation state
+   *
+   * @retval false packet violates at least one checker. Will call state::fail() with proper code and message.
+   * @retval true  packet satisfies all checkers, further validation is needed
+   *
+   * @throw Error the supplied pktType doesn't match one for which the rule is designed
+   */
+  bool
+  check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) const;
+
+public:
+  /**
+   * @brief create a rule from configuration section
+   *
+   * @param configSection The section containing the definition of checker.
+   * @param configFilename The configuration file name.
+   * @return a rule created from configuration
+   */
+  static unique_ptr<Rule>
+  create(const ConfigSection& configSection, const std::string& configFilename);
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  std::string m_id;
+  uint32_t m_pktType;
+  std::vector<unique_ptr<Filter>> m_filters;
+  std::vector<unique_ptr<Checker>> m_checkers;
+};
+
+} // namespace validator_config
+} // namespace v2
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_V2_VALIDATOR_CONFIG_RULE_HPP
diff --git a/src/security/validator-config.cpp b/src/security/validator-config.cpp
index f267377..a8c5abc 100644
--- a/src/security/validator-config.cpp
+++ b/src/security/validator-config.cpp
@@ -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).
@@ -20,770 +20,47 @@
  */
 
 #include "validator-config.hpp"
-#include "certificate-cache-ttl.hpp"
-#include "../util/io.hpp"
-#include "../lp/tags.hpp"
-
-#include <boost/filesystem.hpp>
-#include <boost/property_tree/info_parser.hpp>
-#include <boost/algorithm/string.hpp>
+#include "v2/certificate-fetcher-from-network.hpp"
 
 namespace ndn {
 namespace security {
 
-const shared_ptr<CertificateCache> ValidatorConfig::DEFAULT_CERTIFICATE_CACHE;
-const time::milliseconds ValidatorConfig::DEFAULT_GRACE_INTERVAL(3000);
-const time::system_clock::Duration ValidatorConfig::DEFAULT_KEY_TIMESTAMP_TTL = time::hours(1);
-
-ValidatorConfig::ValidatorConfig(Face* face,
-                                 const shared_ptr<CertificateCache>& certificateCache,
-                                 const time::milliseconds& graceInterval,
-                                 const size_t stepLimit,
-                                 const size_t maxTrackedKeys,
-                                 const time::system_clock::Duration& keyTimestampTtl)
-  : Validator(face)
-  , m_shouldValidate(true)
-  , m_stepLimit(stepLimit)
-  , m_certificateCache(certificateCache)
-  , m_graceInterval(graceInterval < time::milliseconds::zero() ?
-                    DEFAULT_GRACE_INTERVAL : graceInterval)
-  , m_maxTrackedKeys(maxTrackedKeys)
-  , m_keyTimestampTtl(keyTimestampTtl)
+ValidatorConfig::ValidatorConfig(std::unique_ptr<v2::CertificateFetcher> fetcher, const Options& options)
+  : v2::Validator(make_unique<v2::ValidationPolicyCommandInterest>(make_unique<v2::ValidationPolicyConfig>(),
+                                                                   options),
+                  std::move(fetcher))
+  , m_policyConfig(static_cast<v2::ValidationPolicyConfig&>(getPolicy().getInnerPolicy()))
 {
-  if (m_certificateCache == nullptr && face != nullptr)
-    m_certificateCache = make_shared<CertificateCacheTtl>(ref(face->getIoService()));
 }
 
-ValidatorConfig::ValidatorConfig(Face& face,
-                                 const shared_ptr<CertificateCache>& certificateCache,
-                                 const time::milliseconds& graceInterval,
-                                 const size_t stepLimit,
-                                 const size_t maxTrackedKeys,
-                                 const time::system_clock::Duration& keyTimestampTtl)
-  : Validator(face)
-  , m_shouldValidate(true)
-  , m_stepLimit(stepLimit)
-  , m_certificateCache(certificateCache)
-  , m_graceInterval(graceInterval < time::milliseconds::zero() ?
-                    DEFAULT_GRACE_INTERVAL : graceInterval)
-  , m_maxTrackedKeys(maxTrackedKeys)
-  , m_keyTimestampTtl(keyTimestampTtl)
+ValidatorConfig::ValidatorConfig(Face& face, const Options& options)
+  : ValidatorConfig(make_unique<v2::CertificateFetcherFromNetwork>(face), options)
 {
-  if (m_certificateCache == nullptr)
-    m_certificateCache = make_shared<CertificateCacheTtl>(ref(face.getIoService()));
 }
 
 void
 ValidatorConfig::load(const std::string& filename)
 {
-  std::ifstream inputFile;
-  inputFile.open(filename.c_str());
-  if (!inputFile.good() || !inputFile.is_open()) {
-    std::string msg = "Failed to read configuration file: ";
-    msg += filename;
-    BOOST_THROW_EXCEPTION(security::conf::Error(msg));
-  }
-  load(inputFile, filename);
-  inputFile.close();
+  m_policyConfig.load(filename);
 }
 
 void
 ValidatorConfig::load(const std::string& input, const std::string& filename)
 {
-  std::istringstream inputStream(input);
-  load(inputStream, filename);
+  m_policyConfig.load(input, filename);
 }
 
-
 void
 ValidatorConfig::load(std::istream& input, const std::string& filename)
 {
-  security::conf::ConfigSection tree;
-  try {
-    boost::property_tree::read_info(input, tree);
-  }
-  catch (const boost::property_tree::info_parser_error& error) {
-    std::stringstream msg;
-    msg << "Failed to parse configuration file";
-    msg << " " << filename;
-    msg << " " << error.message() << " line " << error.line();
-    BOOST_THROW_EXCEPTION(security::conf::Error(msg.str()));
-  }
-
-  load(tree, filename);
+  m_policyConfig.load(input, filename);
 }
 
 void
-ValidatorConfig::load(const security::conf::ConfigSection& configSection,
+ValidatorConfig::load(const v2::validator_config::ConfigSection& configSection,
                       const std::string& filename)
 {
-  BOOST_ASSERT(!filename.empty());
-
-  reset();
-
-  if (configSection.begin() == configSection.end()) {
-    std::string msg = "Error processing configuration file";
-    msg += ": ";
-    msg += filename;
-    msg += " no data";
-    BOOST_THROW_EXCEPTION(security::conf::Error(msg));
-  }
-
-  for (security::conf::ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end(); ++i) {
-    const std::string& sectionName = i->first;
-    const security::conf::ConfigSection& section = i->second;
-
-    if (boost::iequals(sectionName, "rule")) {
-      onConfigRule(section, filename);
-    }
-    else if (boost::iequals(sectionName, "trust-anchor")) {
-      onConfigTrustAnchor(section, filename);
-    }
-    else {
-      std::string msg = "Error processing configuration file";
-      msg += " ";
-      msg += filename;
-      msg += " unrecognized section: " + sectionName;
-      BOOST_THROW_EXCEPTION(security::conf::Error(msg));
-    }
-  }
-}
-
-void
-ValidatorConfig::onConfigRule(const security::conf::ConfigSection& configSection,
-                              const std::string& filename)
-{
-  using namespace ndn::security::conf;
-
-  ConfigSection::const_iterator propertyIt = configSection.begin();
-
-  // Get rule.id
-  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "id"))
-    BOOST_THROW_EXCEPTION(Error("Expect <rule.id>!"));
-
-  std::string ruleId = propertyIt->second.data();
-  propertyIt++;
-
-  // Get rule.for
-  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,"for"))
-    BOOST_THROW_EXCEPTION(Error("Expect <rule.for> in rule: " + ruleId + "!"));
-
-  std::string usage = propertyIt->second.data();
-  propertyIt++;
-
-  bool isForData = false;
-  if (boost::iequals(usage, "data"))
-    isForData = true;
-  else if (boost::iequals(usage, "interest"))
-    isForData = false;
-  else
-    BOOST_THROW_EXCEPTION(Error("Unrecognized <rule.for>: " + usage
-                                + " in rule: " + ruleId));
-
-  // Get rule.filter(s)
-  std::vector<shared_ptr<Filter>> filters;
-  for (; propertyIt != configSection.end(); propertyIt++) {
-    if (!boost::iequals(propertyIt->first, "filter")) {
-      if (boost::iequals(propertyIt->first, "checker"))
-        break;
-      BOOST_THROW_EXCEPTION(Error("Expect <rule.filter> in rule: " + ruleId));
-    }
-
-    filters.push_back(FilterFactory::create(propertyIt->second));
-    continue;
-  }
-
-  // Get rule.checker(s)
-  std::vector<shared_ptr<Checker>> checkers;
-  for (; propertyIt != configSection.end(); propertyIt++) {
-    if (!boost::iequals(propertyIt->first, "checker"))
-      BOOST_THROW_EXCEPTION(Error("Expect <rule.checker> in rule: " + ruleId));
-
-    checkers.push_back(CheckerFactory::create(propertyIt->second, filename));
-    continue;
-  }
-
-  // Check other stuff
-  if (propertyIt != configSection.end())
-    BOOST_THROW_EXCEPTION(Error("Expect the end of rule: " + ruleId));
-
-  if (checkers.empty())
-    BOOST_THROW_EXCEPTION(Error("No <rule.checker> is specified in rule: " + ruleId));
-
-  if (isForData) {
-    shared_ptr<DataRule> rule = make_shared<DataRule>(ruleId);
-    for (const auto& filter : filters)
-      rule->addFilter(filter);
-    for (const auto& checker : checkers)
-      rule->addChecker(checker);
-
-    m_dataRules.push_back(rule);
-  }
-  else {
-    shared_ptr<InterestRule> rule = make_shared<InterestRule>(ruleId);;
-    for (const auto& filter : filters)
-      rule->addFilter(filter);
-    for (const auto& checker : checkers)
-      rule->addChecker(checker);
-
-    m_interestRules.push_back(rule);
-  }
-}
-
-void
-ValidatorConfig::onConfigTrustAnchor(const security::conf::ConfigSection& configSection,
-                                     const std::string& filename)
-{
-  using namespace ndn::security::conf;
-  using namespace boost::filesystem;
-
-  ConfigSection::const_iterator propertyIt = configSection.begin();
-
-  // Get trust-anchor.type
-  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
-    BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.type>!"));
-
-  std::string type = propertyIt->second.data();
-  propertyIt++;
-
-  if (boost::iequals(type, "file")) {
-    // Get trust-anchor.file
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
-      BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.file-name>!"));
-
-    std::string file = propertyIt->second.data();
-    propertyIt++;
-
-    // Check other stuff
-    if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect the end of trust-anchor!"));
-
-    path certfilePath = absolute(file, path(filename).parent_path());
-    auto idCert = io::load<v1::IdentityCertificate>(certfilePath.string());
-
-    if (idCert != nullptr) {
-      BOOST_ASSERT(idCert->getName().size() >= 1);
-      m_staticContainer.add(idCert);
-      m_anchors[idCert->getName().getPrefix(-1)] = idCert;
-    }
-    else
-      BOOST_THROW_EXCEPTION(Error("Cannot read certificate from file: " + certfilePath.native()));
-
-    return;
-  }
-  else if (boost::iequals(type, "base64")) {
-    // Get trust-anchor.base64-string
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "base64-string"))
-      BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.base64-string>!"));
-
-    std::stringstream ss(propertyIt->second.data());
-    propertyIt++;
-
-    // Check other stuff
-    if (propertyIt != configSection.end())
-      BOOST_THROW_EXCEPTION(Error("Expect the end of trust-anchor!"));
-
-    auto idCert = io::load<v1::IdentityCertificate>(ss);
-
-    if (idCert != nullptr) {
-      BOOST_ASSERT(idCert->getName().size() >= 1);
-      m_staticContainer.add(idCert);
-      m_anchors[idCert->getName().getPrefix(-1)] = idCert;
-    }
-    else
-      BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from base64-string"));
-
-    return;
-  }
-  else if (boost::iequals(type, "dir")) {
-    if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "dir"))
-      BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.dir>"));
-
-    std::string dirString(propertyIt->second.data());
-    propertyIt++;
-
-    if (propertyIt != configSection.end()) {
-      if (boost::iequals(propertyIt->first, "refresh")) {
-        using namespace boost::filesystem;
-
-        time::nanoseconds refresh = getRefreshPeriod(propertyIt->second.data());
-        propertyIt++;
-
-        if (propertyIt != configSection.end())
-          BOOST_THROW_EXCEPTION(Error("Expect the end of trust-anchor"));
-
-        path dirPath = absolute(dirString, path(filename).parent_path());
-
-        m_dynamicContainers.push_back(DynamicTrustAnchorContainer(dirPath, true, refresh));
-
-        m_dynamicContainers.rbegin()->setLastRefresh(time::system_clock::now() - refresh);
-
-        return;
-      }
-      else
-        BOOST_THROW_EXCEPTION(Error("Expect <trust-anchor.refresh>!"));
-    }
-    else {
-      using namespace boost::filesystem;
-
-      path dirPath = absolute(dirString, path(filename).parent_path());
-
-      directory_iterator end;
-
-      for (directory_iterator it(dirPath); it != end; it++) {
-        auto idCert = io::load<v1::IdentityCertificate>(it->path().string());
-
-        if (idCert != nullptr)
-          m_staticContainer.add(idCert);
-      }
-
-      return;
-    }
-  }
-  else if (boost::iequals(type, "any")) {
-    m_shouldValidate = false;
-  }
-  else
-    BOOST_THROW_EXCEPTION(Error("Unsupported trust-anchor.type: " + type));
-}
-
-void
-ValidatorConfig::reset()
-{
-  if (m_certificateCache != nullptr)
-    m_certificateCache->reset();
-  m_interestRules.clear();
-  m_dataRules.clear();
-
-  m_anchors.clear();
-
-  m_staticContainer = TrustAnchorContainer();
-
-  m_dynamicContainers.clear();
-}
-
-bool
-ValidatorConfig::isEmpty()
-{
-  return ((m_certificateCache == nullptr || m_certificateCache->isEmpty()) &&
-          m_interestRules.empty() && m_dataRules.empty() && m_anchors.empty());
-}
-
-time::nanoseconds
-ValidatorConfig::getRefreshPeriod(std::string inputString)
-{
-  char unit = inputString[inputString.size() - 1];
-  std::string refreshString = inputString.substr(0, inputString.size() - 1);
-
-  uint32_t refreshPeriod = 0;
-
-  try {
-    refreshPeriod = boost::lexical_cast<uint32_t>(refreshString);
-  }
-  catch (const boost::bad_lexical_cast&) {
-    BOOST_THROW_EXCEPTION(Error("Bad number: " + refreshString));
-  }
-
-  if (refreshPeriod == 0)
-    return getDefaultRefreshPeriod();
-
-  switch (unit) {
-  case 'h':
-    return time::duration_cast<time::nanoseconds>(time::hours(refreshPeriod));
-  case 'm':
-    return time::duration_cast<time::nanoseconds>(time::minutes(refreshPeriod));
-  case 's':
-    return time::duration_cast<time::nanoseconds>(time::seconds(refreshPeriod));
-  default:
-    BOOST_THROW_EXCEPTION(Error(std::string("Wrong time unit: ") + unit));
-  }
-}
-
-time::nanoseconds
-ValidatorConfig::getDefaultRefreshPeriod()
-{
-  return time::duration_cast<time::nanoseconds>(time::seconds(3600));
-}
-
-void
-ValidatorConfig::refreshAnchors()
-{
-  time::system_clock::TimePoint now = time::system_clock::now();
-
-  bool isRefreshed = false;
-
-  for (auto cIt = m_dynamicContainers.begin();
-       cIt != m_dynamicContainers.end() && cIt->getLastRefresh() + cIt->getRefreshPeriod() < now;
-       cIt++) {
-    isRefreshed = true;
-    cIt->refresh();
-    cIt->setLastRefresh(now);
-  }
-
-  if (isRefreshed) {
-    m_anchors.clear();
-
-    for (const auto& cert : m_staticContainer.getAll()) {
-      m_anchors[cert->getName().getPrefix(-1)] = cert;
-    }
-
-    for (const auto& container : m_dynamicContainers) {
-      const CertificateList& certList = container.getAll();
-
-      for (const auto& cert :certList) {
-        m_anchors[cert->getName().getPrefix(-1)] = cert;
-      }
-    }
-    m_dynamicContainers.sort(ValidatorConfig::compareDynamicContainer);
-  }
-}
-
-void
-ValidatorConfig::checkPolicy(const Data& data,
-                             int nSteps,
-                             const OnDataValidated& onValidated,
-                             const OnDataValidationFailed& onValidationFailed,
-                             std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  if (!m_shouldValidate)
-    return onValidated(data.shared_from_this());
-
-  bool isMatched = false;
-  int8_t checkResult = -1;
-
-  for (const auto& dataRule : m_dataRules) {
-    if (dataRule->match(data)) {
-      isMatched = true;
-      checkResult = dataRule->check(data, onValidated, onValidationFailed);
-      break;
-    }
-  }
-
-  if (!isMatched)
-    return onValidationFailed(data.shared_from_this(), "No rule matched!");
-
-  if (checkResult == 0) {
-    const Signature& signature = data.getSignature();
-    checkSignature(data, signature, nSteps,
-                   onValidated, onValidationFailed, nextSteps);
-  }
-}
-
-void
-ValidatorConfig::checkPolicy(const Interest& interest,
-                             int nSteps,
-                             const OnInterestValidated& onValidated,
-                             const OnInterestValidationFailed& onValidationFailed,
-                             std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  if (!m_shouldValidate)
-    return onValidated(interest.shared_from_this());
-
-  // If interestName has less than 4 name components,
-  // it is definitely not a signed interest.
-  if (interest.getName().size() < command_interest::MIN_SIZE)
-    return onValidationFailed(interest.shared_from_this(),
-                              "Interest is not signed: " + interest.getName().toUri());
-
-  try {
-    const Name& interestName = interest.getName();
-    Signature signature(interestName[command_interest::POS_SIG_INFO].blockFromValue(),
-                        interestName[command_interest::POS_SIG_VALUE].blockFromValue());
-
-    if (!signature.hasKeyLocator())
-      return onValidationFailed(interest.shared_from_this(), "No valid KeyLocator");
-
-    const KeyLocator& keyLocator = signature.getKeyLocator();
-
-    if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
-      return onValidationFailed(interest.shared_from_this(), "Key Locator is not a name");
-
-    Name keyName = v1::IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName());
-
-    bool isMatched = false;
-    int8_t checkResult = -1;
-
-    for (const auto& interestRule : m_interestRules) {
-      if (interestRule->match(interest)) {
-        isMatched = true;
-        checkResult = interestRule->check(interest,
-                                          bind(&ValidatorConfig::checkTimestamp, this, _1,
-                                               keyName, onValidated, onValidationFailed),
-                                          onValidationFailed);
-        break;
-      }
-    }
-
-    if (!isMatched)
-      return onValidationFailed(interest.shared_from_this(), "No rule matched!");
-
-    if (checkResult == 0) {
-      checkSignature<Interest, OnInterestValidated, OnInterestValidationFailed>
-        (interest, signature, nSteps,
-         bind(&ValidatorConfig::checkTimestamp, this, _1,
-              keyName, onValidated, onValidationFailed),
-         onValidationFailed,
-         nextSteps);
-    }
-  }
-  catch (const Signature::Error& e) {
-    return onValidationFailed(interest.shared_from_this(), "No valid signature");
-  }
-  catch (const KeyLocator::Error& e){
-    return onValidationFailed(interest.shared_from_this(), "No valid KeyLocator");
-  }
-  catch (const v1::IdentityCertificate::Error& e){
-    return onValidationFailed(interest.shared_from_this(), "Cannot determine the signing key");
-  }
-  catch (const tlv::Error& e){
-    return onValidationFailed(interest.shared_from_this(), "Cannot decode signature");
-  }
-}
-
-void
-ValidatorConfig::checkTimestamp(const shared_ptr<const Interest>& interest,
-                                const Name& keyName,
-                                const OnInterestValidated& onValidated,
-                                const OnInterestValidationFailed& onValidationFailed)
-{
-  const Name& interestName = interest->getName();
-  time::system_clock::TimePoint interestTime;
-
-  try {
-    interestTime =
-      time::fromUnixTimestamp(time::milliseconds(interestName.at(command_interest::POS_TIMESTAMP).toNumber()));
-  }
-  catch (const tlv::Error& e) {
-    return onValidationFailed(interest,
-                              "Cannot decode signature related TLVs");
-  }
-
-  time::system_clock::TimePoint currentTime = time::system_clock::now();
-
-  LastTimestampMap::iterator timestampIt = m_lastTimestamp.find(keyName);
-  if (timestampIt == m_lastTimestamp.end()) {
-    if (!(currentTime - m_graceInterval <= interestTime &&
-          interestTime <= currentTime + m_graceInterval))
-      return onValidationFailed(interest,
-                                "The command is not in grace interval: " + interest->getName().toUri());
-  }
-  else {
-    if (interestTime <= timestampIt->second)
-      return onValidationFailed(interest,
-                                "The command is outdated: " + interest->getName().toUri());
-  }
-
-  // Update timestamp
-  if (timestampIt == m_lastTimestamp.end()) {
-    cleanOldKeys();
-    m_lastTimestamp[keyName] = interestTime;
-  }
-  else {
-    timestampIt->second = interestTime;
-  }
-
-  return onValidated(interest);
-}
-
-void
-ValidatorConfig::cleanOldKeys()
-{
-  if (m_lastTimestamp.size() < m_maxTrackedKeys)
-    return;
-
-  LastTimestampMap::iterator timestampIt = m_lastTimestamp.begin();
-  LastTimestampMap::iterator end = m_lastTimestamp.end();
-
-  time::system_clock::TimePoint now = time::system_clock::now();
-  LastTimestampMap::iterator oldestKeyIt = m_lastTimestamp.begin();
-  time::system_clock::TimePoint oldestTimestamp = oldestKeyIt->second;
-
-  while (timestampIt != end) {
-    if (now - timestampIt->second > m_keyTimestampTtl) {
-      LastTimestampMap::iterator toDelete = timestampIt;
-      timestampIt++;
-      m_lastTimestamp.erase(toDelete);
-      continue;
-    }
-
-    if (timestampIt->second < oldestTimestamp) {
-      oldestTimestamp = timestampIt->second;
-      oldestKeyIt = timestampIt;
-    }
-
-    timestampIt++;
-  }
-
-  if (m_lastTimestamp.size() >= m_maxTrackedKeys)
-    m_lastTimestamp.erase(oldestKeyIt);
-}
-
-void
-ValidatorConfig::DynamicTrustAnchorContainer::refresh()
-{
-  using namespace boost::filesystem;
-
-  m_certificates.clear();
-
-  if (m_isDir) {
-    directory_iterator end;
-
-    for (directory_iterator it(m_path); it != end; it++) {
-      auto idCert = io::load<v1::IdentityCertificate>(it->path().string());
-
-      if (idCert != nullptr)
-        m_certificates.push_back(idCert);
-    }
-  }
-  else {
-    auto idCert = io::load<v1::IdentityCertificate>(m_path.string());
-
-    if (idCert != nullptr)
-      m_certificates.push_back(idCert);
-  }
-}
-
-template<class Packet, class OnValidated, class OnFailed>
-void
-ValidatorConfig::checkSignature(const Packet& packet,
-                                const Signature& signature,
-                                size_t nSteps,
-                                const OnValidated& onValidated,
-                                const OnFailed& onValidationFailed,
-                                std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  if (signature.getType() == tlv::DigestSha256) {
-    DigestSha256 sigSha256(signature);
-
-    if (verifySignature(packet, sigSha256))
-      return onValidated(packet.shared_from_this());
-    else
-      return onValidationFailed(packet.shared_from_this(), "Sha256 Signature cannot be verified!");
-  }
-
-  try {
-    switch (signature.getType()) {
-      case tlv::SignatureSha256WithRsa:
-      case tlv::SignatureSha256WithEcdsa: {
-        if (!signature.hasKeyLocator()) {
-          return onValidationFailed(packet.shared_from_this(),
-                                    "Missing KeyLocator in SignatureInfo");
-        }
-        break;
-      }
-      default:
-        return onValidationFailed(packet.shared_from_this(), "Unsupported signature type");
-    }
-  }
-  catch (const KeyLocator::Error& e) {
-    return onValidationFailed(packet.shared_from_this(),
-                              "Cannot decode KeyLocator in public key signature");
-  }
-  catch (const tlv::Error& e) {
-    return onValidationFailed(packet.shared_from_this(), "Cannot decode public key signature");
-  }
-
-  if (signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name) {
-    return onValidationFailed(packet.shared_from_this(), "Unsupported KeyLocator type");
-  }
-
-  const Name& keyLocatorName = signature.getKeyLocator().getName();
-
-  shared_ptr<const v1::Certificate> trustedCert;
-
-  refreshAnchors();
-
-  AnchorList::const_iterator it = m_anchors.find(keyLocatorName);
-  if (m_anchors.end() == it && m_certificateCache != nullptr)
-    trustedCert = m_certificateCache->getCertificate(keyLocatorName);
-  else if (m_anchors.end() != it)
-    trustedCert = it->second;
-
-  if (trustedCert != nullptr) {
-    if (verifySignature(packet, signature, trustedCert->getPublicKeyInfo()))
-      return onValidated(packet.shared_from_this());
-    else
-      return onValidationFailed(packet.shared_from_this(), "Cannot verify signature");
-  }
-  else {
-    if (m_stepLimit == nSteps)
-      return onValidationFailed(packet.shared_from_this(), "Maximum steps of validation reached");
-
-    OnDataValidated onCertValidated =
-      bind(&ValidatorConfig::onCertValidated<Packet, OnValidated, OnFailed>,
-           this, _1, packet.shared_from_this(), onValidated, onValidationFailed);
-
-    OnDataValidationFailed onCertValidationFailed =
-      bind(&ValidatorConfig::onCertFailed<Packet, OnFailed>,
-           this, _1, _2, packet.shared_from_this(), onValidationFailed);
-
-    Interest certInterest(keyLocatorName);
-
-    uint64_t incomingFaceId = 0;
-    auto incomingFaceIdTag = packet.template getTag<lp::IncomingFaceIdTag>();
-    if (incomingFaceIdTag != nullptr) {
-      incomingFaceId = incomingFaceIdTag->get();
-    }
-    auto nextStep = make_shared<ValidationRequest>(certInterest,
-                                                   onCertValidated,
-                                                   onCertValidationFailed,
-                                                   1, nSteps + 1,
-                                                   incomingFaceId);
-
-    nextSteps.push_back(nextStep);
-    return;
-  }
-  return onValidationFailed(packet.shared_from_this(), "Unsupported Signature Type");
-}
-
-template<class Packet, class OnValidated, class OnFailed>
-void
-ValidatorConfig::onCertValidated(const shared_ptr<const Data>& signCertificate,
-                                 const shared_ptr<const Packet>& packet,
-                                 const OnValidated& onValidated,
-                                 const OnFailed& onValidationFailed)
-{
-  if (signCertificate->getContentType() != tlv::ContentType_Key)
-    return onValidationFailed(packet,
-                              "Cannot retrieve signer's cert: " +
-                              signCertificate->getName().toUri());
-
-  shared_ptr<v1::IdentityCertificate> certificate;
-  try {
-    certificate = make_shared<v1::IdentityCertificate>(*signCertificate);
-  }
-  catch (const tlv::Error&) {
-    return onValidationFailed(packet,
-                              "Cannot decode signer's cert: " +
-                              signCertificate->getName().toUri());
-  }
-
-  if (!certificate->isTooLate() && !certificate->isTooEarly()) {
-    if (m_certificateCache != nullptr)
-      m_certificateCache->insertCertificate(certificate);
-
-    if (verifySignature(*packet, certificate->getPublicKeyInfo()))
-      return onValidated(packet);
-    else
-      return onValidationFailed(packet,
-                                "Cannot verify signature: " + packet->getName().toUri());
-  }
-  else {
-    return onValidationFailed(packet,
-                              "Signing certificate " +
-                              signCertificate->getName().toUri() + " is no longer valid.");
-  }
-}
-
-template<class Packet, class OnFailed>
-void
-ValidatorConfig::onCertFailed(const shared_ptr<const Data>& signCertificate,
-                              const std::string& failureInfo,
-                              const shared_ptr<const Packet>& packet,
-                              const OnFailed& onValidationFailed)
-{
-  onValidationFailed(packet, failureInfo);
+  m_policyConfig.load(configSection, filename);
 }
 
 } // namespace security
diff --git a/src/security/validator-config.hpp b/src/security/validator-config.hpp
index 47d536e..bc42e52 100644
--- a/src/security/validator-config.hpp
+++ b/src/security/validator-config.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).
@@ -22,51 +22,29 @@
 #ifndef NDN_SECURITY_VALIDATOR_CONFIG_HPP
 #define NDN_SECURITY_VALIDATOR_CONFIG_HPP
 
-#include "validator.hpp"
-#include "certificate-cache.hpp"
-#include "conf/rule.hpp"
-#include "conf/common.hpp"
+#include "v2/validator.hpp"
+#include "v2/validation-policy-command-interest.hpp"
+#include "v2/validation-policy-config.hpp"
 
 namespace ndn {
 namespace security {
 
 /**
- * @brief The validator which can be set up via a configuration file.
+ * @brief Helper for validator that uses CommandInterest + Config policy and NetworkFetcher
  */
-class ValidatorConfig : public Validator
+class ValidatorConfig : public v2::Validator
 {
 public:
-  class Error : public Validator::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Validator::Error(what)
-    {
-    }
-  };
+  using v2::Validator::Validator;
+  using Options = v2::ValidationPolicyCommandInterest::Options;
 
-  /**
-   * @note  When both certificate cache and face are not supplied, no cache will be used.
-   *        However, if only face is supplied, a default cache will be created and used.
-   */
   explicit
-  ValidatorConfig(Face* face = nullptr,
-                  const shared_ptr<CertificateCache>& certificateCache = DEFAULT_CERTIFICATE_CACHE,
-                  const time::milliseconds& graceInterval = DEFAULT_GRACE_INTERVAL,
-                  const size_t stepLimit = 10,
-                  const size_t maxTrackedKeys = 1000,
-                  const time::system_clock::Duration& keyTimestampTtl = DEFAULT_KEY_TIMESTAMP_TTL);
+  ValidatorConfig(std::unique_ptr<v2::CertificateFetcher> fetcher, const Options& options = Options());
 
-  /// @deprecated Use the constructor taking Face* as parameter.
   explicit
-  ValidatorConfig(Face& face,
-                  const shared_ptr<CertificateCache>& certificateCache = DEFAULT_CERTIFICATE_CACHE,
-                  const time::milliseconds& graceInterval = DEFAULT_GRACE_INTERVAL,
-                  const size_t stepLimit = 10,
-                  const size_t maxTrackedKeys = 1000,
-                  const time::system_clock::Duration& keyTimestampTtl = DEFAULT_KEY_TIMESTAMP_TTL);
+  ValidatorConfig(Face& face, const Options& options = Options());
 
+public: // helpers for ValidationPolicyConfig
   void
   load(const std::string& filename);
 
@@ -77,182 +55,11 @@
   load(std::istream& input, const std::string& filename);
 
   void
-  load(const security::conf::ConfigSection& configSection,
+  load(const v2::validator_config::ConfigSection& configSection,
        const std::string& filename);
 
-  void
-  reset();
-
-  bool
-  isEmpty();
-
-protected:
-  void
-  checkPolicy(const Data& data,
-              int nSteps,
-              const OnDataValidated& onValidated,
-              const OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-  void
-  checkPolicy(const Interest& interest,
-              int nSteps,
-              const OnInterestValidated& onValidated,
-              const OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-private:
-  template<class Packet, class OnValidated, class OnFailed>
-  void
-  checkSignature(const Packet& packet,
-                 const Signature& signature,
-                 size_t nSteps,
-                 const OnValidated& onValidated,
-                 const OnFailed& onValidationFailed,
-                 std::vector<shared_ptr<ValidationRequest>>& nextSteps);
-
-  void
-  checkTimestamp(const shared_ptr<const Interest>& interest,
-                 const Name& keyName,
-                 const OnInterestValidated& onValidated,
-                 const OnInterestValidationFailed& onValidationFailed);
-
-  template<class Packet, class OnValidated, class OnFailed>
-  void
-  onCertValidated(const shared_ptr<const Data>& signCertificate,
-                  const shared_ptr<const Packet>& packet,
-                  const OnValidated& onValidated,
-                  const OnFailed& onValidationFailed);
-
-  template<class Packet, class OnFailed>
-  void
-  onCertFailed(const shared_ptr<const Data>& signCertificate,
-               const std::string& failureInfo,
-               const shared_ptr<const Packet>& packet,
-               const OnFailed& onValidationFailed);
-
-  void
-  onConfigRule(const security::conf::ConfigSection& section,
-               const std::string& filename);
-
-  void
-  onConfigTrustAnchor(const security::conf::ConfigSection& section,
-                      const std::string& filename);
-
-  time::nanoseconds
-  getRefreshPeriod(std::string refreshString);
-
-  time::nanoseconds
-  getDefaultRefreshPeriod();
-
-  void
-  refreshAnchors();
-
-  void
-  cleanOldKeys();
-
-  class TrustAnchorContainer
-  {
-  public:
-    const std::list<shared_ptr<v1::IdentityCertificate>>&
-    getAll() const
-    {
-      return m_certificates;
-    }
-
-    void
-    add(shared_ptr<v1::IdentityCertificate> certificate)
-    {
-      m_certificates.push_back(certificate);
-    }
-
-  protected:
-    std::list<shared_ptr<v1::IdentityCertificate>> m_certificates;
-  };
-
-  class DynamicTrustAnchorContainer : public TrustAnchorContainer
-  {
-  public:
-    DynamicTrustAnchorContainer(const boost::filesystem::path& path, bool isDir,
-                                time::nanoseconds refreshPeriod)
-      : m_path(path)
-      , m_isDir(isDir)
-      , m_refreshPeriod(refreshPeriod)
-    {
-    }
-
-    void
-    setLastRefresh(const time::system_clock::TimePoint& lastRefresh)
-    {
-      m_lastRefresh = lastRefresh;
-    }
-
-    const time::system_clock::TimePoint&
-    getLastRefresh() const
-    {
-      return m_lastRefresh;
-    }
-
-    const time::nanoseconds&
-    getRefreshPeriod() const
-    {
-      return m_refreshPeriod;
-    }
-
-    void
-    refresh();
-
-  private:
-    boost::filesystem::path m_path;
-    bool m_isDir;
-
-    time::system_clock::TimePoint m_lastRefresh;
-    time::nanoseconds m_refreshPeriod;
-  };
-
-  static inline bool
-  compareDynamicContainer(const DynamicTrustAnchorContainer& containerA,
-                          const DynamicTrustAnchorContainer& containerB)
-  {
-    return (containerA.getLastRefresh() < containerB.getLastRefresh());
-  }
-
-public:
-  static const shared_ptr<CertificateCache> DEFAULT_CERTIFICATE_CACHE;
-  static const time::milliseconds DEFAULT_GRACE_INTERVAL;
-  static const time::system_clock::Duration DEFAULT_KEY_TIMESTAMP_TTL;
-
 NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  typedef security::conf::Rule<Interest> InterestRule;
-  typedef security::conf::Rule<Data>     DataRule;
-  typedef std::vector<shared_ptr<InterestRule>> InterestRuleList;
-  typedef std::vector<shared_ptr<DataRule>>     DataRuleList;
-  typedef std::map<Name, shared_ptr<v1::IdentityCertificate>> AnchorList;
-  typedef std::list<DynamicTrustAnchorContainer> DynamicContainers; // sorted by m_lastRefresh
-  typedef std::list<shared_ptr<v1::IdentityCertificate>> CertificateList;
-
-  /**
-   * @brief gives whether validation should be preformed
-   *
-   * If false, no validation occurs, and any packet is considered validated immediately.
-   */
-  bool m_shouldValidate;
-
-  size_t m_stepLimit;
-  shared_ptr<CertificateCache> m_certificateCache;
-
-  InterestRuleList m_interestRules;
-  DataRuleList m_dataRules;
-
-  AnchorList m_anchors;
-  TrustAnchorContainer m_staticContainer;
-  DynamicContainers m_dynamicContainers;
-
-  time::milliseconds m_graceInterval;
-  size_t m_maxTrackedKeys;
-  typedef std::map<Name, time::system_clock::TimePoint> LastTimestampMap;
-  LastTimestampMap m_lastTimestamp;
-  const time::system_clock::Duration& m_keyTimestampTtl;
+  v2::ValidationPolicyConfig& m_policyConfig;
 };
 
 } // namespace security
