diff --git a/tools/pib/cert-publisher.cpp b/tools/pib/cert-publisher.cpp
new file mode 100644
index 0000000..abcd5a2
--- /dev/null
+++ b/tools/pib/cert-publisher.cpp
@@ -0,0 +1,128 @@
+/* -*- 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 "cert-publisher.hpp"
+
+namespace ndn {
+namespace pib {
+
+CertPublisher::CertPublisher(Face& face, PibDb& db)
+  : m_face(face)
+  , m_db(db)
+{
+  startPublishAll();
+
+  m_certDeletedConnection =
+    m_db.certificateDeleted.connect(bind(&CertPublisher::stopPublish, this, _1));
+  m_certInsertedConnection =
+    m_db.certificateInserted.connect(bind(&CertPublisher::startPublish, this, _1));
+}
+
+CertPublisher::~CertPublisher()
+{
+  for (const auto& it : m_registeredPrefixes)
+    m_face.unsetInterestFilter(it.second);
+}
+
+void
+CertPublisher::startPublishAll()
+{
+  // For now we have to register the prefix of certificates separately.
+  // The reason is that certificates do not share the same prefix that
+  // can aggregate the certificates publishing without attracting interests
+  // for non-PIB data.
+
+  std::vector<Name> identities = m_db.listIdentities();
+
+  for (const auto& identity : identities) {
+    std::vector<Name> keyNames = m_db.listKeyNamesOfIdentity(identity);
+
+    for (const auto& key : keyNames) {
+      std::vector<Name> certNames = m_db.listCertNamesOfKey(key);
+
+      for (const auto& certName : certNames)
+        startPublish(certName);
+    }
+  }
+}
+
+void
+CertPublisher::registerCertPrefix(const Name& certName)
+{
+  BOOST_ASSERT(!certName.empty());
+
+  const Name& prefix = certName.getPrefix(-1);
+
+  if (m_registeredPrefixes.find(prefix) == m_registeredPrefixes.end()) {
+    m_registeredPrefixes[prefix] =
+      m_face.setInterestFilter(certName.getPrefix(-1),
+        bind(&CertPublisher::processInterest, this, _1, _2),
+        [] (const Name& name) {},
+        [=] (const Name& name, const std::string& msg) {
+          if (m_registeredPrefixes.erase(prefix) == 0) {
+            // registration no longer needed - certificates deleted
+            return;
+          }
+          // retry
+          registerCertPrefix(certName);
+        });
+
+  }
+}
+
+void
+CertPublisher::processInterest(const InterestFilter& interestFilter,
+                               const Interest& interest)
+{
+  shared_ptr<const Data> certificate = m_responseCache.find(interest);
+  if (certificate != nullptr) {
+    m_face.put(*certificate);
+  }
+}
+
+void
+CertPublisher::startPublish(const Name& certName)
+{
+  m_responseCache.insert(*m_db.getCertificate(certName));
+  registerCertPrefix(certName);
+}
+
+void
+CertPublisher::stopPublish(const Name& certName)
+{
+  BOOST_ASSERT(!certName.empty());
+
+  m_responseCache.erase(certName);
+
+  // clear the listener if this is the only cert using the prefix
+  const Name& prefix = certName.getPrefix(-1); // strip version component
+
+  if (m_responseCache.find(prefix) != nullptr)
+    return;
+
+  auto it = m_registeredPrefixes.find(prefix);
+  BOOST_ASSERT(it != m_registeredPrefixes.end());
+  m_face.unsetInterestFilter(it->second);
+  m_registeredPrefixes.erase(it);
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/cert-publisher.hpp b/tools/pib/cert-publisher.hpp
new file mode 100644
index 0000000..052895c
--- /dev/null
+++ b/tools/pib/cert-publisher.hpp
@@ -0,0 +1,99 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_CERT_PUBLISHER_HPP
+#define NDN_PIB_CERT_PUBLISHER_HPP
+
+#include "pib-db.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
+
+namespace ndn {
+namespace pib {
+
+/// @brief implements the certificate publisher
+class CertPublisher : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param face The face pib used to receive queries and serve certificates.
+   * @param pibDb Database which holds the certificates.
+   */
+  CertPublisher(Face& face, PibDb& pibDb);
+
+  ~CertPublisher();
+
+private:
+  void
+  startPublishAll();
+
+  /**
+   * @brief add an interest filter for the certificate
+   */
+  void
+  registerCertPrefix(const Name& certName);
+
+  void
+  processInterest(const InterestFilter& interestFilter,
+                  const Interest& interest);
+
+  void
+  startPublish(const Name& certName);
+
+  /**
+   * @brief callback when a certificate is deleted
+   *
+   * The method will remove the cert from in-memory storage
+   * and also unset interest filter if the removed cert
+   * is the only one with the registered prefix.
+   *
+   * @param certName removed certificate name
+   */
+  void
+  stopPublish(const Name& certName);
+
+private:
+  Face& m_face;
+  PibDb& m_db;
+  util::InMemoryStoragePersistent m_responseCache;
+  std::map<Name, const RegisteredPrefixId*> m_registeredPrefixes;
+
+  util::signal::ScopedConnection m_certDeletedConnection;
+  util::signal::ScopedConnection m_certInsertedConnection;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_CERT_PUBLISHER_HPP
diff --git a/tools/pib/default-query-processor.cpp b/tools/pib/default-query-processor.cpp
new file mode 100644
index 0000000..4909ea2
--- /dev/null
+++ b/tools/pib/default-query-processor.cpp
@@ -0,0 +1,199 @@
+/* -*- 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 "default-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+
+const size_t DefaultQueryProcessor::DEFAULT_QUERY_LENGTH = 5;
+
+DefaultQueryProcessor::DefaultQueryProcessor(PibDb& db)
+  : m_db(db)
+{
+}
+
+std::pair<bool, Block>
+DefaultQueryProcessor::operator()(const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+
+  // handle pib query: /localhost/pib/[UserName]/default/param
+  if (interestName.size() != DEFAULT_QUERY_LENGTH) {
+    // malformed interest, discard
+    return std::make_pair(false, Block());
+  }
+
+  DefaultParam param;
+
+  try {
+    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
+  }
+  catch (const tlv::Error& e) {
+    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  switch (param.getTargetType()) {
+  case TYPE_ID:
+    return processDefaultIdQuery(param);
+  case TYPE_KEY:
+    return processDefaultKeyQuery(param);
+  case TYPE_CERT:
+    return processDefaultCertQuery(param);
+  default:
+    {
+      PibError error(ERR_WRONG_PARAM,
+                     "target type is not supported: " +
+                     boost::lexical_cast<string>(param.getTargetType()));
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+}
+
+std::pair<bool, Block>
+DefaultQueryProcessor::processDefaultIdQuery(const DefaultParam& param)
+{
+  if (param.getOriginType() == TYPE_USER) {
+    try {
+      PibIdentity result(m_db.getDefaultIdentity());
+      return std::make_pair(true, result.wireEncode());
+    }
+    catch (PibDb::Error&) {
+      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+  else {
+    PibError error(ERR_WRONG_PARAM,
+                   "origin type of id target must be USER(0), but gets: " +
+                   boost::lexical_cast<string>(param.getOriginType()));
+    return std::make_pair(true, error.wireEncode());
+  }
+}
+
+std::pair<bool, Block>
+DefaultQueryProcessor::processDefaultKeyQuery(const DefaultParam& param)
+{
+  Name identity;
+  if (param.getOriginType() == TYPE_ID)
+    identity = param.getOriginName();
+  else if (param.getOriginType() == TYPE_USER) {
+    try {
+      identity = m_db.getDefaultIdentity();
+    }
+    catch (PibDb::Error&) {
+      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+  else {
+    PibError error(ERR_WRONG_PARAM,
+                   "origin type of key target must be ID(1) or USER(0), but gets: " +
+                   boost::lexical_cast<string>(param.getOriginType()));
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  try {
+    Name keyName = m_db.getDefaultKeyNameOfIdentity(identity);
+    shared_ptr<PublicKey> key = m_db.getKey(keyName);
+
+    if (key == nullptr) {
+      PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+
+    PibPublicKey result(keyName, *key);
+    return std::make_pair(true, result.wireEncode());
+  }
+  catch (PibDb::Error& e) {
+    PibError error(ERR_NO_DEFAULT_KEY,
+                   "default key does not exist: " + string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+}
+
+std::pair<bool, Block>
+DefaultQueryProcessor::processDefaultCertQuery(const DefaultParam& param)
+{
+  Name identity;
+  if (param.getOriginType() == TYPE_USER) {
+    try {
+      identity = m_db.getDefaultIdentity();
+    }
+    catch (PibDb::Error&) {
+      PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+  else if (param.getOriginType() == TYPE_ID)
+    identity = param.getOriginName();
+  else if (param.getOriginType() != TYPE_KEY) {
+    PibError error(ERR_WRONG_PARAM,
+                   "origin type of cert target must be KEY(2), ID(1) or USER(0), but gets: " +
+                   boost::lexical_cast<string>(param.getOriginType()));
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  Name keyName;
+  if (param.getOriginType() == TYPE_KEY) {
+    keyName = param.getOriginName();
+    if (keyName.size() < 1) {
+      PibError error(ERR_WRONG_PARAM,
+                     "key name must contain key id component");
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+  else {
+    try {
+      keyName = m_db.getDefaultKeyNameOfIdentity(identity);
+    }
+    catch (PibDb::Error&) {
+      PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+
+  try {
+    Name certName = m_db.getDefaultCertNameOfKey(keyName);
+    shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(certName);
+
+    if (certificate == nullptr) {
+      PibError error (ERR_NO_DEFAULT_CERT, "default cert does not exist");
+      return std::make_pair(true, error.wireEncode());
+    }
+
+    PibCertificate result(*certificate);
+    return std::make_pair(true, result.wireEncode());
+  }
+  catch (PibDb::Error&) {
+    PibError error(ERR_NO_DEFAULT_CERT, "default cert does not exist");
+    return std::make_pair(true, error.wireEncode());
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/default-query-processor.hpp b/tools/pib/default-query-processor.hpp
new file mode 100644
index 0000000..1938074
--- /dev/null
+++ b/tools/pib/default-query-processor.hpp
@@ -0,0 +1,76 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
+#define NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
+
+#include "pib-db.hpp"
+#include "encoding/default-param.hpp"
+#include <ndn-cxx/interest.hpp>
+#include <utility>
+
+namespace ndn {
+namespace pib {
+
+class DefaultQueryProcessor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param db The pib database.
+   */
+  explicit
+  DefaultQueryProcessor(PibDb& db);
+
+  std::pair<bool, Block>
+  operator()(const Interest& interest);
+
+private:
+  std::pair<bool, Block>
+  processDefaultIdQuery(const DefaultParam& param);
+
+  std::pair<bool, Block>
+  processDefaultKeyQuery(const DefaultParam& param);
+
+  std::pair<bool, Block>
+  processDefaultCertQuery(const DefaultParam& param);
+
+private:
+  static const size_t DEFAULT_QUERY_LENGTH;
+
+  const PibDb&  m_db;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/delete-query-processor.cpp b/tools/pib/delete-query-processor.cpp
new file mode 100644
index 0000000..9174784
--- /dev/null
+++ b/tools/pib/delete-query-processor.cpp
@@ -0,0 +1,205 @@
+/* -*- 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 "delete-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+#include "pib.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+
+const size_t DeleteQueryProcessor::DELETE_QUERY_LENGTH = 9;
+const Name DeleteQueryProcessor::PIB_PREFIX("/localhost/pib");
+
+DeleteQueryProcessor::DeleteQueryProcessor(PibDb& db)
+  : m_db(db)
+{
+}
+
+std::pair<bool, Block>
+DeleteQueryProcessor::operator()(const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+
+  // handle pib query: /localhost/pib/[UserName]/delete/param/<signed_interest_related_components>
+  if (interestName.size() != DELETE_QUERY_LENGTH) {
+    // malformed interest, discard
+    return std::make_pair(false, Block());
+  }
+
+  try {
+    DeleteParam param;
+    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
+
+    SignatureInfo sigInfo;
+    sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
+
+    // sigInfo must have KeyLocator.Name if the interest passed validation.
+    Name signerName;
+    signerName = sigInfo.getKeyLocator().getName();
+
+    switch (param.getTargetType()) {
+    case TYPE_USER:
+      return std::make_pair(true, PibError(ERR_WRONG_PARAM, "not allowed to delete user").wireEncode());
+    case TYPE_ID:
+      return processDeleteIdQuery(param, signerName);
+    case TYPE_KEY:
+      return processDeleteKeyQuery(param, signerName);
+    case TYPE_CERT:
+      return processDeleteCertQuery(param, signerName);
+    default:
+      {
+        PibError error(ERR_WRONG_PARAM,
+                       "target type is not supported: " +
+                       boost::lexical_cast<string>(param.getTargetType()));
+        return std::make_pair(true, error.wireEncode());
+      }
+    }
+  }
+  catch (const PibDb::Error& e) {
+    PibError error(ERR_INTERNAL_ERROR, e.what());
+    return std::make_pair(true, error.wireEncode());
+  }
+  catch (const tlv::Error& e) {
+    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+}
+
+std::pair<bool, Block>
+DeleteQueryProcessor::processDeleteIdQuery(const DeleteParam& param, const Name& signerName)
+{
+  Name identity = param.getTargetName();
+  if (!isDeleteAllowed(TYPE_ID, identity, signerName)) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  m_db.deleteIdentity(identity);
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+std::pair<bool, Block>
+DeleteQueryProcessor::processDeleteKeyQuery(const DeleteParam& param, const Name& signerName)
+{
+  const Name& keyName = param.getTargetName();
+  if (!isDeleteAllowed(TYPE_KEY, keyName, signerName)) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  m_db.deleteKey(keyName);
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+std::pair<bool, Block>
+DeleteQueryProcessor::processDeleteCertQuery(const DeleteParam& param, const Name& signerName)
+{
+  const Name& certName = param.getTargetName();
+  if (!isDeleteAllowed(TYPE_CERT, certName, signerName)) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  m_db.deleteCertificate(certName);
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+bool
+DeleteQueryProcessor::isDeleteAllowed(const pib::Type targetType,
+                                      const Name& targetName,
+                                      const Name& signer) const
+{
+  // sanity checking, user cannot be deleted.
+  if (targetType == TYPE_USER)
+    return false;
+
+  // Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
+  // that prefix will be rejected.
+  if (PIB_PREFIX.isPrefixOf(targetName))
+    return false;
+
+  // Rules for other items:
+  //
+  //    signer                   | deleting privilege
+  //    =========================+===============================================
+  //    local mgmt key           | any id, key, and cert
+  //    -------------------------+-----------------------------------------------
+  //    default key of an id     | any id, key, and cert under the id's namespace
+  //    -------------------------+-----------------------------------------------
+  //    non-default key of an id | any cert of the key
+
+  const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
+  const Name& signerId = signerKeyName.getPrefix(-1);
+
+  bool hasSignerDefaultKey = true;
+  Name signerDefaultKeyName;
+  try {
+    signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
+  }
+  catch (PibDb::Error&) {
+    hasSignerDefaultKey = false;
+  }
+
+  Name mgmtCertName;
+  try {
+    mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
+  }
+  catch (PibDb::Error&) {
+    return false;
+  }
+
+  if (signer == mgmtCertName) {
+    // signer is current management key, anything is allowed.
+    return true;
+  }
+  else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
+    // signer is an identity's default key
+    if (!signerId.isPrefixOf(targetName))
+      return false;
+    else
+      return true;
+  }
+  else {
+    // non-default key
+    if (targetType == TYPE_CERT) {
+      // check if it is for the key's cert
+      if (IdentityCertificate::certificateNameToPublicKeyName(targetName) == signerKeyName)
+        return true;
+    }
+    else if (targetType == TYPE_KEY) {
+      // check if it is for the key itself
+      if (targetName == signerKeyName)
+        return true;
+    }
+    return false;
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/delete-query-processor.hpp b/tools/pib/delete-query-processor.hpp
new file mode 100644
index 0000000..3336deb
--- /dev/null
+++ b/tools/pib/delete-query-processor.hpp
@@ -0,0 +1,93 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
+#define NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
+
+#include "pib-db.hpp"
+#include "encoding/delete-param.hpp"
+#include <ndn-cxx/interest.hpp>
+#include <utility>
+
+namespace ndn {
+namespace pib {
+
+class Pib;
+
+/// @brief Processing unit for PIB delete query
+class DeleteQueryProcessor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param db The pib database.
+   */
+  explicit
+  DeleteQueryProcessor(PibDb& db);
+
+  std::pair<bool, Block>
+  operator()(const Interest& interest);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Determine if a delete command is allowed.
+   *
+   * @param targetType The type of the target that will be deleted.
+   * @param targetName The name of the target that will be deleted.
+   * @param signer     The name of the command signer.
+   */
+  bool
+  isDeleteAllowed(const pib::Type targetType,
+                  const Name& targetName,
+                  const Name& signer) const;
+
+private:
+  std::pair<bool, Block>
+  processDeleteIdQuery(const DeleteParam& param, const Name& signerName);
+
+  std::pair<bool, Block>
+  processDeleteKeyQuery(const DeleteParam& param, const Name& signerName);
+
+  std::pair<bool, Block>
+  processDeleteCertQuery(const DeleteParam& param, const Name& signerName);
+
+private:
+  static const size_t DELETE_QUERY_LENGTH;
+  static const Name PIB_PREFIX;
+
+  PibDb&  m_db;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/encoding/default-param.cpp b/tools/pib/encoding/default-param.cpp
new file mode 100644
index 0000000..015bf19
--- /dev/null
+++ b/tools/pib/encoding/default-param.cpp
@@ -0,0 +1,168 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "default-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, DefaultParam::Error>::value,
+              "DefaultParam::Error must inherit from tlv::Error");
+
+const std::string DefaultParam::VERB("default");
+
+DefaultParam::DefaultParam()
+  : m_targetType(TYPE_DEFAULT)
+  , m_originType(TYPE_DEFAULT)
+{
+}
+
+DefaultParam::DefaultParam(const pib::Type targetType,
+                           const pib::Type originType,
+                           const Name& originName)
+  : m_targetType(targetType)
+  , m_originType(originType)
+  , m_originName(originName)
+{
+}
+
+DefaultParam::DefaultParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+DefaultParam::getOriginName() const
+{
+  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
+    return m_originName;
+  else
+    throw Error("DefaultParam::getOriginName: origin name does not exist");
+}
+
+template<bool T>
+size_t
+DefaultParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_originName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("DefaultParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::DefaultParam);
+
+  return totalLength;
+}
+
+template size_t
+DefaultParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+DefaultParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+DefaultParam::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+DefaultParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::DefaultParam)
+    throw Error("Unexpected TLV type when decoding DefaultParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DefaultParam requires the first sub-TLV to be PibType");
+
+  // the second block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DefaultParam requires the second sub-TLV to be PibType");
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the third block, if exists, must be Name
+        m_originName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("DefaultParam requires the third sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("DefaultParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/default-param.hpp b/tools/pib/encoding/default-param.hpp
new file mode 100644
index 0000000..1906954
--- /dev/null
+++ b/tools/pib/encoding/default-param.hpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+
+#ifndef NDN_PIB_DEFAULT_PARAM_HPP
+#define NDN_PIB_DEFAULT_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief DefaultParam is the abstraction of PIB Default parameter.
+ *
+ *  PibDefaultParam := PIB-DEFAULT-PARAM-TYPE TLV-LENGTH
+ *                     PibType    // target type
+ *                     PibType    // origin type
+ *                     Name?      // origin name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Default-Parameters
+ */
+
+class DefaultParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  DefaultParam();
+
+  DefaultParam(const pib::Type targetType,
+               const pib::Type originType,
+               const Name& originName = Name());
+
+  explicit
+  DefaultParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::DefaultParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  pib::Type
+  getOriginType() const
+  {
+    return m_originType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if origin name does not exist
+   */
+  const Name&
+  getOriginName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  pib::Type m_originType;
+  Name m_originName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+
+
+#endif // NDN_PIB_DEFAULT_PARAM_HPP
diff --git a/tools/pib/encoding/delete-param.cpp b/tools/pib/encoding/delete-param.cpp
new file mode 100644
index 0000000..41c8f6a
--- /dev/null
+++ b/tools/pib/encoding/delete-param.cpp
@@ -0,0 +1,129 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "delete-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, DeleteParam::Error>::value,
+              "DeleteParam::Error must inherit from tlv::Error");
+
+const std::string DeleteParam::VERB("delete");
+
+DeleteParam::DeleteParam()
+  : m_targetType(TYPE_DEFAULT)
+{
+}
+
+DeleteParam::DeleteParam(const Name& name, pib::Type type)
+  : m_targetType(type)
+  , m_targetName(name)
+{
+}
+
+DeleteParam::DeleteParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+DeleteParam::wireEncode(EncodingImpl<T>& block) const
+{
+  if (m_targetType != TYPE_ID &&
+      m_targetType != TYPE_KEY &&
+      m_targetType != TYPE_CERT &&
+      m_targetType != TYPE_USER)
+    throw Error("DeleteParam::wireEncode: Wrong Type value: " +
+                boost::lexical_cast<std::string>(m_targetType));
+
+  size_t totalLength = 0;
+
+  totalLength += m_targetName.wireEncode(block);
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::DeleteParam);
+
+  return totalLength;
+}
+
+template size_t
+DeleteParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+DeleteParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+DeleteParam::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+DeleteParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::DeleteParam)
+    throw Error("Unexpected TLV type when decoding DeleteParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Type
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DeleteParam requires the first sub-TLV to be Type");
+
+  // the second block must be Name
+  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
+    m_targetName.wireDecode(*it);
+    it++;
+  }
+  else
+    throw Error("DeleteParam requires the second sub-TLV to be Name");
+
+  if (it != m_wire.elements_end())
+    throw Error("DeleteParam must not contain more than two sub-TLVs");
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/delete-param.hpp b/tools/pib/encoding/delete-param.hpp
new file mode 100644
index 0000000..14d8392
--- /dev/null
+++ b/tools/pib/encoding/delete-param.hpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_DELETE_PARAM_HPP
+#define NDN_PIB_DELETE_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief DeleteParam is the abstraction of PIB Delete parameter.
+ *
+ * PibDeleteParam := PIB-DELETE-PARAM-TYPE TLV-LENGTH
+ *                   PibType
+ *                   Name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Delete-Parameters
+ */
+
+class DeleteParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  DeleteParam();
+
+  explicit
+  DeleteParam(const Name& name, const pib::Type type = TYPE_ID);
+
+  explicit
+  DeleteParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::DeleteParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  const Name&
+  getTargetName() const
+  {
+    return m_targetName;
+  }
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  Name m_targetName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_DELETE_PARAM_HPP
diff --git a/tools/pib/encoding/get-param.cpp b/tools/pib/encoding/get-param.cpp
new file mode 100644
index 0000000..ea076f9
--- /dev/null
+++ b/tools/pib/encoding/get-param.cpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "get-param.hpp"
+#include <boost/lexical_cast.hpp>
+#include <ndn-cxx/encoding/block-helpers.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, GetParam::Error>::value,
+              "GetParam::Error must inherit from tlv::Error");
+
+const std::string GetParam::VERB("get");
+
+GetParam::GetParam()
+  : m_targetType(TYPE_USER)
+{
+}
+
+GetParam::GetParam(const pib::Type targetType, const Name& targetName)
+  : m_targetType(targetType)
+  , m_targetName(targetName)
+{
+}
+
+GetParam::GetParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+GetParam::getTargetName() const
+{
+  if (m_targetType == TYPE_ID || m_targetType == TYPE_KEY || m_targetType == TYPE_CERT)
+    return m_targetName;
+  else
+    throw Error("GetParam::getTargetName: target name does not exist");
+}
+
+template<bool T>
+size_t
+GetParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_targetType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_targetName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("GetParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_targetType));
+  }
+
+  // Encode Type
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::GetParam);
+
+  return totalLength;
+}
+
+template size_t
+GetParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+GetParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+GetParam::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+GetParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::GetParam)
+    throw Error("Unexpected TLV type when decoding GetParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Type
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("GetParam requires the first sub-TLV to be PibType");
+
+  switch (m_targetType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the second block, if exists, must be Name
+        m_targetName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("GetParam requires the second sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("GetParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_targetType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/get-param.hpp b/tools/pib/encoding/get-param.hpp
new file mode 100644
index 0000000..39a6c0e
--- /dev/null
+++ b/tools/pib/encoding/get-param.hpp
@@ -0,0 +1,115 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_GET_PARAM_HPP
+#define NDN_PIB_GET_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief GetParam is the abstraction of PIB Get parameter.
+ *
+ * PibGetParam := PIB-GET-PARAM-TYPE TLV-LENGTH
+ *                PibType
+ *                Name?
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Get-Parameters
+ */
+
+class GetParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  GetParam();
+
+  GetParam(const pib::Type targetType, const Name& targetName);
+
+  explicit
+  GetParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::GetParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if target name does not exist
+   */
+  const Name&
+  getTargetName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  Name m_targetName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_GET_PARAM_HPP
diff --git a/tools/pib/encoding/list-param.cpp b/tools/pib/encoding/list-param.cpp
new file mode 100644
index 0000000..cb604e6
--- /dev/null
+++ b/tools/pib/encoding/list-param.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "list-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, ListParam::Error>::value,
+              "ListParam::Error must inherit from tlv::Error");
+
+const std::string ListParam::VERB("list");
+
+ListParam::ListParam()
+  : m_originType(TYPE_USER)
+{
+}
+
+ListParam::ListParam(const pib::Type originType, const Name& originName)
+  : m_originType(originType)
+  , m_originName(originName)
+{
+}
+
+ListParam::ListParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+ListParam::getOriginName() const
+{
+  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
+    return m_originName;
+  else
+    throw Error("ListParam::getOriginName: origin name does not exist");
+}
+
+template<bool T>
+size_t
+ListParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_originName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("ListParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::ListParam);
+
+  return totalLength;
+}
+
+template size_t
+ListParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+ListParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+ListParam::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+ListParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::ListParam)
+    throw Error("Unexpected TLV type when decoding ListParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("ListParam requires the first sub-TLV to be PibType");
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the second block, if exists, must be Name
+        m_originName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("ListParam requires the second sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("ListParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/list-param.hpp b/tools/pib/encoding/list-param.hpp
new file mode 100644
index 0000000..f94732e
--- /dev/null
+++ b/tools/pib/encoding/list-param.hpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+
+#ifndef NDN_PIB_LIST_PARAM_HPP
+#define NDN_PIB_LIST_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief ListParam is the abstraction of PIB List parameter.
+ *
+ *  PibListParam := PIB-LIST-PARAM-TYPE TLV-LENGTH
+ *                  PibType    // origin type
+ *                  Name?      // origin name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
+ */
+
+class ListParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  ListParam();
+
+  ListParam(const pib::Type originType, const Name& originName);
+
+  explicit
+  ListParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::ListParam;
+  }
+
+  pib::Type
+  getOriginType() const
+  {
+    return m_originType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if origin name does not exist
+   */
+  const Name&
+  getOriginName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_originType;
+  Name m_originName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+
+
+#endif // NDN_PIB_LIST_PARAM_HPP
diff --git a/tools/pib/encoding/pib-common.hpp b/tools/pib/encoding/pib-common.hpp
new file mode 100644
index 0000000..74c5daf
--- /dev/null
+++ b/tools/pib/encoding/pib-common.hpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_PIB_COMMON_HPP
+#define NDN_PIB_PIB_COMMON_HPP
+
+namespace ndn {
+namespace pib {
+
+/// @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
+
+enum {
+  OFFSET_USER              = 2,
+  OFFSET_VERB              = 3,
+  OFFSET_PARAM             = 4,
+  OFFSET_TIMESTAMP         = 5,
+  OFFSET_NONCE             = 6,
+  OFFSET_SIG_INFO          = 7,
+  OFFSET_SIG_VALUE         = 8,
+
+  MIN_PIB_INTEREST_SIZE    = 5,
+  SIGNED_PIB_INTEREST_SIZE = 9
+};
+
+enum Type {
+  TYPE_USER    = 0,
+  TYPE_ID      = 1,
+  TYPE_KEY     = 2,
+  TYPE_CERT    = 3,
+  TYPE_DEFAULT = 255
+};
+
+enum DefaultOpt {
+  DEFAULT_OPT_NO   = 0,
+  DEFAULT_OPT_KEY  = 1, // 0x01
+  DEFAULT_OPT_ID   = 3, // 0x03
+  DEFAULT_OPT_USER = 7 // 0x07
+};
+
+enum DefaultOptMask {
+  DEFAULT_OPT_KEY_MASK  = 0x1,
+  DEFAULT_OPT_ID_MASK   = 0x2,
+  DEFAULT_OPT_USER_MASK = 0x4
+};
+
+enum ErrCode {
+  ERR_SUCCESS = 0,
+
+  // Invalid query
+  ERR_INCOMPLETE_COMMAND = 1,
+  ERR_WRONG_VERB         = 2,
+  ERR_WRONG_PARAM        = 3,
+  ERR_WRONG_SIGNER       = 4,
+  ERR_INTERNAL_ERROR     = 5,
+
+  // Non existing entity
+  ERR_NON_EXISTING_USER = 128,
+  ERR_NON_EXISTING_ID   = 129,
+  ERR_NON_EXISTING_KEY  = 130,
+  ERR_NON_EXISTING_CERT = 131,
+
+  // No default setting
+  ERR_NO_DEFAULT_ID     = 256,
+  ERR_NO_DEFAULT_KEY    = 257,
+  ERR_NO_DEFAULT_CERT   = 258,
+
+  // Delete default setting
+  ERR_DELETE_DEFAULT_SETTING = 384
+};
+
+} // namespace pib
+
+
+namespace tlv {
+namespace pib {
+
+enum ParamType {
+  GetParam          = 128, // 0x80
+  DefaultParam      = 129, // 0x81
+  ListParam         = 130, // 0x82
+  UpdateParam       = 131, // 0x83
+  DeleteParam       = 132  // 0x84
+};
+
+enum EntityType {
+  User              = 144, // 0x90
+  Identity          = 145, // 0x91
+  PublicKey         = 146, // 0x92
+  Certificate       = 147  // 0x93
+};
+
+// Other
+enum {
+  Bytes             = 148, // 0x94
+  DefaultOpt        = 149, // 0x95
+  NameList          = 150, // 0x96
+  Type              = 151, // 0x97
+  Error             = 152, // 0x98
+  TpmLocator        = 153, // 0x99
+
+  // ErrorCode
+  ErrorCode         = 252  // 0xfc
+};
+
+} // namespace pib
+} // namespace tlv
+} // namespace ndn
+
+
+#endif // NDN_PIB_PIB_COMMON_HPP
diff --git a/tools/pib/encoding/pib-encoding.cpp b/tools/pib/encoding/pib-encoding.cpp
new file mode 100644
index 0000000..e7c5ca4
--- /dev/null
+++ b/tools/pib/encoding/pib-encoding.cpp
@@ -0,0 +1,525 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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-encoding.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <vector>
+#include <string>
+
+namespace ndn {
+namespace pib {
+
+using std::vector;
+using std::string;
+
+PibIdentity::PibIdentity()
+{
+}
+
+PibIdentity::PibIdentity(const Name& identity)
+  : m_identity(identity)
+{
+}
+
+PibIdentity::PibIdentity(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibIdentity::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = m_identity.wireEncode(block);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Identity);
+
+  return totalLength;
+}
+
+template size_t
+PibIdentity::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibIdentity::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibIdentity::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibIdentity::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Identity)
+    throw tlv::Error("Unexpected TLV type when decoding PibIdentity");
+
+  m_wire = wire;
+  m_identity.wireDecode(m_wire.blockFromValue());
+}
+
+
+
+PibPublicKey::PibPublicKey()
+  : m_isValueSet(false)
+{
+}
+
+PibPublicKey::PibPublicKey(const Name& keyName, const PublicKey& key)
+  : m_isValueSet(true)
+  , m_keyName(keyName)
+  , m_key(key)
+{
+}
+
+PibPublicKey::PibPublicKey(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+PibPublicKey::getKeyName() const
+{
+  if (m_isValueSet)
+    return m_keyName;
+  else
+    throw tlv::Error("PibPublicKey::getKeyName: keyName is not set");
+}
+
+const PublicKey&
+PibPublicKey::getPublicKey() const
+{
+  if (m_isValueSet)
+    return m_key;
+  else
+    throw tlv::Error("PibPublicKey::getPublicKey: key is not set");
+}
+
+template<bool T>
+size_t
+PibPublicKey::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = prependByteArrayBlock(block, tlv::pib::Bytes,
+                                             m_key.get().buf(), m_key.get().size());
+  totalLength += m_keyName.wireEncode(block);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::PublicKey);
+
+  return totalLength;
+}
+
+template size_t
+PibPublicKey::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibPublicKey::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibPublicKey::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibPublicKey::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::PublicKey)
+    throw tlv::Error("Unexpected TLV type when decoding PibPublicKey");
+
+  m_wire = wire;
+  m_wire.parse();
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
+    m_keyName.wireDecode(*it);
+    it++;
+  }
+  else
+    throw tlv::Error("PibPublicKey requires the first sub-TLV to be Name");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
+    m_key = PublicKey(it->value(), it->value_size());
+    it++;
+  }
+  else
+    throw tlv::Error("PibPublicKey requires the second sub-TLV to be Bytes");
+
+  m_isValueSet = true;
+  if (it != m_wire.elements_end())
+    throw tlv::Error("PibPublicKey must contain only two sub-TLVs");
+}
+
+
+PibCertificate::PibCertificate()
+  : m_isValueSet(false)
+{
+}
+
+PibCertificate::PibCertificate(const IdentityCertificate& certificate)
+  : m_isValueSet(true)
+  , m_certificate(certificate)
+{
+}
+
+PibCertificate::PibCertificate(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const IdentityCertificate&
+PibCertificate::getCertificate() const
+{
+  if (m_isValueSet)
+    return m_certificate;
+  else
+    throw tlv::Error("PibCertificate::getCertificate: certificate is not set");
+}
+
+template<bool T>
+size_t
+PibCertificate::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = prependBlock(block, m_certificate.wireEncode());
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Certificate);
+
+  return totalLength;
+}
+
+template size_t
+PibCertificate::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibCertificate::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibCertificate::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibCertificate::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Certificate)
+    throw tlv::Error("Unexpected TLV type when decoding PibCertificate");
+
+  m_wire = wire;
+  m_certificate.wireDecode(m_wire.blockFromValue());
+
+  m_isValueSet = true;
+}
+
+
+PibNameList::PibNameList()
+{
+}
+
+PibNameList::PibNameList(const std::vector<Name>& names)
+  : m_names(names)
+{
+}
+
+PibNameList::PibNameList(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibNameList::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  for (vector<Name>::const_reverse_iterator it = m_names.rbegin();
+       it != m_names.rend(); it++) {
+    totalLength += it->wireEncode(block);
+  }
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::NameList);
+  return totalLength;
+}
+
+template size_t
+PibNameList::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibNameList::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibNameList::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibNameList::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::NameList)
+    throw tlv::Error("Unexpected TLV type when decoding PibNameList");
+
+  m_wire = wire;
+  m_wire.parse();
+  for (Block::element_const_iterator it = m_wire.elements_begin();
+       it != m_wire.elements_end(); it++) {
+    if (it->type() == tlv::Name) {
+      Name name;
+      name.wireDecode(*it);
+      m_names.push_back(name);
+    }
+  }
+}
+
+PibError::PibError()
+  : m_errCode(ERR_SUCCESS)
+{
+}
+
+PibError::PibError(const pib::ErrCode errCode, const std::string& msg)
+  : m_errCode(errCode)
+  , m_msg(msg)
+{
+}
+
+PibError::PibError(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibError::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+  totalLength += prependByteArrayBlock(block, tlv::pib::Bytes,
+                                       reinterpret_cast<const uint8_t*>(m_msg.c_str()),
+                                       m_msg.size());
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::ErrorCode, m_errCode);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Error);
+  return totalLength;
+}
+
+template size_t
+PibError::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibError::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibError::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibError::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Error)
+    throw tlv::Error("Unexpected TLV type when decoding Error");
+
+  m_wire = wire;
+  m_wire.parse();
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::ErrorCode) {
+    m_errCode = static_cast<pib::ErrCode>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the first sub-TLV to be ErrorCode");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
+    m_msg = string(reinterpret_cast<const char*>(it->value()), it->value_size());
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the second sub-TLV to be Bytes");
+}
+
+PibUser::PibUser()
+{
+}
+
+PibUser::PibUser(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+void
+PibUser::setMgmtCert(const IdentityCertificate& mgmtCert)
+{
+  m_wire.reset();
+  m_mgmtCert = mgmtCert;
+}
+
+void
+PibUser::setTpmLocator(const std::string& tpmLocator)
+{
+  m_wire.reset();
+  m_tpmLocator = tpmLocator;
+}
+
+template<bool T>
+size_t
+PibUser::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  if (!m_tpmLocator.empty())
+    totalLength = prependByteArrayBlock(block, tlv::pib::TpmLocator,
+                                        reinterpret_cast<const uint8_t*>(m_tpmLocator.c_str()),
+                                        m_tpmLocator.size());
+
+  totalLength += prependBlock(block, m_mgmtCert.wireEncode());
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::User);
+
+  return totalLength;
+}
+
+template size_t
+PibUser::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibUser::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibUser::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+PibUser::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::User)
+    throw tlv::Error("Unexpected TLV type when decoding Content");
+
+  m_wire = wire;
+  m_wire.parse();
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+  if (it != m_wire.elements_end() && it->type() == tlv::Data) {
+    m_mgmtCert.wireDecode(*it);
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the first sub-TLV to be Data");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::TpmLocator) {
+    m_tpmLocator = string(reinterpret_cast<const char*>(it->value()), it->value_size());
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/pib-encoding.hpp b/tools/pib/encoding/pib-encoding.hpp
new file mode 100644
index 0000000..9ebb4c4
--- /dev/null
+++ b/tools/pib/encoding/pib-encoding.hpp
@@ -0,0 +1,316 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_PIB_ENCODING_HPP
+#define NDN_PIB_PIB_ENCODING_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/security/identity-certificate.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief Abstraction of pib::Identity TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibIdentity
+{
+public:
+  PibIdentity();
+
+  explicit
+  PibIdentity(const Name& identity);
+
+  explicit
+  PibIdentity(const Block& wire);
+
+  const Name&
+  getIdentity() const
+  {
+    return m_identity;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibIdentity from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  Name m_identity;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::PublicKey TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibPublicKey
+{
+public:
+  PibPublicKey();
+
+  PibPublicKey(const Name& keyName, const PublicKey& key);
+
+  explicit
+  PibPublicKey(const Block& wire);
+
+  const Name&
+  getKeyName() const;
+
+  const PublicKey&
+  getPublicKey() const;
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibPublicKey from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  bool m_isValueSet;
+  Name m_keyName;
+  PublicKey m_key;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::Certificate TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibCertificate
+{
+public:
+  PibCertificate();
+
+  explicit
+  PibCertificate(const IdentityCertificate& certificate);
+
+  explicit
+  PibCertificate(const Block& wire);
+
+  const IdentityCertificate&
+  getCertificate() const;
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  bool m_isValueSet;
+  IdentityCertificate m_certificate;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::NameList TLV.
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
+ */
+class PibNameList : noncopyable
+{
+public:
+  PibNameList();
+
+  explicit
+  PibNameList(const std::vector<Name>& names);
+
+  explicit
+  PibNameList(const Block& wire);
+
+  const std::vector<Name>&
+  getNameList() const
+  {
+    return m_names;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  std::vector<Name> m_names;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::Error TLV.
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibError : noncopyable
+{
+public:
+  PibError();
+
+  explicit
+  PibError(const pib::ErrCode errCode, const std::string& msg = "");
+
+  explicit
+  PibError(const Block& wire);
+
+  pib::ErrCode
+  getErrorCode() const
+  {
+    return m_errCode;
+  }
+
+  const std::string&
+  getErrorMsg() const
+  {
+    return m_msg;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  pib::ErrCode m_errCode;
+  std::string m_msg;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::User TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibUser
+{
+public:
+  PibUser();
+
+  explicit
+  PibUser(const Block& wire);
+
+  void
+  setMgmtCert(const IdentityCertificate& mgmtCert);
+
+  const IdentityCertificate&
+  getMgmtCert() const
+  {
+    return m_mgmtCert;
+  }
+
+  void
+  setTpmLocator(const std::string& tpmLocator);
+
+  const std::string&
+  getTpmLocator() const
+  {
+    return m_tpmLocator;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  IdentityCertificate m_mgmtCert;
+  std::string m_tpmLocator;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_PIB_ENCODING_HPP
diff --git a/tools/pib/encoding/update-param.cpp b/tools/pib/encoding/update-param.cpp
new file mode 100644
index 0000000..71a6602
--- /dev/null
+++ b/tools/pib/encoding/update-param.cpp
@@ -0,0 +1,235 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "update-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, UpdateParam::Error>::value,
+              "UpdateParam::Error must inherit from tlv::Error");
+
+const std::string UpdateParam::VERB("update");
+
+UpdateParam::UpdateParam()
+  : m_defaultOpt(DEFAULT_OPT_NO)
+{
+}
+
+UpdateParam::UpdateParam(const PibUser& user)
+  : m_entityType(tlv::pib::User)
+  , m_user(user)
+  , m_defaultOpt(DEFAULT_OPT_NO)
+{
+}
+
+UpdateParam::UpdateParam(const Name& identity, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::Identity)
+  , m_identity(identity)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::PublicKey)
+  , m_key(keyName, key)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::Certificate)
+  , m_certificate(certificate)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const PibUser&
+UpdateParam::getUser() const
+{
+  if (m_entityType == tlv::pib::User)
+      return m_user;
+  else
+    throw Error("UpdateParam::getUser: entityType must be User");
+}
+
+const PibIdentity&
+UpdateParam::getIdentity() const
+{
+  if (m_entityType == tlv::pib::Identity)
+    return m_identity;
+  else
+    throw Error("UpdateParam::getIdentity: entityType must be Identity");
+}
+
+const PibPublicKey&
+UpdateParam::getPublicKey() const
+{
+  if (m_entityType == tlv::pib::PublicKey)
+    return m_key;
+  else
+    throw Error("UpdateParam::getPublicKey: entityType must be PublicKey");
+}
+
+const PibCertificate&
+UpdateParam::getCertificate() const
+{
+  if (m_entityType == tlv::pib::Certificate)
+    return m_certificate;
+  else
+    throw Error("UpdateParam::getCertificate: entityType must be Certificate");
+}
+
+template<bool T>
+size_t
+UpdateParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::DefaultOpt, m_defaultOpt);
+
+  // Encode Entity
+  switch (m_entityType) {
+  case tlv::pib::Identity:
+    {
+      totalLength += m_identity.wireEncode(block);
+      break;
+    }
+  case tlv::pib::PublicKey:
+    {
+      totalLength += m_key.wireEncode(block);
+      break;
+    }
+  case tlv::pib::Certificate:
+    {
+      totalLength += m_certificate.wireEncode(block);
+      break;
+    }
+  case tlv::pib::User:
+    {
+      totalLength += m_user.wireEncode(block);
+      break;
+    }
+  default:
+    throw Error("UpdateParam::wireEncode: unsupported entity type: " +
+                boost::lexical_cast<std::string>(m_entityType));
+  }
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::UpdateParam);
+
+  return totalLength;
+}
+
+template size_t
+UpdateParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+UpdateParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+UpdateParam::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+UpdateParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::UpdateParam)
+    throw Error("Unexpected TLV type when decoding UpdateParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Entity
+  if (it != m_wire.elements_end()) {
+    switch (it->type()) {
+    case tlv::pib::Identity:
+      {
+        m_entityType = tlv::pib::Identity;
+        m_identity.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::PublicKey:
+      {
+        m_entityType = tlv::pib::PublicKey;
+        m_key.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::Certificate:
+      {
+        m_entityType = tlv::pib::Certificate;
+        m_certificate.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::User:
+      {
+        m_entityType = tlv::pib::User;
+        m_user.wireDecode(*it);
+        break;
+      }
+    default:
+      throw Error("The first sub-TLV of UpdateParam is not an entity type");
+    }
+
+    it++;
+  }
+  else
+    throw Error("UpdateParam requires the first sub-TLV to be an entity type");
+
+  // the second block must be DefaultOpt
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::DefaultOpt) {
+    m_defaultOpt = static_cast<pib::DefaultOpt>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("UpdateParam requires the second sub-TLV to be DefaultOpt");
+
+  if (it != m_wire.elements_end())
+    throw Error("UpdateParam must not contain more than two sub-TLVs");
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/update-param.hpp b/tools/pib/encoding/update-param.hpp
new file mode 100644
index 0000000..6a6e5ba
--- /dev/null
+++ b/tools/pib/encoding/update-param.hpp
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_UPDATE_PARAM_HPP
+#define NDN_PIB_UPDATE_PARAM_HPP
+
+#include "pib-common.hpp"
+#include "pib-encoding.hpp"
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/security/identity-certificate.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief UpdateParam is the abstraction of PIB Update parameter.
+ *
+ * PibUpdateParam := PIB-UPDATE-PARAM-TYPE TLV-LENGTH
+ *                   (PibIdentity | PibPublicKey | PibCertificate)
+ *                   PibDefaultOpt
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Update-Parameters
+ */
+
+class UpdateParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  UpdateParam();
+
+  explicit
+  UpdateParam(const PibUser& user);
+
+  explicit
+  UpdateParam(const Name& identity, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  explicit
+  UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  explicit
+  UpdateParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::UpdateParam;
+  }
+
+  tlv::pib::EntityType
+  getEntityType() const
+  {
+    return m_entityType;
+  }
+
+  const PibUser&
+  getUser() const;
+
+  const PibIdentity&
+  getIdentity() const;
+
+  const PibPublicKey&
+  getPublicKey() const;
+
+  const PibCertificate&
+  getCertificate() const;
+
+  pib::DefaultOpt
+  getDefaultOpt() const
+  {
+    return m_defaultOpt;
+  }
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /// @brief Encode to a wire format
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  tlv::pib::EntityType m_entityType;
+  PibUser m_user;
+  PibIdentity m_identity;
+  PibPublicKey m_key;
+  PibCertificate m_certificate;
+  pib::DefaultOpt m_defaultOpt;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_UPDATE_PARAM_HPP
diff --git a/tools/pib/get-query-processor.cpp b/tools/pib/get-query-processor.cpp
new file mode 100644
index 0000000..bc22747
--- /dev/null
+++ b/tools/pib/get-query-processor.cpp
@@ -0,0 +1,132 @@
+/* -*- 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 "get-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+const Name GetQueryProcessor::PIB_PREFIX("/localhost/pib");
+const size_t GetQueryProcessor::GET_QUERY_LENGTH = 5;
+
+GetQueryProcessor::GetQueryProcessor(PibDb& db)
+  : m_db(db)
+{
+}
+
+std::pair<bool, Block>
+GetQueryProcessor::operator()(const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+
+  // handle pib query: /localhost/pib/[UserName]/get/param
+  if (interestName.size() != GET_QUERY_LENGTH) {
+    // malformed interest, discard
+    return std::make_pair(false, Block());
+  }
+
+  GetParam param;
+
+  try {
+    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
+  }
+  catch (const tlv::Error& e) {
+    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + std::string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  switch (param.getTargetType()) {
+  case TYPE_ID:
+    return processGetIdQuery(param);
+  case TYPE_KEY:
+    return processGetKeyQuery(param);
+  case TYPE_CERT:
+    return processGetCertQuery(param);
+  case TYPE_USER:
+    if (interest.getName().get(2).toUri() != m_db.getOwnerName())
+      return std::make_pair(false, Block());
+    else
+      return processGetUserQuery(param);
+  default:
+    {
+      PibError error(ERR_WRONG_PARAM, "requested type is not supported:" +
+                     boost::lexical_cast<std::string>(param.getTargetType()));
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+}
+
+std::pair<bool, Block>
+GetQueryProcessor::processGetIdQuery(const GetParam& param)
+{
+  if (!m_db.hasIdentity(param.getTargetName())) {
+    PibError error(ERR_NON_EXISTING_ID, "requested id does not exist");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  PibIdentity result(param.getTargetName());
+  return std::make_pair(true, result.wireEncode());
+}
+
+std::pair<bool, Block>
+GetQueryProcessor::processGetKeyQuery(const GetParam& param)
+{
+  if (param.getTargetName().empty()) {
+    PibError error(ERR_WRONG_PARAM, "key name does not have id-component");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  shared_ptr<PublicKey> key = m_db.getKey(param.getTargetName());
+  if (key == nullptr) {
+    PibError error(ERR_NON_EXISTING_KEY, "requested key does not exist");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  PibPublicKey result(param.getTargetName(), *key);
+  return std::make_pair(true, result.wireEncode());
+}
+
+std::pair<bool, Block>
+GetQueryProcessor::processGetCertQuery(const GetParam& param)
+{
+  shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(param.getTargetName());
+  if (certificate == nullptr) {
+    PibError error(ERR_NON_EXISTING_CERT, "requested certificate does not exist");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  PibCertificate result(*certificate);
+  return std::make_pair(true, result.wireEncode());
+}
+
+std::pair<bool, Block>
+GetQueryProcessor::processGetUserQuery(const GetParam& param)
+{
+  PibUser result;
+  result.setMgmtCert(*m_db.getMgmtCertificate());
+  result.setTpmLocator(m_db.getTpmLocator());
+  return std::make_pair(true, result.wireEncode());
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/get-query-processor.hpp b/tools/pib/get-query-processor.hpp
new file mode 100644
index 0000000..f4eca40
--- /dev/null
+++ b/tools/pib/get-query-processor.hpp
@@ -0,0 +1,82 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_GET_QUERY_PROCESSOR_HPP
+#define NDN_PIB_GET_QUERY_PROCESSOR_HPP
+
+#include "pib-db.hpp"
+#include "encoding/get-param.hpp"
+#include <ndn-cxx/interest.hpp>
+#include <utility>
+
+namespace ndn {
+namespace pib {
+
+/// @brief implements the PIB service
+class GetQueryProcessor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param db The pib database.
+   * @param owner Owner of the pib database.
+   */
+  explicit
+  GetQueryProcessor(PibDb& db);
+
+  std::pair<bool, Block>
+  operator()(const Interest& interest);
+
+private:
+  std::pair<bool, Block>
+  processGetUserQuery(const GetParam& param);
+
+  std::pair<bool, Block>
+  processGetIdQuery(const GetParam& param);
+
+  std::pair<bool, Block>
+  processGetKeyQuery(const GetParam& param);
+
+  std::pair<bool, Block>
+  processGetCertQuery(const GetParam& param);
+
+private:
+  static const Name PIB_PREFIX;
+  static const size_t GET_QUERY_LENGTH;
+
+  const PibDb&  m_db;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_GET_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/key-cache.cpp b/tools/pib/key-cache.cpp
new file mode 100644
index 0000000..431e635
--- /dev/null
+++ b/tools/pib/key-cache.cpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "key-cache.hpp"
+
+namespace ndn {
+namespace pib {
+
+KeyCacheEntry::KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key)
+  : name(name)
+  , key(key)
+{
+  BOOST_ASSERT(static_cast<bool>(key));
+}
+
+KeyCache::KeyCache(size_t capacity)
+  : m_capacity(capacity)
+{
+}
+
+void
+KeyCache::insert(const Name& name, shared_ptr<PublicKey> key)
+{
+  // check if key exist
+  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
+  if (it != m_keys.get<byName>().end()) {
+    adjustLru(it);
+    return;
+  }
+
+  // evict key when capacity is reached
+  if (size() >= m_capacity)
+    evictKey();
+
+  // insert entry
+  m_keys.insert(KeyCacheEntry(name, key));
+}
+
+shared_ptr<PublicKey>
+KeyCache::find(const Name& name) const
+{
+  // check if key exist
+  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
+  if (it == m_keys.get<byName>().end())
+    return shared_ptr<PublicKey>();
+  else {
+    // adjust lru
+    shared_ptr<PublicKey> key = it->key;
+    adjustLru(it);
+    return key;
+  }
+}
+
+void
+KeyCache::erase(const Name& name)
+{
+  // check if key exist
+  KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
+  if (it != m_keys.get<byName>().end()) {
+    m_keys.erase(it);
+  }
+}
+
+size_t
+KeyCache::size() const
+{
+  return m_keys.size();
+}
+
+void
+KeyCache::evictKey()
+{
+  if (!m_keys.get<byUsedTime>().empty()) {
+    KeyContainer::index<byUsedTime>::type::iterator it = m_keys.get<byUsedTime>().begin();
+    m_keys.erase(m_keys.project<0>(it));
+  }
+}
+
+void
+KeyCache::adjustLru(KeyContainer::iterator it) const
+{
+  KeyCacheEntry entry = std::move(*it);
+  m_keys.erase(it);
+  m_keys.insert(entry);
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/key-cache.hpp b/tools/pib/key-cache.hpp
new file mode 100644
index 0000000..5df077a
--- /dev/null
+++ b/tools/pib/key-cache.hpp
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_KEY_CACHE_HPP
+#define NDN_PIB_KEY_CACHE_HPP
+
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/util/time.hpp>
+#include <ndn-cxx/security/public-key.hpp>
+
+#include <stack>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+
+namespace ndn {
+namespace pib {
+
+struct KeyCacheEntry
+{
+  KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key);
+
+  Name name;
+  shared_ptr<PublicKey> key;
+};
+
+class byName;
+class byUsedTime;
+
+typedef boost::multi_index::multi_index_container<
+  KeyCacheEntry,
+  boost::multi_index::indexed_by<
+    boost::multi_index::hashed_unique<
+      boost::multi_index::tag<byName>,
+      boost::multi_index::member<KeyCacheEntry, Name, &KeyCacheEntry::name>,
+      std::hash<Name>
+    >,
+
+    boost::multi_index::sequenced<
+      boost::multi_index::tag<byUsedTime>
+    >
+  >
+> KeyContainer;
+
+class KeyCache : noncopyable
+{
+public:
+  explicit
+  KeyCache(size_t capacity = getDefaultCapacity());
+
+  void
+  insert(const Name& name, shared_ptr<PublicKey> key);
+
+  shared_ptr<PublicKey>
+  find(const Name& name) const;
+
+  void
+  erase(const Name& name);
+
+  size_t
+  size() const;
+
+private:
+  static size_t
+  getDefaultCapacity()
+  {
+    return 100;
+  }
+
+  void
+  evictKey();
+
+  void
+  adjustLru(KeyContainer::iterator it) const;
+
+  void
+  freeEntry(KeyContainer::iterator it);
+
+private:
+  size_t m_capacity;
+  mutable KeyContainer m_keys;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_KEY_CACHE_HPP
diff --git a/tools/pib/list-query-processor.cpp b/tools/pib/list-query-processor.cpp
new file mode 100644
index 0000000..ad4e2d5
--- /dev/null
+++ b/tools/pib/list-query-processor.cpp
@@ -0,0 +1,98 @@
+/* -*- 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 "list-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+using std::vector;
+
+const size_t ListQueryProcessor::LIST_QUERY_LENGTH = 5;
+
+ListQueryProcessor::ListQueryProcessor(PibDb& db)
+  : m_db(db)
+{
+}
+
+std::pair<bool, Block>
+ListQueryProcessor::operator()(const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+
+  // handle pib query: /localhost/pib/[UserName]/list/param
+  if (interestName.size() != MIN_PIB_INTEREST_SIZE) {
+    // malformed interest, discard
+    return std::make_pair(false, Block());
+  }
+
+  ListParam param;
+
+  try {
+    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
+  }
+  catch (const tlv::Error& e) {
+    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  vector<Name> nameList;
+  switch (param.getOriginType()) {
+  case TYPE_USER:
+    {
+      nameList = m_db.listIdentities();
+      break;
+    }
+  case TYPE_ID:
+    {
+      nameList = m_db.listKeyNamesOfIdentity(param.getOriginName());
+      break;
+    }
+  case TYPE_KEY:
+    {
+      const Name& keyName = param.getOriginName();
+      if (keyName.empty()) {
+        PibError error(ERR_WRONG_PARAM,
+                       "key name must contain key id component");
+        return std::make_pair(true, error.wireEncode());
+      }
+
+      nameList = m_db.listCertNamesOfKey(keyName);
+      break;
+    }
+  default:
+    {
+      PibError error(ERR_WRONG_PARAM,
+                     "origin type is not supported: " +
+                     boost::lexical_cast<string>(param.getOriginType()));
+      return std::make_pair(true, error.wireEncode());
+    }
+  }
+
+  PibNameList result(nameList);
+  return std::make_pair(true, result.wireEncode());
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/list-query-processor.hpp b/tools/pib/list-query-processor.hpp
new file mode 100644
index 0000000..4b814f7
--- /dev/null
+++ b/tools/pib/list-query-processor.hpp
@@ -0,0 +1,66 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_LIST_QUERY_PROCESSOR_HPP
+#define NDN_PIB_LIST_QUERY_PROCESSOR_HPP
+
+#include "pib-db.hpp"
+#include "encoding/list-param.hpp"
+#include <ndn-cxx/interest.hpp>
+#include <utility>
+
+namespace ndn {
+namespace pib {
+
+class ListQueryProcessor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param db The pib database.
+   */
+  explicit
+  ListQueryProcessor(PibDb& db);
+
+  std::pair<bool, Block>
+  operator()(const Interest& interest);
+
+private:
+  static const size_t LIST_QUERY_LENGTH;
+
+  const PibDb&  m_db;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_LIST_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/ndn-pib.cpp b/tools/pib/ndn-pib.cpp
new file mode 100644
index 0000000..4166bd8
--- /dev/null
+++ b/tools/pib/ndn-pib.cpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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.hpp"
+
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/config-file.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace pib {
+
+int
+main(int argc, char** argv)
+{
+  namespace po = boost::program_options;
+  namespace fs = boost::filesystem;
+
+  std::string owner;
+  std::string dbDir;
+  std::string tpmLocator;
+  Face face;
+
+  std::cerr << "hello" << std::endl;
+
+  po::options_description description(
+    "General Usage\n"
+    "  ndn-pib [-h] -o owner -d database_dir -t tpm_locator\n"
+    "General options");
+
+  description.add_options()
+    ("help,h",     "produce help message")
+    ("owner,o",    po::value<std::string>(&owner),
+                   "Name of the owner, PIB will listen to /localhost/pib/[owner].")
+    ("database,d", po::value<std::string>(&dbDir),
+                   "Absolute path to the directory of PIB database, /<database_dir>/pib.db")
+    ("tpm,t",      po::value<std::string>(&tpmLocator),
+                   "URI of the tpm. e.g., tpm-file:/var")
+    ;
+
+  po::variables_map vm;
+  try {
+    po::store(po::parse_command_line(argc, argv, description), vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cerr << description << std::endl;
+    return 0;
+  }
+
+  try {
+    if (vm.count("owner") == 0 && vm.count("database") == 0 && vm.count("tpm") == 0) {
+      if (std::getenv("HOME")) {
+        fs::path pibDir(std::getenv("HOME"));
+        pibDir /= ".ndn/pib";
+        dbDir = pibDir.string();
+      }
+      else {
+        std::cerr << "ERROR: HOME variable is not set" << std::endl;
+        return 1;
+      }
+
+      tpmLocator = KeyChain::getDefaultTpmLocator();
+
+      if (std::getenv("USER")) {
+        owner = std::string(std::getenv("USER"));
+      }
+      else {
+        std::cerr << "ERROR: HOME variable is not set" << std::endl;
+        return 1;
+      }
+    }
+    else if (vm.count("owner") == 0 || vm.count("database") == 0 ||
+             vm.count("tpm") == 0) {
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+    Pib pib(face, dbDir, tpmLocator, owner);
+    face.processEvents();
+  }
+  catch (std::runtime_error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+
+  return 0;
+}
+
+} // namespace pib
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+  ndn::pib::main(argc, argv);
+}
diff --git a/tools/pib/pib-db.cpp b/tools/pib/pib-db.cpp
new file mode 100644
index 0000000..0e2ce87
--- /dev/null
+++ b/tools/pib/pib-db.cpp
@@ -0,0 +1,825 @@
+/* -*- 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-db.hpp"
+#include <sqlite3.h>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+using std::vector;
+using std::set;
+
+const Name PibDb::NON_EXISTING_IDENTITY("/localhost/reserved/non-existing-identity");
+const Name PibDb::NON_EXISTING_KEY("/localhost/reserved/non-existing-key");
+const Name PibDb::NON_EXISTING_CERTIFICATE("/localhost/reserved/non-existing-certificate");
+
+const Name PibDb::LOCALHOST_PIB("/localhost/pib");
+const name::Component PibDb::MGMT_LABEL("mgmt");
+
+
+static const string INITIALIZATION =
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  mgmt(                                       \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    owner                 BLOB NOT NULL,      \n"
+  "    tpm_locator           BLOB,               \n"
+  "    local_management_cert BLOB NOT NULL       \n"
+  "  );                                          \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  mgmt_insert_trigger                         \n"
+  "  BEFORE INSERT ON mgmt                       \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    DELETE FROM mgmt;                         \n"
+  "  END;                                        \n"
+  "                                              \n"
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  identities(                                 \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    identity              BLOB NOT NULL,      \n"
+  "    is_default            INTEGER DEFAULT 0   \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  identityIndex ON identities(identity);      \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  identity_default_before_insert_trigger      \n"
+  "  BEFORE INSERT ON identities                 \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1                       \n"
+  "  BEGIN                                       \n"
+  "    UPDATE identities SET is_default=0;       \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  identity_default_after_insert_trigger       \n"
+  "  AFTER INSERT ON identities                  \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NOT EXISTS                             \n"
+  "    (SELECT id                                \n"
+  "       FROM identities                        \n"
+  "       WHERE is_default=1)                    \n"
+  "  BEGIN                                       \n"
+  "    UPDATE identities                         \n"
+  "      SET is_default=1                        \n"
+  "      WHERE identity=NEW.identity;            \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  identity_default_update_trigger             \n"
+  "  BEFORE UPDATE ON identities                 \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
+  "  BEGIN                                       \n"
+  "    UPDATE identities SET is_default=0;       \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  identity_delete_trigger                     \n"
+  "  AFTER DELETE ON identities                  \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    SELECT identityDeleted (OLD.identity);    \n"
+  "  END;                                        \n"
+  "                                              \n"
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  keys(                                       \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    identity_id           INTEGER NOT NULL,   \n"
+  "    key_name              BLOB NOT NULL,      \n"
+  "    key_type              INTEGER NOT NULL,   \n"
+  "    key_bits              BLOB NOT NULL,      \n"
+  "    is_default            INTEGER DEFAULT 0,  \n"
+  "    FOREIGN KEY(identity_id)                  \n"
+  "      REFERENCES identities(id)               \n"
+  "      ON DELETE CASCADE                       \n"
+  "      ON UPDATE CASCADE                       \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  keyIndex ON keys(key_name);                 \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  key_default_before_insert_trigger           \n"
+  "  BEFORE INSERT ON keys                       \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1                       \n"
+  "  BEGIN                                       \n"
+  "    UPDATE keys                               \n"
+  "      SET is_default=0                        \n"
+  "      WHERE identity_id=NEW.identity_id;      \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  key_default_after_insert_trigger            \n"
+  "  AFTER INSERT ON keys                        \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NOT EXISTS                             \n"
+  "    (SELECT id                                \n"
+  "       FROM keys                              \n"
+  "       WHERE is_default=1                     \n"
+  "         AND identity_id=NEW.identity_id)     \n"
+  "  BEGIN                                       \n"
+  "    UPDATE keys                               \n"
+  "      SET is_default=1                        \n"
+  "      WHERE key_name=NEW.key_name;            \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  key_default_update_trigger                  \n"
+  "  BEFORE UPDATE ON keys                       \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
+  "  BEGIN                                       \n"
+  "    UPDATE keys                               \n"
+  "      SET is_default=0                        \n"
+  "      WHERE identity_id=NEW.identity_id;      \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  key_delete_trigger                          \n"
+  "  AFTER DELETE ON keys                        \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    SELECT keyDeleted (OLD.key_name);         \n"
+  "  END;                                        \n"
+  "                                              \n"
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  certificates(                               \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    key_id                INTEGER NOT NULL,   \n"
+  "    certificate_name      BLOB NOT NULL,      \n"
+  "    certificate_data      BLOB NOT NULL,      \n"
+  "    is_default            INTEGER DEFAULT 0,  \n"
+  "    FOREIGN KEY(key_id)                       \n"
+  "      REFERENCES keys(id)                     \n"
+  "      ON DELETE CASCADE                       \n"
+  "      ON UPDATE CASCADE                       \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  certIndex ON certificates(certificate_name);\n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cert_default_before_insert_trigger          \n"
+  "  BEFORE INSERT ON certificates               \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1                       \n"
+  "  BEGIN                                       \n"
+  "    UPDATE certificates                       \n"
+  "      SET is_default=0                        \n"
+  "      WHERE key_id=NEW.key_id;                \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cert_default_after_insert_trigger           \n"
+  "  AFTER INSERT ON certificates                \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NOT EXISTS                             \n"
+  "    (SELECT id                                \n"
+  "       FROM certificates                      \n"
+  "       WHERE is_default=1                     \n"
+  "         AND key_id=NEW.key_id)               \n"
+  "  BEGIN                                       \n"
+  "    UPDATE certificates                       \n"
+  "      SET is_default=1                        \n"
+  "      WHERE certificate_name=NEW.certificate_name;\n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cert_default_update_trigger                 \n"
+  "  BEFORE UPDATE ON certificates               \n"
+  "  FOR EACH ROW                                \n"
+  "  WHEN NEW.is_default=1 AND OLD.is_default=0  \n"
+  "  BEGIN                                       \n"
+  "    UPDATE certificates                       \n"
+  "      SET is_default=0                        \n"
+  "      WHERE key_id=NEW.key_id;                \n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cert_delete_trigger                         \n"
+  "  AFTER DELETE ON certificates                \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    SELECT certDeleted (OLD.certificate_name);\n"
+  "  END;                                        \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cert_insert_trigger                         \n"
+  "  AFTER INSERT ON certificates                \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    SELECT certInserted (NEW.certificate_name);\n"
+  "  END;                                        \n";
+
+
+/**
+ * A utility function to call the normal sqlite3_bind_text where the value and length are
+ * value.c_str() and value.size().
+ */
+static int
+sqlite3_bind_string(sqlite3_stmt* statement,
+                    int index,
+                    const string& value,
+                    void(*destructor)(void*))
+{
+  return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
+}
+
+/**
+ * A utility function to call the normal sqlite3_bind_blob where the value and length are
+ * block.wire() and block.size().
+ */
+static int
+sqlite3_bind_block(sqlite3_stmt* statement,
+                   int index,
+                   const Block& block,
+                   void(*destructor)(void*))
+{
+  return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
+}
+
+/**
+ * A utility function to generate string by calling the normal sqlite3_column_text.
+ */
+static string
+sqlite3_column_string(sqlite3_stmt* statement, int column)
+{
+  return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
+                sqlite3_column_bytes(statement, column));
+}
+
+/**
+ * A utility function to generate block by calling the normal sqlite3_column_text.
+ */
+static Block
+sqlite3_column_block(sqlite3_stmt* statement, int column)
+{
+  return Block(sqlite3_column_blob(statement, column), sqlite3_column_bytes(statement, column));
+}
+
+PibDb::PibDb(const string& dbDir)
+{
+  // Determine the path of PIB DB
+  boost::filesystem::path dir;
+  if (dbDir == "") {
+    dir = boost::filesystem::path(getenv("HOME")) / ".ndn";
+    boost::filesystem::create_directories(dir);
+  }
+  else {
+    dir = boost::filesystem::path(dbDir);
+    boost::filesystem::create_directories(dir);
+  }
+  // Open PIB
+  int result = sqlite3_open_v2((dir / "pib.db").c_str(), &m_database,
+                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
+                               "unix-dotfile"
+#else
+                               nullptr
+#endif
+                               );
+
+  if (result != SQLITE_OK)
+    throw Error("PIB DB cannot be opened/created: " + dbDir);
+
+
+  // enable foreign key
+  sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
+
+  // initialize PIB specific tables
+  char* errorMessage = nullptr;
+  result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
+  if (result != SQLITE_OK && errorMessage != nullptr) {
+    sqlite3_free(errorMessage);
+    throw Error("PIB DB cannot be initialized");
+  }
+
+  // create delete trigger functions
+  createDbDeleteTrigger();
+
+  getOwnerName();
+}
+
+void
+PibDb::createDbDeleteTrigger()
+{
+  int res = 0;
+
+  res = sqlite3_create_function(m_database, "identityDeleted", -1, SQLITE_UTF8,
+                                reinterpret_cast<void*>(this),
+                                PibDb::identityDeletedFun, nullptr, nullptr);
+  if (res != SQLITE_OK)
+    throw Error("Cannot create function ``identityDeleted''");
+
+  res = sqlite3_create_function(m_database, "keyDeleted", -1, SQLITE_UTF8,
+                                reinterpret_cast<void*>(this),
+                                PibDb::keyDeletedFun, nullptr, nullptr);
+  if (res != SQLITE_OK)
+    throw Error("Cannot create function ``keyDeleted''");
+
+  res = sqlite3_create_function(m_database, "certDeleted", -1, SQLITE_UTF8,
+                                reinterpret_cast<void*>(this),
+                                PibDb::certDeletedFun, nullptr, nullptr);
+  if (res != SQLITE_OK)
+    throw Error("Cannot create function ``certDeleted''");
+
+  res = sqlite3_create_function(m_database, "certInserted", -1, SQLITE_UTF8,
+                                reinterpret_cast<void*>(this),
+                                PibDb::certInsertedFun, nullptr, nullptr);
+  if (res != SQLITE_OK)
+    throw Error("Cannot create function ``certInserted''");
+}
+
+void
+PibDb::identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+  BOOST_ASSERT(argc == 1);
+
+  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
+  Name identity(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
+
+  pibDb->identityDeleted(identity);
+}
+
+void
+PibDb::keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+  BOOST_ASSERT(argc == 1);
+
+  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
+  Name keyName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
+
+  pibDb->keyDeleted(keyName);
+}
+
+void
+PibDb::certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+  BOOST_ASSERT(argc == 1);
+
+  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
+  Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
+
+  pibDb->certificateDeleted(certName);
+}
+
+void
+PibDb::certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
+{
+  BOOST_ASSERT(argc == 1);
+
+  PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
+  Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
+
+  pibDb->certificateInserted(certName);
+}
+
+void
+PibDb::updateMgmtCertificate(const IdentityCertificate& certificate)
+{
+  const Name& keyName = certificate.getPublicKeyName();
+
+  // Name of mgmt key should be "/localhost/pib/[UserName]/mgmt/[KeyID]"
+  if (keyName.size() != 5 ||
+      keyName.compare(0, 2, LOCALHOST_PIB) ||
+      keyName.get(3) != MGMT_LABEL)
+    throw Error("PibDb::updateMgmtCertificate: certificate does not follow the naming convention");
+
+  string owner = keyName.get(2).toUri();
+  sqlite3_stmt* statement;
+  if (!m_owner.empty()) {
+    if (m_owner != owner)
+      throw Error("PibDb::updateMgmtCertificate: owner name does not match");
+    else {
+      sqlite3_prepare_v2(m_database,
+                         "UPDATE mgmt SET local_management_cert=? WHERE owner=?",
+                         -1, &statement, nullptr);
+    }
+  }
+  else {
+    sqlite3_prepare_v2(m_database,
+                       "INSERT INTO mgmt (local_management_cert, owner) VALUES (?, ?)",
+                       -1, &statement, nullptr);
+  }
+
+  sqlite3_bind_block(statement, 1, certificate.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_string(statement, 2, owner, SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  m_owner = owner;
+
+  mgmtCertificateChanged();
+}
+
+string
+PibDb::getOwnerName() const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database, "SELECT owner FROM mgmt", -1, &statement, nullptr);
+
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    m_owner = sqlite3_column_string(statement, 0);
+  }
+
+  sqlite3_finalize(statement);
+  return m_owner;
+}
+
+shared_ptr<IdentityCertificate>
+PibDb::getMgmtCertificate() const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database, "SELECT local_management_cert FROM mgmt", -1, &statement, nullptr);
+
+  shared_ptr<IdentityCertificate> certificate;
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    certificate = make_shared<IdentityCertificate>();
+    certificate->wireDecode(sqlite3_column_block(statement, 0));
+  }
+
+  sqlite3_finalize(statement);
+  return certificate;
+}
+
+void
+PibDb::setTpmLocator(const std::string& tpmLocator)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "UPDATE mgmt SET tpm_locator=? WHERE owner=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
+  sqlite3_bind_string(statement, 2, m_owner, SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+std::string
+PibDb::getTpmLocator() const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM mgmt", -1, &statement, nullptr);
+
+  string tpmLocator;
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    tpmLocator = sqlite3_column_string(statement, 0);
+  }
+
+  sqlite3_finalize(statement);
+  return tpmLocator;
+}
+
+int64_t
+PibDb::addIdentity(const Name& identity)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "INSERT INTO identities (identity) values (?)",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  return sqlite3_last_insert_rowid(m_database);
+}
+
+void
+PibDb::deleteIdentity(const Name& identity)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "DELETE FROM identities WHERE identity=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+bool
+PibDb::hasIdentity(const Name& identity) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT id FROM identities WHERE identity=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_ROW)
+    return true;
+  else
+    return false;
+}
+
+void
+PibDb::setDefaultIdentity(const Name& identity)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "UPDATE identities SET is_default=1 WHERE identity=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+Name
+PibDb::getDefaultIdentity() const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT identity FROM identities WHERE is_default=1",
+                     -1, &statement, nullptr);
+
+  Name identity = NON_EXISTING_IDENTITY;
+  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
+    identity = Name(sqlite3_column_block(statement, 0));
+  }
+  sqlite3_finalize(statement);
+  return identity;
+}
+
+vector<Name>
+PibDb::listIdentities() const
+{
+  vector<Name> identities;
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database, "SELECT identity FROM identities", -1, &statement, nullptr);
+
+  identities.clear();
+  while (sqlite3_step(statement) == SQLITE_ROW) {
+    Name name(sqlite3_column_block(statement, 0));
+    identities.push_back(name);
+  }
+  sqlite3_finalize(statement);
+
+  return identities;
+}
+
+int64_t
+PibDb::addKey(const Name& keyName, const PublicKey& key)
+{
+  if (keyName.empty())
+    return 0;
+
+  Name&& identity = keyName.getPrefix(-1);
+  if (!hasIdentity(identity))
+    addIdentity(identity);
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "INSERT INTO keys (identity_id, key_name, key_type, key_bits) \
+                      values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_int(statement, 3, key.getKeyType());
+  sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  return sqlite3_last_insert_rowid(m_database);
+}
+
+shared_ptr<PublicKey>
+PibDb::getKey(const Name& keyName) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT key_bits FROM keys WHERE key_name=?"
+                     , -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+  shared_ptr<PublicKey> key;
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+      key = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
+                                   sqlite3_column_bytes(statement, 0));
+  }
+  sqlite3_finalize(statement);
+  return key;
+}
+
+void
+PibDb::deleteKey(const Name& keyName)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "DELETE FROM keys WHERE key_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+bool
+PibDb::hasKey(const Name& keyName) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT id FROM keys WHERE key_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_ROW)
+    return true;
+  else
+    return false;
+}
+
+void
+PibDb::setDefaultKeyNameOfIdentity(const Name& keyName)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "UPDATE keys SET is_default=1 WHERE key_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+Name
+PibDb::getDefaultKeyNameOfIdentity(const Name& identity) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
+                      WHERE identities.identity=? AND keys.is_default=1",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+
+  Name keyName = NON_EXISTING_KEY;
+  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
+    keyName = Name(sqlite3_column_block(statement, 0));
+  }
+
+  sqlite3_finalize(statement);
+  return keyName;
+}
+
+vector<Name>
+PibDb::listKeyNamesOfIdentity(const Name& identity) const
+{
+  vector<Name> keyNames;
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
+                      WHERE identities.identity=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
+
+  keyNames.clear();
+  while (sqlite3_step(statement) == SQLITE_ROW) {
+    Name keyName(sqlite3_column_block(statement, 0));
+    keyNames.push_back(keyName);
+  }
+
+  sqlite3_finalize(statement);
+  return keyNames;
+}
+
+
+int64_t
+PibDb::addCertificate(const IdentityCertificate& certificate)
+{
+  const Name& certName = certificate.getName();
+  const Name& keyName = certificate.getPublicKeyName();
+
+  if (!hasKey(keyName))
+    addKey(keyName, certificate.getPublicKeyInfo());
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "INSERT INTO certificates \
+                      (key_id, certificate_name, certificate_data) \
+                      values ((SELECT id FROM keys WHERE key_name=?), ?, ?)",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_block(statement, 2, certName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_block(statement, 3, certificate.wireEncode(), SQLITE_STATIC);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  return sqlite3_last_insert_rowid(m_database);
+}
+
+shared_ptr<IdentityCertificate>
+PibDb::getCertificate(const Name& certificateName) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT certificate_data FROM certificates WHERE certificate_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
+
+  shared_ptr<IdentityCertificate> certificate;
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    certificate = make_shared<IdentityCertificate>();
+    certificate->wireDecode(sqlite3_column_block(statement, 0));
+  }
+
+  sqlite3_finalize(statement);
+  return certificate;
+}
+
+void
+PibDb::deleteCertificate(const Name& certificateName)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "DELETE FROM certificates WHERE certificate_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+bool
+PibDb::hasCertificate(const Name& certificateName) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT id FROM certificates WHERE certificate_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_ROW)
+    return true;
+  else
+    return false;
+}
+
+void
+PibDb::setDefaultCertNameOfKey(const Name& certificateName)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "UPDATE certificates SET is_default=1 WHERE certificate_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_step(statement);
+  sqlite3_finalize(statement);
+}
+
+Name
+PibDb::getDefaultCertNameOfKey(const Name& keyName) const
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT certificate_name\
+                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
+                      WHERE keys.key_name=? AND certificates.is_default=1",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+  Name certName = NON_EXISTING_CERTIFICATE;
+  if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
+    certName = Name(sqlite3_column_block(statement, 0));
+  }
+  sqlite3_finalize(statement);
+  return certName;
+}
+
+vector<Name>
+PibDb::listCertNamesOfKey(const Name& keyName) const
+{
+  vector<Name> certNames;
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_database,
+                     "SELECT certificate_name\
+                      FROM certificates JOIN keys ON certificates.key_id=keys.id\
+                      WHERE keys.key_name=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+  certNames.clear();
+  while (sqlite3_step(statement) == SQLITE_ROW) {
+    Name name(sqlite3_column_block(statement, 0));
+    certNames.push_back(name);
+  }
+  sqlite3_finalize(statement);
+
+  return certNames;
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/pib-db.hpp b/tools/pib/pib-db.hpp
new file mode 100644
index 0000000..5101e25
--- /dev/null
+++ b/tools/pib/pib-db.hpp
@@ -0,0 +1,265 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_PIB_DB_HPP
+#define NDN_PIB_PIB_DB_HPP
+
+#include "core/common.hpp"
+#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/util/signal.hpp>
+
+#include <set>
+#include <vector>
+
+struct sqlite3;
+struct sqlite3_context;
+struct Mem;
+typedef Mem sqlite3_value;
+
+namespace ndn {
+namespace pib {
+
+/// @brief Callback to report changes on user info.
+typedef function<void(const std::string&)> UserChangedEventHandler;
+
+/// @brief Callback to report that a key is deleted.
+typedef function<void(const std::string&, const Name&,
+                      const name::Component&)> KeyDeletedEventHandler;
+
+/**
+ * @brief PibDb is a class to manage the database of PIB service.
+ *
+ * only public key related information is stored in this database.
+ * Detail information can be found at:
+ * http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
+ */
+class PibDb : noncopyable
+{
+public:
+  util::signal::Signal<PibDb> mgmtCertificateChanged;
+  util::signal::Signal<PibDb, Name> certificateDeleted;
+  util::signal::Signal<PibDb, Name> keyDeleted;
+  util::signal::Signal<PibDb, Name> identityDeleted;
+  util::signal::Signal<PibDb, Name> certificateInserted;
+
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  explicit
+  PibDb(const std::string& dbDir = "");
+
+public: // Owner management
+  /**
+   * @brief Update owner's management certificate
+   *
+   * Since owner name is encoded in the management certificate,
+   * this method can also set the owner name if it is not set.
+   * If the owner name is set but does not match the one in the
+   * supplied certificate, it throws @p Error.
+   *
+   * @throws Error if supplied certificate is wrong
+   */
+  void
+  updateMgmtCertificate(const IdentityCertificate& certificate);
+
+  /**
+   * @brief Get owner name
+   *
+   * return empty string when owner name is not set.
+   */
+  std::string
+  getOwnerName() const;
+
+  /** @brief Get the management cert
+   *
+   * return nullptr when the management cert is not set
+   */
+  shared_ptr<IdentityCertificate>
+  getMgmtCertificate() const;
+
+  /// @brief Set TPM locator
+  void
+  setTpmLocator(const std::string& tpmLocator);
+
+  /**
+   * @brief Get TPM locator
+   *
+   * return empty string when tpmLocator is not set.
+   */
+  std::string
+  getTpmLocator() const;
+
+public: // Identity management
+
+  /**
+   * @brief Add an identity
+   *
+   * @return row id of the added identity, 0 if insert fails.
+   */
+  int64_t
+  addIdentity(const Name& identity);
+
+  /// @brief Delete an identity
+  void
+  deleteIdentity(const Name& identity);
+
+  /// @brief Check if an identity exists
+  bool
+  hasIdentity(const Name& identity) const;
+
+  /// @brief Get all identities
+  std::vector<Name>
+  listIdentities() const;
+
+  /// @brief Set the default identity
+  void
+  setDefaultIdentity(const Name& identity);
+
+  /**
+   * @brief Get the default identity
+   *
+   * @return default identity or /localhost/reserved/non-existing-identity if no default identity
+   */
+  Name
+  getDefaultIdentity() const;
+
+public: // Key management
+
+  /// @brief Add key
+  int64_t
+  addKey(const Name& keyName, const PublicKey& key);
+
+  /// @brief Delete key
+  void
+  deleteKey(const Name& keyName);
+
+  /// @brief Check if a key exists
+  bool
+  hasKey(const Name& keyName) const;
+
+  /**
+   * @brief Get key
+   *
+   * @return shared pointer to the key, nullptr if the key does not exit
+   */
+  shared_ptr<PublicKey>
+  getKey(const Name& keyName) const;
+
+  /// @brief Get all the key names of an identity
+  std::vector<Name>
+  listKeyNamesOfIdentity(const Name& identity) const;
+
+  /// @brief Set an identity's default key name
+  void
+  setDefaultKeyNameOfIdentity(const Name& keyName);
+
+  /**
+   * @brief Get the default key name of an identity
+   *
+   * @return default key name or /localhost/reserved/non-existing-key if no default key
+   */
+  Name
+  getDefaultKeyNameOfIdentity(const Name& identity) const;
+
+public: // Certificate management
+
+  /// @brief Add a certificate
+  int64_t
+  addCertificate(const IdentityCertificate& certificate);
+
+  /// @brief Delete a certificate
+  void
+  deleteCertificate(const Name& certificateName);
+
+  /// @brief Check if the certificate exist
+  bool
+  hasCertificate(const Name& certificateName) const;
+
+  /**
+   * @brief Get a certificate
+   *
+   * @return shared pointer to the certificate, nullptr if the certificate does not exist
+   */
+  shared_ptr<IdentityCertificate>
+  getCertificate(const Name& certificateName) const;
+
+  /// @brief Get all the cert names of a key
+  std::vector<Name>
+  listCertNamesOfKey(const Name& keyName) const;
+
+  /// @brief Set a key's default certificate name
+  void
+  setDefaultCertNameOfKey(const Name& certificateName);
+
+  /**
+   * @brief Get a key's default certificate name
+   *
+   * @return default certificate name or /localhost/reserved/non-existing-certificate if no default
+   *         certificate.
+   */
+  Name
+  getDefaultCertNameOfKey(const Name& keyName) const;
+
+private:
+  void
+  createDbDeleteTrigger();
+
+private:
+  static void
+  identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
+
+  static void
+  keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
+
+  static void
+  certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
+
+  static void
+  certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
+
+public:
+  static const Name NON_EXISTING_IDENTITY;
+  static const Name NON_EXISTING_KEY;
+  static const Name NON_EXISTING_CERTIFICATE;
+
+private:
+  static const Name LOCALHOST_PIB;
+  static const name::Component MGMT_LABEL;
+
+private:
+  sqlite3* m_database;
+
+  mutable std::string m_owner;
+};
+
+} // namespace pib
+} // namespace ndn
+
+
+#endif // NDN_PIB_PIB_DB_HPP
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
diff --git a/tools/pib/pib-validator.hpp b/tools/pib/pib-validator.hpp
new file mode 100644
index 0000000..9d7a3e1
--- /dev/null
+++ b/tools/pib/pib-validator.hpp
@@ -0,0 +1,81 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_PIB_VALIDATOR_HPP
+#define NDN_PIB_PIB_VALIDATOR_HPP
+
+#include "pib-db.hpp"
+#include "key-cache.hpp"
+#include <ndn-cxx/security/validator.hpp>
+#include <unordered_map>
+
+namespace ndn {
+namespace pib {
+
+
+/*
+ * @brief The validator to verify the command interests to PIB service
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
+ */
+class PibValidator : public Validator
+{
+  struct UserKeyCache;
+public:
+  explicit
+  PibValidator(const PibDb& pibDb,
+               size_t maxCacheSize = 1000);
+
+  ~PibValidator();
+
+protected:
+  virtual void
+  checkPolicy(const Interest& interest,
+              int nSteps,
+              const OnInterestValidated& onValidated,
+              const OnInterestValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest>>& nextSteps);
+
+  virtual void
+  checkPolicy(const Data& data,
+              int nSteps,
+              const OnDataValidated& onValidated,
+              const OnDataValidationFailed& onValidationFailed,
+              std::vector<shared_ptr<ValidationRequest>>& nextSteps);
+
+private:
+
+  const PibDb& m_db;
+
+  bool m_isMgmtReady;
+  std::string m_owner;
+  shared_ptr<IdentityCertificate> m_mgmtCert;
+
+  KeyCache m_keyCache;
+
+  util::signal::ScopedConnection m_mgmtChangeConnection;
+  util::signal::ScopedConnection m_keyDeletedConnection;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_PIB_VALIDATOR_HPP
diff --git a/tools/pib/pib.cpp b/tools/pib/pib.cpp
new file mode 100644
index 0000000..d5a4e5c
--- /dev/null
+++ b/tools/pib/pib.cpp
@@ -0,0 +1,282 @@
+/* -*- 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.hpp"
+
+#include "encoding/pib-encoding.hpp"
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/crypto.hpp>
+#include <ndn-cxx/util/concepts.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+using std::vector;
+using std::set;
+
+const Name Pib::PIB_PREFIX("/localhost/pib");
+const Name Pib::EMPTY_SIGNER_NAME;
+const name::Component Pib::MGMT_LABEL("mgmt");
+
+// \todo make this a static method in KeyChain
+static inline void
+signWithDigestSha256(Data& data)
+{
+  DigestSha256 sig;
+  data.setSignature(sig);
+  Block sigValue(tlv::SignatureValue,
+                 crypto::sha256(data.wireEncode().value(),
+                                data.wireEncode().value_size() -
+                                data.getSignature().getValue().size()));
+  data.setSignatureValue(sigValue);
+  data.wireEncode();
+}
+
+Pib::Pib(Face& face,
+         const std::string& dbDir,
+         const std::string& tpmLocator,
+         const std::string& owner)
+  : m_db(dbDir)
+  , m_tpm(nullptr)
+  , m_owner(owner)
+  , m_validator(m_db)
+  , m_face(face)
+  , m_certPublisher(m_face, m_db)
+  , m_getProcessor(m_db)
+  , m_defaultProcessor(m_db)
+  , m_listProcessor(m_db)
+  , m_updateProcessor(m_db, *this)
+  , m_deleteProcessor(m_db)
+{
+  if (!m_db.getOwnerName().empty() && m_db.getOwnerName() != owner)
+    throw Error("owner argument differs from OwnerName in database");
+
+  if (!m_db.getTpmLocator().empty() && m_db.getTpmLocator() != tpmLocator)
+    throw Error("tpmLocator argument differs from TpmLocator in database");
+
+  initializeTpm(tpmLocator);
+  initializeMgmtCert();
+  m_db.setTpmLocator(tpmLocator);
+
+  registerPrefix();
+}
+
+Pib::~Pib()
+{
+  m_face.unsetInterestFilter(m_pibMgmtFilterId);
+  m_face.unsetInterestFilter(m_pibGetFilterId);
+  m_face.unsetInterestFilter(m_pibDefaultFilterId);
+  m_face.unsetInterestFilter(m_pibListFilterId);
+  m_face.unsetInterestFilter(m_pibUpdateFilterId);
+  m_face.unsetInterestFilter(m_pibDeleteFilterId);
+
+  m_face.unsetInterestFilter(m_pibPrefixId);
+}
+
+void
+Pib::setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert)
+{
+  if (mgmtCert != nullptr)
+    m_mgmtCert = mgmtCert;
+}
+
+void
+Pib::initializeTpm(const string& tpmLocator)
+{
+  m_tpm = KeyChain::createTpm(tpmLocator);
+}
+
+void
+Pib::initializeMgmtCert()
+{
+  shared_ptr<IdentityCertificate> mgmtCert = m_db.getMgmtCertificate();
+
+  if (mgmtCert == nullptr ||
+      !m_tpm->doesKeyExistInTpm(mgmtCert->getPublicKeyName(), KEY_CLASS_PRIVATE)) {
+    // If mgmt cert is set, or corresponding private key of the current mgmt cert is missing,
+    // generate new mgmt cert
+
+    // key name: /localhost/pib/[UserName]/mgmt/dsk-...
+    Name mgmtKeyName = PIB_PREFIX;
+    mgmtKeyName.append(m_owner).append(MGMT_LABEL);
+    std::ostringstream oss;
+    oss << "dsk-" << time::toUnixTimestamp(time::system_clock::now()).count();
+    mgmtKeyName.append(oss.str());
+
+    // self-sign pib root key
+    m_mgmtCert = prepareCertificate(mgmtKeyName, RsaKeyParams(),
+                                    time::system_clock::now(),
+                                    time::system_clock::now() + time::days(7300));
+
+    // update management certificate in database
+    m_db.updateMgmtCertificate(*m_mgmtCert);
+  }
+  else
+    m_mgmtCert = mgmtCert;
+}
+
+shared_ptr<IdentityCertificate>
+Pib::prepareCertificate(const Name& keyName, const KeyParams& keyParams,
+                        const time::system_clock::TimePoint& notBefore,
+                        const time::system_clock::TimePoint& notAfter,
+                        const Name& signerName)
+{
+  // Generate mgmt key
+  m_tpm->generateKeyPairInTpm(keyName, keyParams);
+  shared_ptr<PublicKey> publicKey = m_tpm->getPublicKeyFromTpm(keyName);
+
+  // Set mgmt cert
+  auto certificate = make_shared<IdentityCertificate>();
+  Name certName = keyName.getPrefix(-1);
+  certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+  certificate->setName(certName);
+  certificate->setNotBefore(notBefore);
+  certificate->setNotAfter(notAfter);
+  certificate->setPublicKeyInfo(*publicKey);
+  CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
+  certificate->addSubjectDescription(subjectName);
+  certificate->encode();
+
+
+  Name signingKeyName;
+  KeyLocator keyLocator;
+  if (signerName == EMPTY_SIGNER_NAME) {
+    // Self-sign mgmt cert
+    keyLocator = KeyLocator(certificate->getName().getPrefix(-1));
+    signingKeyName = keyName;
+  }
+  else {
+    keyLocator = KeyLocator(signerName.getPrefix(-1));
+    signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signerName);
+  }
+
+  SignatureSha256WithRsa signature(keyLocator);
+  certificate->setSignature(signature);
+  EncodingBuffer encoder;
+  certificate->wireEncode(encoder, true);
+  Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
+                                          signingKeyName, DIGEST_ALGORITHM_SHA256);
+  certificate->wireEncode(encoder, signatureValue);
+
+  return certificate;
+}
+
+void
+Pib::registerPrefix()
+{
+  // register pib prefix
+  Name pibPrefix = PIB_PREFIX;
+  pibPrefix.append(m_owner);
+  m_pibPrefixId =
+    m_face.registerPrefix(pibPrefix,
+                          [] (const Name& name) {},
+                          [] (const Name& name, const string& msg) {
+                            throw Error("cannot register pib prefix");
+                          });
+
+  // set interest filter for management certificate
+  m_pibMgmtFilterId =
+    m_face.setInterestFilter(Name(pibPrefix).append(MGMT_LABEL),
+                             [this] (const InterestFilter&, const Interest& interest) {
+                               if (m_mgmtCert != nullptr) {
+                                 m_face.put(*m_mgmtCert);
+                               }
+                             });
+
+  // set interest filter for get command
+  m_pibGetFilterId = registerProcessor(Name(pibPrefix).append(GetParam::VERB), m_getProcessor);
+
+  // set interest filter for default command
+  m_pibDefaultFilterId = registerProcessor(Name(pibPrefix).append(DefaultParam::VERB),
+                                           m_defaultProcessor);
+
+  // set interest filter for list command
+  m_pibListFilterId = registerProcessor(Name(pibPrefix).append(ListParam::VERB),
+                                        m_listProcessor);
+
+  // set interest filter for update command
+  m_pibUpdateFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(UpdateParam::VERB),
+                                                       m_updateProcessor);
+
+  // set interest filter for delete command
+  m_pibDeleteFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(DeleteParam::VERB),
+                                                       m_deleteProcessor);
+}
+
+template<class Processor>
+const InterestFilterId*
+Pib::registerProcessor(const Name& prefix, Processor& process)
+{
+  return m_face.setInterestFilter(prefix,
+                                  [&] (const InterestFilter&, const Interest& interest) {
+                                    processCommand(process, interest);
+                                  });
+}
+
+template<class Processor>
+const InterestFilterId*
+Pib::registerSignedCommandProcessor(const Name& prefix, Processor& process)
+{
+  const InterestFilterId* filterId =
+    m_face.setInterestFilter(prefix,
+      [&] (const InterestFilter&, const Interest& interest) {
+        m_validator.validate(interest,
+                             [&] (const shared_ptr<const Interest>& interest) {
+                               processCommand(process, *interest);
+                             },
+                             [] (const shared_ptr<const Interest>&, const string&) {});
+      });
+
+  return filterId;
+}
+
+template<class Processor>
+void
+Pib::processCommand(Processor& process, const Interest& interest)
+{
+  std::pair<bool, Block> result = process(interest);
+  if (result.first)
+    returnResult(Name(interest.getName()).appendVersion(),
+                 result.second);
+}
+
+void
+Pib::returnResult(const Name& dataName, const Block& content)
+{
+  shared_ptr<Data> data = make_shared<Data>(dataName);
+
+  data->setFreshnessPeriod(time::milliseconds::zero());
+  data->setContent(content);
+  signWithDigestSha256(*data);
+
+  // Put data into response cache
+  m_responseCache.insert(*data);
+
+  // Put data to face.
+  m_face.put(*data);
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/pib.hpp b/tools/pib/pib.hpp
new file mode 100644
index 0000000..3128191
--- /dev/null
+++ b/tools/pib/pib.hpp
@@ -0,0 +1,178 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_PIB_HPP
+#define NDN_PIB_PIB_HPP
+
+#include "pib-db.hpp"
+#include "pib-validator.hpp"
+#include "cert-publisher.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
+
+#include "get-query-processor.hpp"
+#include "default-query-processor.hpp"
+#include "list-query-processor.hpp"
+#include "update-query-processor.hpp"
+#include "delete-query-processor.hpp"
+
+#include <ndn-cxx/security/sec-tpm.hpp>
+
+namespace ndn {
+namespace pib {
+
+/// @brief implements the PIB service
+class Pib : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param face The face pib used to receive queries and serve certificates.
+   * @param dbDir Absolute path to the directory of the pib database.
+   * @param tpmLocator URI to locate the TPM for pib service.
+   * @param owner Owner of the pib database.
+   */
+  Pib(Face& face,
+      const std::string& dbDir,
+      const std::string& tpmLocator,
+      const std::string& owner);
+
+  ~Pib();
+
+  void
+  setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert);
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  PibDb&
+  getDb()
+  {
+    return m_db;
+  }
+
+  SecTpm&
+  getTpm()
+  {
+    return *m_tpm;
+  }
+
+  util::InMemoryStoragePersistent&
+  getResponseCache()
+  {
+    return m_responseCache;
+  }
+
+  const std::string&
+  getOwner() const
+  {
+    return m_owner;
+  }
+
+  const IdentityCertificate&
+  getMgmtCert() const
+  {
+    BOOST_ASSERT(m_mgmtCert != nullptr);
+    return *m_mgmtCert;
+  }
+
+private: // initialization
+  /// @brief initialize the PIB's own TPM.
+  void
+  initializeTpm(const std::string& tpmLocator);
+
+  /// @brief initialize management certificate
+  void
+  initializeMgmtCert();
+
+  std::shared_ptr<IdentityCertificate>
+  prepareCertificate(const Name& keyName, const KeyParams& keyParams,
+                     const time::system_clock::TimePoint& notBefore,
+                     const time::system_clock::TimePoint& notAfter,
+                     const Name& signerName = EMPTY_SIGNER_NAME);
+
+  /// @brief register prefix for PIB query and management certificate
+  void
+  registerPrefix();
+
+  template<class Processor>
+  const InterestFilterId*
+  registerProcessor(const Name& prefix, Processor& process);
+
+  template<class Processor>
+  const InterestFilterId*
+  registerSignedCommandProcessor(const Name& prefix, Processor& process);
+
+  template<class Processor>
+  void
+  processCommand(Processor& process, const Interest& interest);
+
+  void
+  returnResult(const Name& dataName, const Block& content);
+
+private:
+
+  static const Name EMPTY_SIGNER_NAME;
+  static const Name PIB_PREFIX;
+  static const name::Component MGMT_LABEL;
+
+  PibDb m_db;
+  std::unique_ptr<SecTpm> m_tpm;
+  std::string m_owner;
+  std::shared_ptr<IdentityCertificate> m_mgmtCert;
+
+  PibValidator m_validator;
+
+  Face& m_face;
+  CertPublisher m_certPublisher;
+  util::InMemoryStoragePersistent m_responseCache;
+
+  const RegisteredPrefixId* m_pibPrefixId;
+  const InterestFilterId* m_pibMgmtFilterId;
+  const InterestFilterId* m_pibGetFilterId;
+  const InterestFilterId* m_pibDefaultFilterId;
+  const InterestFilterId* m_pibListFilterId;
+  const InterestFilterId* m_pibUpdateFilterId;
+  const InterestFilterId* m_pibDeleteFilterId;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+
+  GetQueryProcessor m_getProcessor;
+  DefaultQueryProcessor m_defaultProcessor;
+  ListQueryProcessor m_listProcessor;
+  UpdateQueryProcessor m_updateProcessor;
+  DeleteQueryProcessor m_deleteProcessor;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_PIB_HPP
diff --git a/tools/pib/response-cache.cpp b/tools/pib/response-cache.cpp
new file mode 100644
index 0000000..57c211e
--- /dev/null
+++ b/tools/pib/response-cache.cpp
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 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 "response-cache.hpp"
+
+namespace ndn {
+namespace pib {
+
+using std::map;
+
+ResponseCache::ResponseCache()
+{
+}
+
+
+shared_ptr<const Data>
+ResponseCache::find(const Name& dataName, bool hasVersion) const
+{
+  if (!hasVersion) {
+    Storage::const_iterator it = m_storage.find(dataName);
+    if (it != m_storage.end())
+      return it->second;
+    else
+      return shared_ptr<const Data>();
+  }
+  else {
+    Storage::const_iterator it = m_storage.find(dataName.getPrefix(-1));
+    if (it != m_storage.end() && it->second->getName() == dataName)
+      return it->second;
+    else
+      return shared_ptr<const Data>();
+  }
+}
+
+void
+ResponseCache::insert(const Data& data)
+{
+  data.getName().at(-1).toVersion(); // ensures last component is version
+  m_storage[data.getName().getPrefix(-1)] = data.shared_from_this();
+}
+
+void
+ResponseCache::erase(const Name& dataNameWithoutVersion)
+{
+  m_storage.erase(dataNameWithoutVersion);
+}
+
+void
+ResponseCache::clear()
+{
+  m_storage.clear();
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/response-cache.hpp b/tools/pib/response-cache.hpp
new file mode 100644
index 0000000..40edd04
--- /dev/null
+++ b/tools/pib/response-cache.hpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_PIB_RESPONSE_CACHE_HPP
+#define NDN_PIB_RESPONSE_CACHE_HPP
+
+#include <ndn-cxx/data.hpp>
+#include <map>
+
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief ResponseCache is an abstraction of a cache of response made before
+ *
+ * ResponseCache is used to reduce the number of PibDb lookup and Data signing
+ * operations.
+ *
+ * Eventually, it should be replaced by a formal application level cache. This
+ * one is only a temporary module and is used for test.
+ */
+class ResponseCache : noncopyable
+{
+public:
+  ResponseCache();
+
+  shared_ptr<const Data>
+  find(const Name& dataName, bool hasVersion = false) const;
+
+  /**
+   * @brief Insert a data packet into cache
+   *
+   * Name of the inserted data must end with a version component
+   *
+   * @param data Data to insert. It MUST have been created with make_shared.
+   */
+  void
+  insert(const Data& data);
+
+  void
+  erase(const Name& dataNameWithoutVersion);
+
+  void
+  clear();
+
+private:
+  typedef std::map<Name, shared_ptr<const Data> > Storage;
+
+  Storage m_storage;
+};
+
+} // namespace ndn
+} // namespace pib
+
+#endif // NDN_PIB_RESPONSE_CACHE_HPP
diff --git a/tools/pib/update-query-processor.cpp b/tools/pib/update-query-processor.cpp
new file mode 100644
index 0000000..4ab853d
--- /dev/null
+++ b/tools/pib/update-query-processor.cpp
@@ -0,0 +1,267 @@
+/* -*- 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 "update-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+#include "pib.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+
+const size_t UpdateQueryProcessor::UPDATE_QUERY_LENGTH = 9;
+const Name UpdateQueryProcessor::PIB_PREFIX("/localhost/pib");
+
+UpdateQueryProcessor::UpdateQueryProcessor(PibDb& db, Pib& pib)
+  : m_db(db)
+  , m_pib(pib)
+{
+}
+
+std::pair<bool, Block>
+UpdateQueryProcessor::operator()(const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+
+  // handle pib query: /localhost/pib/[UserName]/update/param/<signed_interest_related_components>
+  if (interestName.size() != UPDATE_QUERY_LENGTH) {
+    // malformed interest, discard
+    return std::make_pair(false, Block());
+  }
+
+  try {
+    UpdateParam param;
+    param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
+
+    SignatureInfo sigInfo;
+    sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
+
+    // sigInfo must have KeyLocator.Name if the interest passed validation.
+    Name signerName;
+    signerName = sigInfo.getKeyLocator().getName();
+
+    switch (param.getEntityType()) {
+    case tlv::pib::User:
+      return processUpdateUserQuery(param, signerName);
+    case tlv::pib::Identity:
+      return processUpdateIdQuery(param, signerName);
+    case tlv::pib::PublicKey:
+      return processUpdateKeyQuery(param, signerName);
+    case tlv::pib::Certificate:
+      return processUpdateCertQuery(param, signerName);
+    default:
+      {
+        PibError error(ERR_WRONG_PARAM,
+                       "entity type is not supported: " +
+                       boost::lexical_cast<string>(param.getEntityType()));
+        return std::make_pair(true, error.wireEncode());
+      }
+    }
+  }
+  catch (const PibDb::Error& e) {
+    PibError error(ERR_INTERNAL_ERROR, e.what());
+    return std::make_pair(true, error.wireEncode());
+  }
+  catch (const tlv::Error& e) {
+    PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
+    return std::make_pair(true, error.wireEncode());
+  }
+}
+
+std::pair<bool, Block>
+UpdateQueryProcessor::processUpdateUserQuery(const UpdateParam& param, const Name& signerName)
+{
+  Name expectedId = m_db.getMgmtCertificate()->getPublicKeyName().getPrefix(-1);
+  Name targetId = param.getUser().getMgmtCert().getPublicKeyName().getPrefix(-1);
+  Name signerId = IdentityCertificate::certificateNameToPublicKeyName(signerName).getPrefix(-1);
+
+  if (expectedId == targetId && expectedId == signerId) {
+    m_db.updateMgmtCertificate(param.getUser().getMgmtCert());
+    m_pib.setMgmtCert(make_shared<IdentityCertificate>(param.getUser().getMgmtCert()));
+    return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+  }
+
+  PibError error(ERR_WRONG_PARAM, "not allowed to update user");
+  return std::make_pair(true, error.wireEncode());
+}
+
+std::pair<bool, Block>
+UpdateQueryProcessor::processUpdateIdQuery(const UpdateParam& param, const Name& signerName)
+{
+  const Name& identity = param.getIdentity().getIdentity();
+  if (!isUpdateAllowed(TYPE_ID, identity, signerName, param.getDefaultOpt())) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  // add the identity
+  m_db.addIdentity(identity);
+
+  // set the identity as user default if it is requested.
+  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
+  if (DEFAULT_OPT_USER_MASK & defaultOpt) {
+    m_db.setDefaultIdentity(identity);
+  }
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+std::pair<bool, Block>
+UpdateQueryProcessor::processUpdateKeyQuery(const UpdateParam& param, const Name& signerName)
+{
+  const Name& keyName = param.getPublicKey().getKeyName();
+  if (!isUpdateAllowed(TYPE_KEY, keyName, signerName, param.getDefaultOpt())) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  Name identity = keyName.getPrefix(-1);
+
+  // add the key
+  m_db.addKey(keyName, param.getPublicKey().getPublicKey());
+
+  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
+  if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
+    m_db.setDefaultKeyNameOfIdentity(keyName);
+  if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
+    m_db.setDefaultIdentity(identity);
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+std::pair<bool, Block>
+UpdateQueryProcessor::processUpdateCertQuery(const UpdateParam& param, const Name& signerName)
+{
+  const IdentityCertificate& cert = param.getCertificate().getCertificate();
+  const Name& certName = cert.getName();
+  if (!isUpdateAllowed(TYPE_CERT, certName, signerName, param.getDefaultOpt())) {
+    PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
+    return std::make_pair(true, error.wireEncode());
+  }
+
+  const Name& keyName = cert.getPublicKeyName();
+  Name identity = keyName.getPrefix(-1);
+
+  // add certificate
+  m_db.addCertificate(cert);
+
+  const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
+  if (DEFAULT_OPT_KEY_MASK & defaultOpt) // set the cert as key default if requested.
+    m_db.setDefaultCertNameOfKey(certName);
+  if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
+    m_db.setDefaultKeyNameOfIdentity(keyName);
+  if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
+    m_db.setDefaultIdentity(identity);
+
+  return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
+}
+
+bool
+UpdateQueryProcessor::isUpdateAllowed(const pib::Type targetType,
+                                      const Name& targetName,
+                                      const Name& signer,
+                                      const pib::DefaultOpt defaultOpt) const
+{
+  // Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
+  // that prefix will be rejected.
+  if (PIB_PREFIX.isPrefixOf(targetName))
+    return false;
+
+  // A request is wrong if
+  // 1) it wants to change the default setting of an identity, but the target is not key nor cert
+  // 2) it wants to change the default setting of a key, but the target is not cert
+  if ((defaultOpt == DEFAULT_OPT_ID && (targetType != TYPE_KEY && targetType != TYPE_CERT)) ||
+      (defaultOpt == DEFAULT_OPT_KEY && targetType != TYPE_CERT))
+    return false;
+
+
+  // Rules for other items:
+  //
+  //    signer          | adding privilege         | default setting privilege
+  //    ================+==========================+============================================
+  //    local mgmt key  | any id, key, and cert    | the default id,
+  //                    |                          | the default key of any id,
+  //                    |                          | the default cert of any key of any id
+  //    ----------------+--------------------------+--------------------------------------------
+  //    default key of  | any id, key, and cert    | the default key of the id and its sub ids,
+  //    an id           | under the id's namespace | the default cert of any key of the id
+  //                    |                          | and its sub ids
+  //    ----------------+--------------------------+--------------------------------------------
+  //    non-default key | any cert of the key      | the default cert of the key
+  //    of an id
+
+  const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
+  const Name& signerId = signerKeyName.getPrefix(-1);
+
+  bool hasSignerDefaultKey = true;
+  Name signerDefaultKeyName;
+  try {
+    signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
+  }
+  catch (PibDb::Error&) {
+    hasSignerDefaultKey = false;
+  }
+
+  Name mgmtCertName;
+  try {
+    mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
+  }
+  catch (PibDb::Error&) {
+    return false;
+  }
+
+  if (signer == mgmtCertName) {
+    // signer is current management key, anything is allowed.
+    return true;
+  }
+  else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
+    // signer is an identity's default key
+    if (!signerId.isPrefixOf(targetName))
+      return false;
+
+    // check default setting
+    // user default setting is not allowed
+    if (defaultOpt == DEFAULT_OPT_USER)
+      return false;
+    else
+      return true;
+  }
+  else {
+    // non-default key
+    if (targetType != TYPE_CERT)
+      return false;
+
+    // check if it is for the key's cert
+    if (IdentityCertificate::certificateNameToPublicKeyName(targetName) != signerKeyName)
+      return false;
+
+    if (defaultOpt == DEFAULT_OPT_USER || defaultOpt == DEFAULT_OPT_ID)
+      return false;
+    else
+      return true;
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/update-query-processor.hpp b/tools/pib/update-query-processor.hpp
new file mode 100644
index 0000000..6c0655b
--- /dev/null
+++ b/tools/pib/update-query-processor.hpp
@@ -0,0 +1,98 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
+#define NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
+
+#include "pib-db.hpp"
+#include "encoding/update-param.hpp"
+#include <ndn-cxx/interest.hpp>
+#include <utility>
+
+namespace ndn {
+namespace pib {
+
+class Pib;
+
+/// @brief Processing unit for PIB update query
+class UpdateQueryProcessor : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Constructor
+   *
+   * @param db The pib database.
+   */
+  UpdateQueryProcessor(PibDb& db, Pib& pib);
+
+  std::pair<bool, Block>
+  operator()(const Interest& interest);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Determine if an update command is allowed.
+   *
+   * @param targetType The type of the target that will be updated.
+   * @param targetName The name of the target that will be updated.
+   * @param signer     The name of the command signer.
+   * @param defaultOpt The default settings that is requested to update.
+   */
+  bool
+  isUpdateAllowed(const pib::Type targetType,
+                  const Name& targetName,
+                  const Name& signer,
+                  const pib::DefaultOpt defaultOpt) const;
+
+private:
+  std::pair<bool, Block>
+  processUpdateUserQuery(const UpdateParam& param, const Name& signerName);
+
+  std::pair<bool, Block>
+  processUpdateIdQuery(const UpdateParam& param, const Name& signerName);
+
+  std::pair<bool, Block>
+  processUpdateKeyQuery(const UpdateParam& param, const Name& signerName);
+
+  std::pair<bool, Block>
+  processUpdateCertQuery(const UpdateParam& param, const Name& signerName);
+
+private:
+  static const size_t UPDATE_QUERY_LENGTH;
+  static const Name PIB_PREFIX;
+
+  PibDb&  m_db;
+  Pib& m_pib;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
diff --git a/tools/pib/wscript b/tools/pib/wscript
new file mode 100644
index 0000000..7a40d5a
--- /dev/null
+++ b/tools/pib/wscript
@@ -0,0 +1,19 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+top = '../..'
+
+def build(bld):
+
+    bld(features=['cxx'],
+        name="pib-objects",
+        target="pib-objects",
+        source=bld.path.ant_glob('**/*.cpp', excl=['ndn-pib.cpp']),
+        use='core-objects',
+        install_path=None,
+        )
+
+
+    bld(features=['cxx', 'cxxprogram'],
+        target='ndn-pib',
+        source='ndn-pib.cpp',
+        use='pib-objects',
+        )
