diff --git a/src/security/conf/checker.hpp b/src/security/conf/checker.hpp
new file mode 100644
index 0000000..1ec2323
--- /dev/null
+++ b/src/security/conf/checker.hpp
@@ -0,0 +1,481 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_CONF_CHECKER_HPP
+#define NDN_SECURITY_CONF_CHECKER_HPP
+
+#include "key-locator-checker.hpp"
+#include "../../util/io.hpp"
+#include <boost/algorithm/string.hpp>
+
+#include "common.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
+   * @param onValidated Callback function which is called when data is immediately valid
+   * @param onValidationFailed Call function which is called when data is immediately invalid
+   * @return -1 if data is immediately invalid (onValidationFailed has been called)
+   *          1 if data is immediately valid (onValidated has been called)
+   *          0 if further signature verification is needed.
+   */
+  virtual int8_t
+  check(const Data& data,
+        const OnDataChecked& onValidated,
+        const OnDataCheckFailed& onValidationFailed) = 0;
+
+  /**
+   * @brief check if interest satisfies condition defined in the specific checker implementation
+   *
+   * @param interest Interest packet
+   * @param onValidated Callback function which is called when interest is immediately valid
+   * @param onValidationFailed Call function which is called when interest is immediately invalid
+   * @return -1 if interest is immediately invalid (onValidationFailed has been called)
+   *          1 if interest is immediately valid (onValidated has been called)
+   *          0 if further signature verification is needed.
+   */
+  virtual int8_t
+  check(const Interest& interest,
+        const OnInterestChecked& onValidated,
+        const OnInterestCheckFailed& onValidationFailed) = 0;
+};
+
+class CustomizedChecker : public Checker
+{
+  enum
+    {
+      INTEREST_SIG_VALUE = -1,
+      INTEREST_SIG_INFO = -2,
+    };
+
+public:
+  CustomizedChecker(uint32_t sigType,
+                    shared_ptr<KeyLocatorChecker> keyLocatorChecker)
+    : m_sigType(sigType)
+    , m_keyLocatorChecker(keyLocatorChecker)
+  {
+    if (m_sigType == Signature::Sha256WithRsa && !static_cast<bool>(m_keyLocatorChecker))
+      throw Error("Strong signature requires KeyLocatorChecker");
+  }
+
+  virtual int8_t
+  check(const Data& data,
+        const OnDataChecked& onValidated,
+        const OnDataCheckFailed& onValidationFailed)
+  {
+    return check(data, data.getSignature(), onValidated, onValidationFailed);
+  }
+
+  virtual int8_t
+  check(const Interest& interest,
+        const OnInterestChecked& onValidated,
+        const OnInterestCheckFailed& onValidationFailed)
+  {
+    const Name& interestName = interest.getName();
+    Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
+                        interestName[INTEREST_SIG_VALUE].blockFromValue());
+    return check(interest, signature, onValidated, onValidationFailed);
+  }
+
+private:
+  template<class Packet, class OnValidated, class OnFailed>
+  int8_t
+  check(const Packet& packet, const Signature& signature,
+        const OnValidated& onValidated,
+        const OnFailed& onValidationFailed)
+  {
+    if (m_sigType != signature.getType())
+      {
+        onValidationFailed(packet.shared_from_this(),
+                           "Signature type does not match: " +
+                           boost::lexical_cast<std::string>(m_sigType) +
+                           "!=" +
+                           boost::lexical_cast<std::string>(signature.getType()));
+        return -1;
+      }
+
+    switch (signature.getType())
+      {
+      case Signature::Sha256WithRsa:
+        {
+          try
+            {
+              SignatureSha256WithRsa sig(signature);
+
+              std::string failInfo;
+              if (m_keyLocatorChecker->check(packet, sig.getKeyLocator(), failInfo))
+                return 0;
+              else
+                {
+                  onValidationFailed(packet.shared_from_this(), failInfo);
+                  return -1;
+                }
+            }
+          catch (const SignatureSha256WithRsa::Error& e)
+            {
+              onValidationFailed(packet.shared_from_this(),
+                                 "Cannot decode Sha256WithRsa signature!");
+              return -1;
+            }
+        }
+      case Signature::Sha256:
+        return 0;
+      default:
+        {
+          onValidationFailed(packet.shared_from_this(),
+                             "Unsupported signature type: " +
+                             boost::lexical_cast<std::string>(signature.getType()));
+          return -1;
+        }
+      }
+  }
+
+private:
+  uint32_t m_sigType;
+  shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
+};
+
+class HierarchicalChecker : public CustomizedChecker
+{
+public:
+  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
+{
+  enum
+    {
+      INTEREST_SIG_VALUE = -1,
+      INTEREST_SIG_INFO = -2,
+    };
+public:
+  FixedSignerChecker(uint32_t sigType,
+                     const std::vector<shared_ptr<IdentityCertificate> >& signers)
+    : m_sigType(sigType)
+  {
+    for (std::vector<shared_ptr<IdentityCertificate> >::const_iterator it = signers.begin();
+         it != signers.end(); it++)
+      m_signers[(*it)->getName().getPrefix(-1)] = (*it);
+  }
+
+  virtual int8_t
+  check(const Data& data,
+        const OnDataChecked& onValidated,
+        const OnDataCheckFailed& onValidationFailed)
+  {
+    return check(data, data.getSignature(), onValidated, onValidationFailed);
+  }
+
+  virtual int8_t
+  check(const Interest& interest,
+        const OnInterestChecked& onValidated,
+        const OnInterestCheckFailed& onValidationFailed)
+  {
+    const Name& interestName = interest.getName();
+    Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
+                        interestName[INTEREST_SIG_VALUE].blockFromValue());
+    return check(interest, signature, onValidated, onValidationFailed);
+  }
+
+private:
+  template<class Packet, class OnValidated, class OnFailed>
+  int8_t
+  check(const Packet& packet, const Signature& signature,
+        const OnValidated& onValidated,
+        const OnFailed& onValidationFailed)
+  {
+    if (m_sigType != signature.getType())
+      {
+        onValidationFailed(packet.shared_from_this(),
+                           "Signature type does not match: "
+                           + boost::lexical_cast<std::string>(m_sigType)
+                           + "!="
+                           + boost::lexical_cast<std::string>(signature.getType()));
+        return -1;
+      }
+
+    switch(signature.getType())
+      {
+      case Signature::Sha256WithRsa:
+        {
+          try
+            {
+              SignatureSha256WithRsa sig(signature);
+
+              const Name& keyLocatorName = sig.getKeyLocator().getName();
+              if (m_signers.find(keyLocatorName) == m_signers.end())
+                {
+                  onValidationFailed(packet.shared_from_this(),
+                                     "Signer is not in the fixed signer list: "
+                                     + keyLocatorName.toUri());
+                  return -1;
+                }
+
+              if (Validator::verifySignature(packet, sig,
+                                             m_signers[keyLocatorName]->getPublicKeyInfo()))
+                {
+                  onValidated(packet.shared_from_this());
+                  return 1;
+                }
+              else
+                {
+                  onValidationFailed(packet.shared_from_this(),
+                                     "Signature cannot be validated!");
+                  return -1;
+                }
+            }
+          catch (const KeyLocator::Error& e)
+            {
+              onValidationFailed(packet.shared_from_this(),
+                                 "KeyLocator does not have name!");
+              return -1;
+            }
+          catch (const SignatureSha256WithRsa::Error& e)
+            {
+              onValidationFailed(packet.shared_from_this(),
+                                 "Cannot decode signature!");
+              return -1;
+            }
+        }
+      case Signature::Sha256:
+        {
+          onValidationFailed(packet.shared_from_this(),
+                             "FixedSigner does not allow Sha256 signature type!");
+          return -1;
+        }
+      default:
+        {
+          onValidationFailed(packet.shared_from_this(),
+                             "Unsupported signature type: "
+                             + boost::lexical_cast<std::string>(signature.getType()));
+          return -1;
+        }
+      }
+  }
+
+private:
+  typedef std::map<Name, shared_ptr<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"))
+      throw 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
+      throw 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"))
+      throw 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"))
+      throw Error("Expect <checker.key-locator>!");
+
+    shared_ptr<KeyLocatorChecker> keyLocatorChecker =
+      KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      throw Error("Expect the end of checker!");
+
+    return make_shared<CustomizedChecker>(boost::cref(getSigType(sigType)),
+                                          boost::cref(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"))
+      throw Error("Expect <checker.sig-type>!");
+
+    std::string sigType = propertyIt->second.data();
+    propertyIt++;
+
+    if (propertyIt != configSection.end())
+      throw Error("Expect the end of checker!");
+
+    return make_shared<HierarchicalChecker>(boost::cref(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"))
+      throw Error("Expect <checker.sig-type>!");
+
+    std::string sigType = propertyIt->second.data();
+    propertyIt++;
+
+    std::vector<shared_ptr<IdentityCertificate> > signers;
+    for (; propertyIt != configSection.end(); propertyIt++)
+      {
+        if (!boost::iequals(propertyIt->first, "signer"))
+          throw Error("Expect <checker.signer> but get <checker."
+                      + propertyIt->first + ">");
+
+        signers.push_back(getSigner(propertyIt->second, configFilename));
+      }
+
+    if (propertyIt != configSection.end())
+      throw Error("Expect the end of checker!");
+
+    return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
+                                                                 signers));
+  }
+
+  static shared_ptr<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"))
+      throw 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"))
+          throw Error("Expect <checker.signer.file-name>!");
+
+        path certfilePath = absolute(propertyIt->second.data(),
+                                     path(configFilename).parent_path());
+        propertyIt++;
+
+        if (propertyIt != configSection.end())
+          throw Error("Expect the end of checker.signer");
+
+        shared_ptr<IdentityCertificate> idCert
+          = io::load<IdentityCertificate>(certfilePath.c_str());
+
+        if (static_cast<bool>(idCert))
+          return idCert;
+        else
+          throw 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"))
+          throw Error("Expect <checker.signer.base64-string>!");
+
+        std::stringstream ss(propertyIt->second.data());
+        propertyIt++;
+
+        if (propertyIt != configSection.end())
+          throw Error("Expect the end of checker.signer");
+
+        shared_ptr<IdentityCertificate> idCert = io::load<IdentityCertificate>(ss);
+
+        if (static_cast<bool>(idCert))
+          return idCert;
+        else
+          throw Error("Cannot decode certificate from string");
+      }
+    else
+      throw Error("Unsupported checker.signer type: " + type);
+  }
+
+  static int32_t
+  getSigType(const std::string& sigType)
+  {
+    if (boost::iequals(sigType, "rsa-sha256"))
+      return Signature::Sha256WithRsa;
+    else if (boost::iequals(sigType, "sha256"))
+      return Signature::Sha256;
+    else
+      return -1;
+  }
+};
+
+} // namespace conf
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_SEC_CONF_RULE_SIGNER_HPP
diff --git a/src/security/conf/common.hpp b/src/security/conf/common.hpp
new file mode 100644
index 0000000..ba68e2a
--- /dev/null
+++ b/src/security/conf/common.hpp
@@ -0,0 +1,34 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_CONF_COMMON_HPP
+#define NDN_SECURITY_CONF_COMMON_HPP
+
+#include <string>
+#include <boost/property_tree/ptree.hpp>
+
+namespace ndn {
+namespace security {
+namespace conf {
+
+typedef boost::property_tree::ptree ConfigSection;
+
+class Error : public std::runtime_error
+{
+public:
+  explicit
+  Error(const std::string& what)
+    : std::runtime_error(what)
+  {
+  }
+};
+
+} // namespace conf
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_CONF_COMMON_HPP
diff --git a/src/security/conf/filter.hpp b/src/security/conf/filter.hpp
new file mode 100644
index 0000000..1db7498
--- /dev/null
+++ b/src/security/conf/filter.hpp
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#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 <boost/algorithm/string.hpp>
+
+#include "common.hpp"
+
+namespace ndn {
+namespace security {
+namespace conf {
+
+class Filter
+{
+public:
+  virtual
+  ~Filter()
+  {
+  }
+
+  virtual bool
+  match(const Data& data) = 0;
+
+  virtual bool
+  match(const Interest& interest) = 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()
+  {
+  }
+
+  virtual bool
+  match(const Data& data)
+  {
+    return match(data.getName());
+  }
+
+  virtual bool
+  match(const Interest& interest)
+  {
+    if (interest.getName().size() < 2)
+      return false;
+
+    Name signedName = interest.getName().getPrefix(-2);
+    return match(signedName);
+  }
+
+private:
+  bool
+  match(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 != name);
+      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()
+  {
+  }
+
+  virtual bool
+  match(const Data& data)
+  {
+    return m_regex.match(data.getName());
+  }
+
+  virtual bool
+  match(const Interest& interest)
+  {
+    if (interest.getName().size() < 2)
+      return false;
+
+    Name signedName = interest.getName().getPrefix(-2);
+    return m_regex.match(signedName);
+  }
+
+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"))
+      throw Error("Expect <filter.type>!");
+
+    std::string type = propertyIt->second.data();
+
+    if (boost::iequals(type, "name"))
+      return createNameFilter(configSection);
+    else
+      throw 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())
+      throw 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)
+          {
+            throw Error("Wrong filter.name: " + propertyIt->second.data());
+          }
+
+        propertyIt++;
+
+        // Get filter.relation
+        if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
+          throw 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
+          throw Error("Unsupported relation: " + relationString);
+
+
+        if (propertyIt != configSection.end())
+          throw Error("Expect the end of filter!");
+
+        return make_shared<RelationNameFilter>(boost::cref(name),
+                                               boost::cref(relation));
+      }
+    else if (boost::iequals(propertyIt->first, "regex"))
+      {
+        std::string regexString = propertyIt->second.data();
+        propertyIt++;
+
+        if (propertyIt != configSection.end())
+          throw Error("Expect the end of filter!");
+
+        try
+          {
+            return shared_ptr<RegexNameFilter>(new RegexNameFilter(regexString));
+          }
+        catch (const Regex::Error& e)
+          {
+            throw Error("Wrong filter.regex: " + regexString);
+          }
+      }
+    else
+      throw 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
new file mode 100644
index 0000000..0f667f7
--- /dev/null
+++ b/src/security/conf/key-locator-checker.hpp
@@ -0,0 +1,362 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#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 <boost/algorithm/string.hpp>
+
+#include "common.hpp"
+
+namespace ndn {
+namespace security {
+namespace conf {
+
+class KeyLocatorCheckerFactory;
+
+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() < 2)
+      {
+        failInfo = "No Signature";
+        return false;
+      }
+
+    Name signedName = interest.getName().getPrefix(-2);
+    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 (const KeyLocator::Error& e)
+      {
+        failInfo = "KeyLocator does not have name";
+        return false;
+      }
+  }
+
+private:
+  Name m_name;
+  KeyLocatorChecker::Relation m_relation;
+};
+
+class RegexKeyLocatorNameChecker : public KeyLocatorChecker
+{
+public:
+  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 (const 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 (const 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"))
+      throw Error("Expect <checker.key-locator.type>!");
+
+    std::string type = propertyIt->second.data();
+
+    if (boost::iequals(type, "name"))
+      return createKeyLocatorNameChecker(configSection, filename);
+    else
+      throw 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())
+      throw 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)
+          {
+            throw Error("Invalid checker.key-locator.name: "
+                        + propertyIt->second.data());
+          }
+        propertyIt++;
+
+        if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
+          throw 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
+          throw Error("Unsupported relation: " + relationString);
+
+        if (propertyIt != configSection.end())
+          throw 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())
+          throw Error("Expect the end of checker.key-locator!");
+
+        try
+          {
+            return shared_ptr<RegexKeyLocatorNameChecker>
+              (new RegexKeyLocatorNameChecker(regexString));
+          }
+        catch (const Regex::Error& e)
+          {
+            throw 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"))
+          throw 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"))
+          throw 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"))
+          throw 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"))
+          throw 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"))
+          throw Error("Expect <checker.key-locator.hyper-relation.p-expand>!");
+
+        std::string pExpand = hPropertyIt->second.data();
+        hPropertyIt++;
+
+        if (hPropertyIt != hSection.end())
+          throw 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
+          throw Error("Unsupported checker.key-locator.hyper-relation.h-relation: "
+                      + hRelation);
+
+        try
+          {
+            return shared_ptr<HyperKeyLocatorNameChecker>
+              (new HyperKeyLocatorNameChecker(pRegex, pExpand,
+                                              kRegex, kExpand,
+                                              relation));
+          }
+        catch (const Regex::Error& e)
+          {
+            throw Error("Invalid regex for key-locator.hyper-relation");
+          }
+      }
+    else
+      throw 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
new file mode 100644
index 0000000..560c440
--- /dev/null
+++ b/src/security/conf/rule.hpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#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:
+  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)
+  {
+    for (CheckerList::iterator it = m_checkers.begin();
+         it != m_checkers.end(); it++)
+      {
+        int8_t result = (*it)->check(packet, onValidated, onValidationFailed);
+        if (result >= 0)
+          return result;
+      }
+    return -1;
+  }
+
+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/validator-config.cpp b/src/security/validator-config.cpp
new file mode 100644
index 0000000..2085daf
--- /dev/null
+++ b/src/security/validator-config.cpp
@@ -0,0 +1,352 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "validator-config.hpp"
+#include "certificate-cache-ttl.hpp"
+#include "../util/io.hpp"
+
+#include <boost/filesystem.hpp>
+#include <boost/property_tree/info_parser.hpp>
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+
+const shared_ptr<CertificateCache> ValidatorConfig::DEFAULT_CERTIFICATE_CACHE;
+
+ValidatorConfig::ValidatorConfig(shared_ptr<Face> face,
+                                 shared_ptr<CertificateCache> certificateCache,
+                                 const int stepLimit)
+  : Validator(face)
+  , m_stepLimit(stepLimit)
+  , m_certificateCache(certificateCache)
+{
+  if (!static_cast<bool>(face))
+    throw Error("Face is not set!");
+
+  if (!static_cast<bool>(m_certificateCache))
+    m_certificateCache = make_shared<CertificateCacheTtl>(m_face->ioService());
+}
+
+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;
+      throw security::conf::Error(msg);
+    }
+  load(inputFile, filename);
+  inputFile.close();
+}
+
+void
+ValidatorConfig::load(const std::string& input, const std::string& filename)
+{
+  std::istringstream inputStream(input);
+  load(inputStream, 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();
+      throw security::conf::Error(msg.str());
+    }
+
+  process(tree, filename);
+}
+
+void
+ValidatorConfig::process(const security::conf::ConfigSection& configSection,
+                         const std::string& filename)
+{
+  BOOST_ASSERT(!filename.empty());
+
+  if (configSection.begin() == configSection.end())
+    {
+      std::string msg = "Error processing configuration file";
+      msg += ": ";
+      msg += filename;
+      msg += " no data";
+      throw 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;
+          throw 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"))
+    throw Error("Expect <rule.id>!");
+
+  std::string ruleId = propertyIt->second.data();
+  propertyIt++;
+
+  // Get rule.for
+  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first,"for"))
+    throw Error("Expect <rule.for> in rule: " + ruleId + "!");
+
+  std::string usage = propertyIt->second.data();
+  propertyIt++;
+
+  bool isForData;
+  if (boost::iequals(usage, "data"))
+    isForData = true;
+  else if (boost::iequals(usage, "interest"))
+    isForData = false;
+  else
+    throw 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;
+          throw 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"))
+        throw Error("Expect <rule.checker> in rule: " + ruleId);
+
+      checkers.push_back(CheckerFactory::create(propertyIt->second, filename));
+      continue;
+    }
+
+  // Check other stuff
+  if (propertyIt != configSection.end())
+    throw Error("Expect the end of rule: " + ruleId);
+
+  if (checkers.size() == 0)
+    throw Error("No <rule.checker> is specified in rule: " + ruleId);
+
+  if (isForData)
+    {
+      shared_ptr<DataRule> rule(new DataRule(ruleId));
+      for (size_t i = 0; i < filters.size(); i++)
+        rule->addFilter(filters[i]);
+      for (size_t i = 0; i < checkers.size(); i++)
+        rule->addChecker(checkers[i]);
+
+      m_dataRules.push_back(rule);
+    }
+  else
+    {
+      shared_ptr<InterestRule> rule(new InterestRule(ruleId));
+      for (size_t i = 0; i < filters.size(); i++)
+        rule->addFilter(filters[i]);
+      for (size_t i = 0; i < checkers.size(); i++)
+        rule->addChecker(checkers[i]);
+
+      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"))
+    throw 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"))
+        throw Error("Expect <trust-anchor.file-name>!");
+
+      std::string file = propertyIt->second.data();
+      propertyIt++;
+
+      // Check other stuff
+      if (propertyIt != configSection.end())
+        throw Error("Expect the end of trust-anchor!");
+
+      path certfilePath = absolute(file, path(filename).parent_path());
+      shared_ptr<IdentityCertificate> idCert =
+        io::load<IdentityCertificate>(certfilePath.string());
+
+      if (static_cast<bool>(idCert))
+        {
+          BOOST_ASSERT(idCert->getName().size() >= 1);
+          m_anchors[idCert->getName().getPrefix(-1)] = idCert;
+        }
+      else
+        throw 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"))
+        throw Error("Expect <trust-anchor.base64-string>!");
+
+      std::stringstream ss(propertyIt->second.data());
+      propertyIt++;
+
+      // Check other stuff
+      if (propertyIt != configSection.end())
+        throw Error("Expect the end of trust-anchor!");
+
+      shared_ptr<IdentityCertificate> idCert = io::load<IdentityCertificate>(ss);
+
+      if (static_cast<bool>(idCert))
+        {
+          BOOST_ASSERT(idCert->getName().size() >= 1);
+          m_anchors[idCert->getName().getPrefix(-1)] = idCert;
+        }
+      else
+        throw Error("Cannot decode certificate from base64-string");
+
+      return;
+    }
+  else
+    throw Error("Unsupported trust-anchor.type: " + type);
+}
+
+void
+ValidatorConfig::checkPolicy(const Data& data,
+                             int stepCount,
+                             const OnDataValidated& onValidated,
+                             const OnDataValidationFailed& onValidationFailed,
+                             std::vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  if (m_stepLimit == stepCount)
+    return onValidationFailed(data.shared_from_this(),
+                              "Maximum steps of validation reached");
+
+  bool isMatched = false;
+  int8_t checkResult = -1;
+
+  for (DataRuleList::iterator it = m_dataRules.begin();
+       it != m_dataRules.end(); it++)
+    {
+      if ((*it)->match(data))
+        {
+          isMatched = true;
+          checkResult = (*it)->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, stepCount,
+                     onValidated, onValidationFailed, nextSteps);
+    }
+}
+
+void
+ValidatorConfig::checkPolicy(const Interest& interest,
+                             int stepCount,
+                             const OnInterestValidated& onValidated,
+                             const OnInterestValidationFailed& onValidationFailed,
+                             std::vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  if (m_stepLimit == stepCount)
+    return onValidationFailed(interest.shared_from_this(),
+                              "Maximum steps of validation reached");
+
+  bool isMatched = false;
+  int8_t checkResult = -1;
+
+  for (InterestRuleList::iterator it = m_interestRules.begin();
+       it != m_interestRules.end(); it++)
+    {
+      if ((*it)->match(interest))
+        {
+          isMatched = true;
+          checkResult = (*it)->check(interest, onValidated, onValidationFailed);
+          break;
+        }
+    }
+
+  if (!isMatched)
+    return onValidationFailed(interest.shared_from_this(), "No rule matched!");
+
+  if (checkResult == 0)
+    {
+      const Name& interestName = interest.getName();
+      Name signedName = interestName.getPrefix(-2);
+      Signature signature(interestName[-2].blockFromValue(),
+                          interestName[-1].blockFromValue());
+
+      checkSignature(interest, signature, stepCount,
+                     onValidated, onValidationFailed, nextSteps);
+    }
+}
+
+
+} // namespace ndn
diff --git a/src/security/validator-config.hpp b/src/security/validator-config.hpp
new file mode 100644
index 0000000..acc85f5
--- /dev/null
+++ b/src/security/validator-config.hpp
@@ -0,0 +1,224 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#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"
+
+namespace ndn {
+
+class ValidatorConfig : public Validator
+{
+public:
+  class Error : public Validator::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : Validator::Error(what)
+    {
+    }
+  };
+
+  static const shared_ptr<CertificateCache> DEFAULT_CERTIFICATE_CACHE;
+
+  ValidatorConfig(shared_ptr<Face> face,
+                  shared_ptr<CertificateCache> certificateCache = DEFAULT_CERTIFICATE_CACHE,
+                  const int stepLimit = 10);
+
+  virtual
+  ~ValidatorConfig()
+  {
+  }
+
+  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);
+
+protected:
+  virtual void
+  checkPolicy(const Data& data,
+              int stepCount,
+              const OnDataValidated& onValidated,
+              const OnDataValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps);
+
+  virtual void
+  checkPolicy(const Interest& interest,
+              int stepCount,
+              const OnInterestValidated& onValidated,
+              const OnInterestValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps);
+
+private:
+  template<class Packet, class OnValidated, class OnFailed>
+  void
+  checkSignature(const Packet& packet,
+                 const Signature& signature,
+                 int stepCount,
+                 const OnValidated& onValidated,
+                 const OnFailed& onValidationFailed,
+                 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
+
+  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
+  process(const security::conf::ConfigSection& configSection,
+          const std::string& filename);
+
+  void
+  onConfigRule(const security::conf::ConfigSection& section,
+               const std::string& filename);
+
+  void
+  onConfigTrustAnchor(const security::conf::ConfigSection& section,
+                      const std::string& filename);
+
+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<IdentityCertificate> > AnchorList;
+
+  int m_stepLimit;
+  shared_ptr<CertificateCache> m_certificateCache;
+
+  InterestRuleList m_interestRules;
+  DataRuleList m_dataRules;
+  AnchorList m_anchors;
+};
+
+template<class Packet, class OnValidated, class OnFailed>
+void
+ValidatorConfig::checkSignature(const Packet& packet,
+                                const Signature& signature,
+                                int stepCount,
+                                const OnValidated& onValidated,
+                                const OnFailed& onValidationFailed,
+                                std::vector<shared_ptr<ValidationRequest> >& nextSteps)
+{
+  if (signature.getType() == Signature::Sha256)
+    {
+      SignatureSha256 sigSha256(signature);
+
+      if (verifySignature(packet, sigSha256))
+        return onValidated(packet.shared_from_this());
+      else
+        return onValidationFailed(packet.shared_from_this(),
+                                  "Sha256 Signature cannot be verified!");
+    }
+
+  if (signature.getType() == Signature::Sha256WithRsa)
+    {
+      SignatureSha256WithRsa sigSha256Rsa(signature);
+      Name keyLocatorName = sigSha256Rsa.getKeyLocator().getName();
+
+      shared_ptr<const Certificate> trustedCert;
+
+      AnchorList::const_iterator it = m_anchors.find(keyLocatorName);
+      if (m_anchors.end() == it)
+        trustedCert = m_certificateCache->getCertificate(keyLocatorName);
+      else
+        trustedCert = it->second;
+
+      if (static_cast<bool>(trustedCert))
+        {
+          if (verifySignature(packet, sigSha256Rsa, trustedCert->getPublicKeyInfo()))
+            return onValidated(packet.shared_from_this());
+          else
+            return onValidationFailed(packet.shared_from_this(),
+                                      "Cannot verify signature");
+        }
+      else
+        {
+          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);
+
+          shared_ptr<ValidationRequest> nextStep =
+            make_shared<ValidationRequest>(boost::cref(certInterest),
+                                           onCertValidated,
+                                           onCertValidationFailed,
+                                           1, stepCount + 1);
+
+          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)
+{
+  shared_ptr<IdentityCertificate> certificate =
+    make_shared<IdentityCertificate>(boost::cref(*signCertificate));
+
+  if (!certificate->isTooLate() && !certificate->isTooEarly())
+    {
+      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);
+}
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_VALIDATOR_CONFIG_HPP
diff --git a/src/security/validator-regex.cpp b/src/security/validator-regex.cpp
index ec22de8..0f09741 100644
--- a/src/security/validator-regex.cpp
+++ b/src/security/validator-regex.cpp
@@ -19,127 +19,147 @@
 
 namespace ndn {
 
-const shared_ptr<CertificateCache> ValidatorRegex::DefaultCertificateCache = shared_ptr<CertificateCache>();
+const shared_ptr<CertificateCache> ValidatorRegex::DEFAULT_CERTIFICATE_CACHE;
 
 ValidatorRegex::ValidatorRegex(shared_ptr<Face> face,
-                               shared_ptr<CertificateCache> certificateCache /* = DefaultCertificateCache */,
-                               const int stepLimit /* = 3 */)
+                               shared_ptr<CertificateCache> certificateCache,
+                               const int stepLimit)
   : Validator(face)
   , m_stepLimit(stepLimit)
   , m_certificateCache(certificateCache)
 {
-  if(!static_cast<bool>(face))
+  if (!static_cast<bool>(face))
     throw Error("Face is not set!");
 
-  if(!static_cast<bool>(m_certificateCache))
+  if (!static_cast<bool>(m_certificateCache))
     m_certificateCache = make_shared<CertificateCacheTtl>(m_face->ioService());
 }
 
 void
-ValidatorRegex::onCertificateValidated(const shared_ptr<const Data> &signCertificate, 
-                                       const shared_ptr<const Data> &data, 
-                                       const OnDataValidated &onValidated, 
-                                       const OnDataValidationFailed &onValidationFailed)
+ValidatorRegex::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
+                                       const shared_ptr<const Data>& data,
+                                       const OnDataValidated& onValidated,
+                                       const OnDataValidationFailed& onValidationFailed)
 {
-  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*signCertificate);
-  
-  if(!certificate->isTooLate() && !certificate->isTooEarly())
+  shared_ptr<IdentityCertificate> certificate =
+    make_shared<IdentityCertificate>(boost::cref(*signCertificate));
+
+  if (!certificate->isTooLate() && !certificate->isTooEarly())
     {
       m_certificateCache->insertCertificate(certificate);
-      
-      if(verifySignature(*data, certificate->getPublicKeyInfo()))
+
+      if (verifySignature(*data, certificate->getPublicKeyInfo()))
         return onValidated(data);
       else
-        return onValidationFailed(data, 
-                                  "Cannot verify signature: " + data->getName().toUri());
+        return onValidationFailed(data,
+                                  "Cannot verify signature: " +
+                                  data->getName().toUri());
     }
   else
     {
       _LOG_DEBUG("Wrong validity:");
-      return onValidationFailed(data, 
-                                "Signing certificate " + signCertificate->getName().toUri() + " is no longer valid.");
+      return onValidationFailed(data,
+                                "Signing certificate " +
+                                signCertificate->getName().toUri() +
+                                " is no longer valid.");
     }
 }
 
 void
-ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate, 
+ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
                                               const string& failureInfo,
-                                              const shared_ptr<const Data> &data, 
-                                              const OnDataValidationFailed &onValidationFailed)
-{ onValidationFailed(data, failureInfo); }
+                                              const shared_ptr<const Data>& data,
+                                              const OnDataValidationFailed& onValidationFailed)
+{
+  onValidationFailed(data, failureInfo);
+}
 
 void
-ValidatorRegex::checkPolicy(const Data& data, 
-                            int stepCount, 
-                            const OnDataValidated &onValidated, 
-                            const OnDataValidationFailed &onValidationFailed,
-                            vector<shared_ptr<ValidationRequest> > &nextSteps)
+ValidatorRegex::checkPolicy(const Data& data,
+                            int stepCount,
+                            const OnDataValidated& onValidated,
+                            const OnDataValidationFailed& onValidationFailed,
+                            vector<shared_ptr<ValidationRequest> >& nextSteps)
 {
-  if(m_stepLimit == stepCount)
-    return onValidationFailed(data.shared_from_this(), 
-                              "Maximum steps of validation reached: " + data.getName().toUri());
+  if (m_stepLimit == stepCount)
+    return onValidationFailed(data.shared_from_this(),
+                              "Maximum steps of validation reached: " +
+                              data.getName().toUri());
 
-  RuleList::iterator it = m_mustFailVerify.begin();
-  for(; it != m_mustFailVerify.end(); it++)
-    if((*it)->satisfy(data))
+  for (RuleList::iterator it = m_mustFailVerify.begin();
+       it != m_mustFailVerify.end();
+       it++)
+    if ((*it)->satisfy(data))
       return onValidationFailed(data.shared_from_this(),
-                                "Comply with mustFail policy: " + data.getName().toUri());
+                                "Comply with mustFail policy: " +
+                                data.getName().toUri());
 
-  it = m_verifyPolicies.begin();
-  for(; it != m_verifyPolicies.end(); it++)
+  for (RuleList::iterator it = m_verifyPolicies.begin();
+       it != m_verifyPolicies.end();
+       it++)
     {
-      if((*it)->satisfy(data))
+      if ((*it)->satisfy(data))
         {
           try
             {
-              SignatureSha256WithRsa sig(data.getSignature());                
-            
+              SignatureSha256WithRsa sig(data.getSignature());
+
               Name keyLocatorName = sig.getKeyLocator().getName();
               shared_ptr<const Certificate> trustedCert;
-              if(m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
+              if (m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
                 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
               else
                 trustedCert = m_trustAnchors[keyLocatorName];
-            
-              if(static_cast<bool>(trustedCert)){
-                if(verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
-                  return onValidated(data.shared_from_this());
-                else
-                  return onValidationFailed(data.shared_from_this(), 
-                                            "Cannot verify signature: " + data.getName().toUri());
-              }
-              else{
-                // _LOG_DEBUG("KeyLocator is not trust anchor");                
-                OnDataValidated onKeyValidated = bind(&ValidatorRegex::onCertificateValidated, this, 
-                                                      _1, data.shared_from_this(), onValidated, onValidationFailed);
-              
-                OnDataValidationFailed onKeyValidationFailed = bind(&ValidatorRegex::onCertificateValidationFailed, this, 
-                                                                    _1, _2, data.shared_from_this(), onValidationFailed);              
 
-                shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(Interest(boost::cref(sig.getKeyLocator().getName())), 
-                                                                                        onKeyValidated,
-                                                                                        onKeyValidationFailed,
-                                                                                        3,
-                                                                                        stepCount + 1);
-                nextSteps.push_back(nextStep);
+              if (static_cast<bool>(trustedCert))
+                {
+                  if (verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
+                    return onValidated(data.shared_from_this());
+                  else
+                    return onValidationFailed(data.shared_from_this(),
+                                              "Cannot verify signature: " +
+                                              data.getName().toUri());
+                }
+              else
+                {
+                  // _LOG_DEBUG("KeyLocator is not trust anchor");
+                  OnDataValidated onKeyValidated =
+                    bind(&ValidatorRegex::onCertificateValidated, this, _1,
+                         data.shared_from_this(), onValidated, onValidationFailed);
 
-                return;
-              }
+                  OnDataValidationFailed onKeyValidationFailed =
+                    bind(&ValidatorRegex::onCertificateValidationFailed, this, _1, _2,
+                         data.shared_from_this(), onValidationFailed);
+
+                  Interest interest(sig.getKeyLocator().getName());
+                  shared_ptr<ValidationRequest> nextStep =
+                    make_shared<ValidationRequest>(boost::cref(interest),
+                                                   onKeyValidated,
+                                                   onKeyValidationFailed,
+                                                   3,
+                                                   stepCount + 1);
+
+                  nextSteps.push_back(nextStep);
+
+                  return;
+                }
             }
-          catch(SignatureSha256WithRsa::Error &e)
-            {
-              return onValidationFailed(data.shared_from_this(), 
-                                        "Not SignatureSha256WithRsa signature: " + data.getName().toUri());
-            }
-          catch(KeyLocator::Error &e)
+          catch (const SignatureSha256WithRsa::Error& e)
             {
               return onValidationFailed(data.shared_from_this(),
-                                        "Key Locator is not a name: " + data.getName().toUri());
+                                        "Not SignatureSha256WithRsa signature: " +
+                                        data.getName().toUri());
+            }
+          catch (const KeyLocator::Error& e)
+            {
+              return onValidationFailed(data.shared_from_this(),
+                                        "Key Locator is not a name: " +
+                                        data.getName().toUri());
             }
         }
     }
 
-  return onValidationFailed(data.shared_from_this(), 
+  return onValidationFailed(data.shared_from_this(),
                             "No policy found for data: " + data.getName().toUri());
 }
 
diff --git a/src/security/validator-regex.hpp b/src/security/validator-regex.hpp
index 9caa380..1124620 100644
--- a/src/security/validator-regex.hpp
+++ b/src/security/validator-regex.hpp
@@ -19,61 +19,73 @@
 class ValidatorRegex : public Validator
 {
 public:
-  struct Error : public Validator::Error { Error(const std::string &what) : Validator::Error(what) {} };
+  class Error : public Validator::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : Validator::Error(what)
+    {
+    }
+  };
 
-  static const shared_ptr<CertificateCache> DefaultCertificateCache;
-  
+  static const shared_ptr<CertificateCache> DEFAULT_CERTIFICATE_CACHE;
+
   ValidatorRegex(shared_ptr<Face> face,
-                 shared_ptr<CertificateCache> certificateCache = DefaultCertificateCache, 
+                 shared_ptr<CertificateCache> certificateCache = DEFAULT_CERTIFICATE_CACHE,
                  const int stepLimit = 3);
-  
-  virtual 
-  ~ValidatorRegex() {}
-  
+
+  virtual
+  ~ValidatorRegex()
+  {
+  }
+
   /**
    * @brief Add a rule for data verification.
    *
    * @param policy The verification rule
    */
   inline void
-  addDataVerificationRule (shared_ptr<SecRuleRelative> rule);
-    
+  addDataVerificationRule(shared_ptr<SecRuleRelative> rule);
+
   /**
    * @brief Add a trust anchor
    *
-   * @param certificate The trust anchor 
+   * @param certificate The trust anchor
    */
-  inline void 
+  inline void
   addTrustAnchor(shared_ptr<IdentityCertificate> certificate);
 
 protected:
   virtual void
-  checkPolicy (const Data& data, 
-               int stepCount, 
-               const OnDataValidated &onValidated, 
-               const OnDataValidationFailed &onValidationFailed,
-               std::vector<shared_ptr<ValidationRequest> > &nextSteps);
+  checkPolicy(const Data& data,
+              int stepCount,
+              const OnDataValidated& onValidated,
+              const OnDataValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps);
 
   virtual void
-  checkPolicy (const Interest& interest, 
-               int stepCount, 
-               const OnInterestValidated &onValidated, 
-               const OnInterestValidationFailed &onValidationFailed,
-               std::vector<shared_ptr<ValidationRequest> > &nextSteps)
-  { onValidationFailed(interest.shared_from_this(), "No policy for signed interest checking"); }
+  checkPolicy(const Interest& interest,
+              int stepCount,
+              const OnInterestValidated& onValidated,
+              const OnInterestValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps)
+  {
+    onValidationFailed(interest.shared_from_this(), "No policy for signed interest checking");
+  }
 
   void
-  onCertificateValidated(const shared_ptr<const Data> &signCertificate, 
-                         const shared_ptr<const Data> &data, 
-                         const OnDataValidated &onValidated, 
-                         const OnDataValidationFailed &onValidationFailed);
-  
+  onCertificateValidated(const shared_ptr<const Data>& signCertificate,
+                         const shared_ptr<const Data>& data,
+                         const OnDataValidated& onValidated,
+                         const OnDataValidationFailed& onValidationFailed);
+
   void
-  onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate,
+  onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
                                 const std::string& failureInfo,
-                                const shared_ptr<const Data> &data, 
-                                const OnDataValidationFailed &onValidationFailed);
-  
+                                const shared_ptr<const Data>& data,
+                                const OnDataValidationFailed& onValidationFailed);
+
 protected:
   typedef std::vector< shared_ptr<SecRuleRelative> > RuleList;
   typedef std::vector< shared_ptr<Regex> > RegexList;
@@ -85,13 +97,17 @@
   std::map<Name, shared_ptr<IdentityCertificate> > m_trustAnchors;
 };
 
-inline void 
-ValidatorRegex::addDataVerificationRule (shared_ptr<SecRuleRelative> rule)
-{ rule->isPositive() ? m_verifyPolicies.push_back(rule) : m_mustFailVerify.push_back(rule); }
-      
-inline void  
+inline void
+ValidatorRegex::addDataVerificationRule(shared_ptr<SecRuleRelative> rule)
+{
+  rule->isPositive() ? m_verifyPolicies.push_back(rule) : m_mustFailVerify.push_back(rule);
+}
+
+inline void
 ValidatorRegex::addTrustAnchor(shared_ptr<IdentityCertificate> certificate)
-{ m_trustAnchors[certificate->getName().getPrefix(-1)] = certificate; }
+{
+  m_trustAnchors[certificate->getName().getPrefix(-1)] = certificate;
+}
 
 } // namespace ndn
 
diff --git a/src/security/validator.cpp b/src/security/validator.cpp
index f1d8035..cb5be23 100644
--- a/src/security/validator.cpp
+++ b/src/security/validator.cpp
@@ -21,47 +21,49 @@
 
 namespace ndn {
 
-const shared_ptr<Face> Validator::DefaultFace = shared_ptr<Face>();
+const shared_ptr<Face> Validator::DEFAULT_FACE;
 
-Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)                   
+Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
   : m_face(face)
-{}
+{
+}
 
 void
-Validator::validate(const Interest& interest, 
-                    const OnInterestValidated &onValidated, 
-                    const OnInterestValidationFailed &onValidationFailed,
+Validator::validate(const Interest& interest,
+                    const OnInterestValidated& onValidated,
+                    const OnInterestValidationFailed& onValidationFailed,
                     int stepCount)
 {
   vector<shared_ptr<ValidationRequest> > nextSteps;
   checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
-  
+
   if (!nextSteps.empty())
     {
-      if(!static_cast<bool>(m_face))
-        throw Error("Face should be set prior to verify method to call");
-      
+      if (!static_cast<bool>(m_face))
+        throw Error("Face should be set before calling validate method");
+
       vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
       OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
-      for(; it != nextSteps.end(); it++)
+      for (; it != nextSteps.end(); it++)
         m_face->expressInterest((*it)->m_interest,
-                                bind(&Validator::onData, this, _1, _2, *it), 
-                                bind(&Validator::onTimeout, 
-                                     this, _1, (*it)->m_retry, 
-                                     onFailure, 
+                                bind(&Validator::onData, this, _1, _2, *it),
+                                bind(&Validator::onTimeout,
+                                     this, _1, (*it)->m_retry,
+                                     onFailure,
                                      *it));
     }
   else
     {
-      //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
-      //No more further processes.
+      // If there is no nextStep,
+      // that means InterestPolicy has already been able to verify the Interest.
+      // No more further processes.
     }
 }
 
 void
-Validator::validate(const Data& data, 
-                    const OnDataValidated &onValidated, 
-                    const OnDataValidationFailed &onValidationFailed,
+Validator::validate(const Data& data,
+                    const OnDataValidated& onValidated,
+                    const OnDataValidationFailed& onValidationFailed,
                     int stepCount)
 {
   vector<shared_ptr<ValidationRequest> > nextSteps;
@@ -69,44 +71,45 @@
 
   if (!nextSteps.empty())
     {
-      if(!static_cast<bool>(m_face))
+      if (!static_cast<bool>(m_face))
         throw Error("Face should be set prior to verify method to call");
 
       vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
       OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
-      for(; it != nextSteps.end(); it++)
+      for (; it != nextSteps.end(); it++)
         m_face->expressInterest((*it)->m_interest,
-                                bind(&Validator::onData, this, _1, _2, *it), 
-                                bind(&Validator::onTimeout, 
-                                     this, _1, (*it)->m_retry, 
+                                bind(&Validator::onData, this, _1, _2, *it),
+                                bind(&Validator::onTimeout,
+                                     this, _1, (*it)->m_retry,
                                      onFailure,
                                      *it));
     }
   else
     {
-      //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
-      //No more further processes.
+      // If there is no nextStep,
+      // that means Data Policy has already been able to verify the Interest.
+      // No more further processes.
     }
 }
 
 void
-Validator::onData(const Interest& interest, 
-                  Data& data, 
+Validator::onData(const Interest& interest,
+                  const Data& data,
                   const shared_ptr<ValidationRequest>& nextStep)
 {
   validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
 }
 
 void
-Validator::onTimeout(const Interest& interest, 
-                     int retry, 
-                     const OnFailure &onFailure, 
+Validator::onTimeout(const Interest& interest,
+                     int retry,
+                     const OnFailure& onFailure,
                      const shared_ptr<ValidationRequest>& nextStep)
 {
   if (retry > 0)
     // Issue the same expressInterest except decrement retry.
-    m_face->expressInterest(interest, 
-                            bind(&Validator::onData, this, _1, _2, nextStep), 
+    m_face->expressInterest(interest,
+                            bind(&Validator::onData, this, _1, _2, nextStep),
                             bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
   else
     onFailure("Cannot fetch cert: " + interest.getName().toUri());
@@ -117,20 +120,21 @@
 {
   try
     {
-      switch(data.getSignature().getType()){
-      case Signature::Sha256WithRsa:
+      switch (data.getSignature().getType())
         {
-          SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
-          return verifySignature(data, sigSha256Rsa, key);
+        case Signature::Sha256WithRsa:
+          {
+            SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
+            return verifySignature(data, sigSha256Rsa, key);
+          }
+        default:
+          {
+            _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
+            return false;
+          }
         }
-      default:
-        {
-          _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
-          return false;
-        }
-      }
     }
-  catch(Signature::Error &e)
+  catch (const Signature::Error& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
@@ -141,40 +145,41 @@
 bool
 Validator::verifySignature(const Interest& interest, const PublicKey& key)
 {
-  const Name &interestName = interest.getName();
+  const Name& interestName = interest.getName();
 
-  if(interestName.size() < 2)
+  if (interestName.size() < 2)
     return false;
 
   try
     {
       const Block& nameBlock = interestName.wireEncode();
 
-      Signature sig(interestName[-2].blockFromValue(), 
+      Signature sig(interestName[-2].blockFromValue(),
                     interestName[-1].blockFromValue());
 
-      switch(sig.getType()){
-      case Signature::Sha256WithRsa:
+      switch (sig.getType())
         {
-          SignatureSha256WithRsa sigSha256Rsa(sig);
+        case Signature::Sha256WithRsa:
+          {
+            SignatureSha256WithRsa sigSha256Rsa(sig);
 
-          return verifySignature(nameBlock.value(), 
-                                 nameBlock.value_size() - interestName[-1].size(), 
-                                 sigSha256Rsa, key);
+            return verifySignature(nameBlock.value(),
+                                   nameBlock.value_size() - interestName[-1].size(),
+                                   sigSha256Rsa, key);
+          }
+        default:
+          {
+            _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
+            return false;
+          }
         }
-      default:
-        {
-          _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
-          return false;
-        }
-      }
     }
-  catch(Signature::Error &e)
+  catch (const Signature::Error& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
     }
-  catch(Block::Error &e)
+  catch (const Block::Error& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
@@ -187,20 +192,21 @@
 {
   try
     {
-      switch(sig.getType()){
-      case Signature::Sha256WithRsa:
+      switch (sig.getType())
         {
-          SignatureSha256WithRsa sigSha256Rsa(sig);
-          return verifySignature(data, sigSha256Rsa, key);
+        case Signature::Sha256WithRsa:
+          {
+            SignatureSha256WithRsa sigSha256Rsa(sig);
+            return verifySignature(data, sigSha256Rsa, key);
+          }
+        default:
+          {
+            _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
+            return false;
+          }
         }
-      default:
-        {
-          _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
-          return false;
-        }
-      }
     }
-  catch(Signature::Error &e)
+  catch (const Signature::Error& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
@@ -209,7 +215,10 @@
 }
 
 bool
-Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa& sig, const PublicKey& key)
+Validator::verifySignature(const uint8_t* buf,
+                           const size_t size,
+                           const SignatureSha256WithRsa& sig,
+                           const PublicKey& key)
 {
   try
     {
@@ -221,10 +230,12 @@
       queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
       publicKey.Load(queue);
 
-      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-      return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
+      RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
+      return verifier.VerifyMessage(buf, size,
+                                    sig.getValue().value(),
+                                    sig.getValue().value_size());
     }
-  catch(CryptoPP::Exception& e)
+  catch (const CryptoPP::Exception& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
@@ -239,23 +250,20 @@
       ConstBufferPtr buffer = crypto::sha256(buf, size);
       const Block& sigValue = sig.getValue();
 
-      if(static_cast<bool>(buffer) 
-         && buffer->size() == sigValue.value_size()
-         && buffer->size() == crypto::SHA256_DIGEST_SIZE)
+      if (static_cast<bool>(buffer) &&
+          buffer->size() == sigValue.value_size() &&
+          buffer->size() == crypto::SHA256_DIGEST_SIZE)
         {
 
           const uint8_t* p1 = buffer->buf();
           const uint8_t* p2 = sigValue.value();
 
-          for(size_t i = 0; i < crypto::SHA256_DIGEST_SIZE; i++)
-            if(p1[i] != p2[i]) 
-              return false;
-          return true;
+          return 0 == memcmp(p1, p2, crypto::SHA256_DIGEST_SIZE);
         }
       else
         return false;
     }
-  catch(CryptoPP::Exception& e)
+  catch (const CryptoPP::Exception& e)
     {
       _LOG_DEBUG("verifySignature: " << e.what());
       return false;
diff --git a/src/security/validator.hpp b/src/security/validator.hpp
index 5147dd7..2b55782 100644
--- a/src/security/validator.hpp
+++ b/src/security/validator.hpp
@@ -20,39 +20,56 @@
 
 namespace ndn {
 /**
- * Validator is one of the main classes of the security library.
+ * @brief Validator is one of the main classes of the security library.
  *
  * The Validator class provides the interfaces for packet validation.
  */
 class Validator {
 public:
-  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
 
-  static const shared_ptr<Face> DefaultFace;
+  static const shared_ptr<Face> DEFAULT_FACE;
 
-  Validator (shared_ptr<Face> face = DefaultFace);
+  explicit
+  Validator(shared_ptr<Face> face = DEFAULT_FACE);
 
   /**
-   * @brief Validate Data and call either onValidated or onValidationFailed. 
-   * 
+   * @brief Validate Data and call either onValidated or onValidationFailed.
+   *
    * @param data The Data with the signature to check.
    * @param onValidated If the Data is validated, this calls onValidated(data).
    * @param onValidationFailed If the Data validation fails, this calls onValidationFailed(data).
    */
   void
-  validate (const Data& data, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed)
-  { validate (data, onValidated, onValidationFailed, 0); }
+  validate(const Data& data,
+           const OnDataValidated& onValidated,
+           const OnDataValidationFailed& onValidationFailed)
+  {
+    validate(data, onValidated, onValidationFailed, 0);
+  }
 
   /**
-   * @brief Validate Interest and call either onValidated or onValidationFailed. 
-   * 
+   * @brief Validate Interest and call either onValidated or onValidationFailed.
+   *
    * @param interest The Interest with the signature to check.
    * @param onValidated If the Interest is validated, this calls onValidated(interest).
    * @param onValidationFailed If the Interest validation fails, this calls onValidationFailed(interest).
    */
   void
-  validate (const Interest& interest, const OnInterestValidated &onValidated, const OnInterestValidationFailed &onValidationFailed)
-  { validate (interest, onValidated, onValidationFailed, 0); }
+  validate(const Interest& interest,
+           const OnInterestValidated& onValidated,
+           const OnInterestValidationFailed& onValidationFailed)
+  {
+    validate(interest, onValidated, onValidationFailed, 0);
+  }
 
   /*****************************************
    *      verifySignature method set       *
@@ -60,53 +77,109 @@
 
   /// @brief Verify the data using the publicKey.
   static bool
-  verifySignature (const Data& data, const PublicKey& publicKey);
+  verifySignature(const Data& data, const PublicKey& publicKey);
 
-  /// @brief Verify the signed Interest using the publicKey.
+  /**
+   * @brief Verify the signed Interest using the publicKey.
+   *
+   * (Note the signature covers the first n-2 name components).
+   */
   static bool
-  verifySignature (const Interest& interest, const PublicKey& publicKey);
+  verifySignature(const Interest& interest, const PublicKey& publicKey);
 
   /// @brief Verify the blob using the publicKey against the signature.
   static bool
-  verifySignature (const Buffer& blob, const Signature& sig, const PublicKey& publicKey);
+  verifySignature(const Buffer& blob, const Signature& sig, const PublicKey& publicKey);
 
   /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
   static bool
-  verifySignature (const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey)
-  { return verifySignature (data.wireEncode().value(), 
-                            data.wireEncode().value_size() - data.getSignature().getValue().size(), 
-                            sig, publicKey); }
+  verifySignature(const Data& data,
+                  const SignatureSha256WithRsa& sig,
+                  const PublicKey& publicKey)
+  {
+    return verifySignature(data.wireEncode().value(),
+                           data.wireEncode().value_size() - data.getSignature().getValue().size(),
+                           sig, publicKey);
+  }
+
+  /** @brief Verify the interest using the publicKey against the SHA256-RSA signature.
+   *
+   * (Note the signature covers the first n-2 name components).
+   */
+  static bool
+  verifySignature(const Interest& interest,
+                  const SignatureSha256WithRsa& sig,
+                  const PublicKey& publicKey)
+  {
+    if (interest.getName().size() < 2)
+      return false;
+
+    Name signedName = interest.getName().getPrefix(-2);
+
+    return verifySignature(signedName.wireEncode().value(),
+                           signedName.wireEncode().value_size(),
+                           sig, publicKey);
+  }
 
   /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
   static bool
-  verifySignature (const Buffer& blob, const SignatureSha256WithRsa& sig, const PublicKey& publicKey)
-  { return verifySignature (blob.buf(), blob.size(), sig, publicKey); }
-  
+  verifySignature(const Buffer& blob,
+                  const SignatureSha256WithRsa& sig,
+                  const PublicKey& publicKey)
+  {
+    return verifySignature(blob.buf(), blob.size(), sig, publicKey);
+  }
+
   /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
   static bool
-  verifySignature (const uint8_t* buf, const size_t size, const SignatureSha256WithRsa &sig, const PublicKey &publicKey);
+  verifySignature(const uint8_t* buf,
+                  const size_t size,
+                  const SignatureSha256WithRsa& sig,
+                  const PublicKey& publicKey);
 
 
   /// @brief Verify the data against the SHA256 signature.
   static bool
-  verifySignature (const Data& data, const SignatureSha256& sig)
-  { return verifySignature (data.wireEncode().value(), 
-                            data.wireEncode().value_size() - data.getSignature().getValue().size(), 
-                            sig); }
+  verifySignature(const Data& data, const SignatureSha256& sig)
+  {
+    return verifySignature(data.wireEncode().value(),
+                           data.wireEncode().value_size() -
+                           data.getSignature().getValue().size(),
+                           sig);
+  }
+
+  /** @brief Verify the interest against the SHA256 signature.
+   *
+   * (Note the signature covers the first n-2 name components).
+   */
+  static bool
+  verifySignature(const Interest& interest, const SignatureSha256& sig)
+  {
+    if (interest.getName().size() < 2)
+      return false;
+
+    Name signedName = interest.getName().getPrefix(-2);
+
+    return verifySignature(signedName.wireEncode().value(),
+                           signedName.wireEncode().value_size(),
+                           sig);
+  }
 
   /// @brief Verify the blob against the SHA256 signature.
   static bool
-  verifySignature (const Buffer& blob, const SignatureSha256& sig)
-  { return verifySignature (blob.buf(), blob.size(), sig); }
-  
+  verifySignature(const Buffer& blob, const SignatureSha256& sig)
+  {
+    return verifySignature (blob.buf(), blob.size(), sig);
+  }
+
   /// @brief Verify the blob against the SHA256 signature.
   static bool
-  verifySignature (const uint8_t* buf, const size_t size, const SignatureSha256& sig);
+  verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig);
 
 
 protected:
   /**
-   * @brief Check the Data against validation policy and return the next validation step if necessary.
+   * @brief Check the Data against policy and return the next validation step if necessary.
    *
    * If there is no next validation step, that validation MUST have been done.
    * i.e., either onValidated or onValidationFailed callback is invoked.
@@ -118,11 +191,11 @@
    * @param nextSteps On return, contains the next validation step.
    */
   virtual void
-  checkPolicy (const Data& data, 
-               int stepCount, 
-               const OnDataValidated &onValidated, 
-               const OnDataValidationFailed &onValidationFailed,
-               std::vector<shared_ptr<ValidationRequest> > &nextSteps) = 0;
+  checkPolicy(const Data& data,
+              int stepCount,
+              const OnDataValidated& onValidated,
+              const OnDataValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
 
   /**
    * @brief Check the Interest against validation policy and return the next validation step if necessary.
@@ -137,39 +210,39 @@
    * @return the indication of next validation step, null if there is no further step.
    */
   virtual void
-  checkPolicy (const Interest& interest, 
-               int stepCount, 
-               const OnInterestValidated &onValidated, 
-               const OnInterestValidationFailed &onValidationFailed,
-               std::vector<shared_ptr<ValidationRequest> > &nextSteps) = 0;
+  checkPolicy(const Interest& interest,
+              int stepCount,
+              const OnInterestValidated& onValidated,
+              const OnInterestValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
 
 private:
   typedef function< void (const std::string&) > OnFailure;
-  
+
   /// @brief Process the received certificate.
   void
-  onData (const Interest& interest, 
-          Data& data, 
-          const shared_ptr<ValidationRequest>& nextStep);
-  
+  onData(const Interest& interest,
+         const Data& data,
+         const shared_ptr<ValidationRequest>& nextStep);
+
   /// @brief Re-express the interest if it times out.
   void
-  onTimeout (const Interest& interest, 
-             int retry, 
-             const OnFailure &onFailure, 
-             const shared_ptr<ValidationRequest>& nextStep);
+  onTimeout(const Interest& interest,
+            int retry,
+            const OnFailure& onFailure,
+            const shared_ptr<ValidationRequest>& nextStep);
 
   void
-  validate (const Data& data, 
-            const OnDataValidated &onValidated, 
-            const OnDataValidationFailed &onValidationFailed, 
-            int stepCount);
+  validate(const Data& data,
+           const OnDataValidated& onValidated,
+           const OnDataValidationFailed& onValidationFailed,
+           int stepCount);
 
   void
-  validate (const Interest& interest, 
-            const OnInterestValidated &onValidated, 
-            const OnInterestValidationFailed &onValidationFailed, 
-            int stepCount);
+  validate(const Interest& interest,
+           const OnInterestValidated& onValidated,
+           const OnInterestValidationFailed& onValidationFailed,
+           int stepCount);
 
 protected:
   shared_ptr<Face> m_face;
