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
