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
