diff --git a/tools/pib/pib-validator.cpp b/tools/pib/pib-validator.cpp
new file mode 100644
index 0000000..cc34645
--- /dev/null
+++ b/tools/pib/pib-validator.cpp
@@ -0,0 +1,163 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2015 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "pib-validator.hpp"
+#include "encoding/pib-common.hpp"
+#include "encoding/update-param.hpp"
+#include <set>
+#include <string>
+
+namespace ndn {
+namespace pib {
+
+using std::set;
+using std::string;
+
+PibValidator::PibValidator(const PibDb& db, size_t maxCacheSize)
+  : m_db(db)
+  , m_isMgmtReady(false)
+{
+  m_owner = m_db.getOwnerName();
+  m_mgmtCert = m_db.getMgmtCertificate();
+
+  if (!m_owner.empty() && m_mgmtCert != nullptr)
+    m_isMgmtReady = true;
+
+  m_mgmtChangeConnection =
+    const_cast<PibDb&>(m_db).mgmtCertificateChanged.connect([this] () {
+        m_owner = m_db.getOwnerName();
+        m_mgmtCert = m_db.getMgmtCertificate();
+        if (!m_owner.empty() && m_mgmtCert != nullptr)
+          m_isMgmtReady = true;
+      });
+
+  m_keyDeletedConnection =
+    const_cast<PibDb&>(m_db).keyDeleted.connect([this] (Name keyName) {
+        m_keyCache.erase(keyName);
+      });
+}
+
+PibValidator::~PibValidator()
+{
+}
+
+void
+PibValidator::checkPolicy(const Interest& interest,
+                          int nSteps,
+                          const OnInterestValidated& onValidated,
+                          const OnInterestValidationFailed& onValidationFailed,
+                          std::vector<shared_ptr<ValidationRequest>>& nextSteps)
+{
+  if (!m_isMgmtReady)
+    return onValidationFailed(interest.shared_from_this(), "PibDb is not initialized");
+
+  const Name& interestName = interest.getName();
+
+  if (interestName.size() != SIGNED_PIB_INTEREST_SIZE) {
+    return onValidationFailed(interest.shared_from_this(),
+                              "Interest is not signed: " + interest.getName().toUri());
+  }
+
+  // Check if the user exists in PIB
+  string user = interestName.get(OFFSET_USER).toUri();
+  if (user != m_owner)
+    return onValidationFailed(interest.shared_from_this(), "Wrong user: " + user);
+
+  // Verify signature
+  try {
+    Signature signature(interestName[OFFSET_SIG_INFO].blockFromValue(),
+                        interestName[OFFSET_SIG_VALUE].blockFromValue());
+    // KeyLocator is required to contain the name of signing certificate (w/o version)
+    if (!signature.hasKeyLocator())
+      return onValidationFailed(interest.shared_from_this(), "No valid KeyLocator");
+
+    const KeyLocator& keyLocator = signature.getKeyLocator();
+    if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
+      return onValidationFailed(interest.shared_from_this(), "Key Locator is not a name");
+
+    // Check if PIB has the corresponding public key
+    shared_ptr<PublicKey> publicKey;
+
+    if (keyLocator.getName() == m_mgmtCert->getName().getPrefix(-1)) {
+      // the signing key is mgmt key.
+      publicKey = make_shared<PublicKey>(m_mgmtCert->getPublicKeyInfo());
+    }
+    else {
+      // the signing key is normal key.
+      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName());
+
+      shared_ptr<PublicKey> key = m_keyCache.find(keyName);
+      if (key != nullptr) {
+        // the signing key is cached.
+        publicKey = key;
+      }
+      else {
+        // the signing key is not cached.
+        publicKey = m_db.getKey(keyName);
+        if (publicKey == nullptr) {
+          // the signing key does not exist in PIB.
+          return onValidationFailed(interest.shared_from_this(), "Public key is not trusted");
+        }
+        else {
+          // the signing key is retrieved from PIB.
+          m_keyCache.insert(keyName, publicKey);
+        }
+      }
+    }
+
+    if (verifySignature(interest, signature, *publicKey))
+      onValidated(interest.shared_from_this());
+    else
+      onValidationFailed(interest.shared_from_this(), "Cannot verify signature");
+
+  }
+  catch (KeyLocator::Error&) {
+    return onValidationFailed(interest.shared_from_this(),
+                              "No valid KeyLocator");
+  }
+  catch (Signature::Error&) {
+    return onValidationFailed(interest.shared_from_this(),
+                              "No valid signature");
+  }
+  catch (IdentityCertificate::Error&) {
+    return onValidationFailed(interest.shared_from_this(),
+                              "Cannot determine the signing key");
+  }
+  catch (tlv::Error&) {
+    return onValidationFailed(interest.shared_from_this(),
+                              "Cannot decode signature");
+  }
+}
+
+void
+PibValidator::checkPolicy(const Data& data,
+                          int nSteps,
+                          const OnDataValidated& onValidated,
+                          const OnDataValidationFailed& onValidationFailed,
+                          std::vector<shared_ptr<ValidationRequest>>& nextSteps)
+{
+  // Pib does not express any interest, therefor should not validate any data.
+  onValidationFailed(data.shared_from_this(),
+                     "PibValidator should not receive data packet");
+}
+
+} // namespace pib
+} // namespace ndn
