diff --git a/AUTHORS.md b/AUTHORS.md
index 3d40a6f..0915877 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -12,3 +12,4 @@
 * Junxiao Shi           <http://www.cs.arizona.edu/people/shijunxiao/>
 * Eric Newberry         <http://ericnewberry.com/>
 * Xiaoke Jiang          <http://netarchlab.tsinghua.edu.cn/~shock/>
+* Yingdi Yu             <http://irl.cs.ucla.edu/~yingdi/>
diff --git a/manpages/conf.py b/manpages/conf.py
index 3c0f6bb..d86777a 100644
--- a/manpages/conf.py
+++ b/manpages/conf.py
@@ -12,4 +12,5 @@
     ('ndnpingserver', 'ndnpingserver', 'reachability testing server', None, 1),
     ('ndndump', 'ndndump', 'traffic analysis tool', None, 8),
     ('ndn-dissect', 'ndn-dissect', 'NDN packet format inspector', None, 1),
+    ('ndn-pib', 'ndn-pib',  'NDN PIB service', None, 1),
 ]
diff --git a/manpages/ndn-pib.rst b/manpages/ndn-pib.rst
new file mode 100644
index 0000000..e94a7d2
--- /dev/null
+++ b/manpages/ndn-pib.rst
@@ -0,0 +1,35 @@
+ndn-pib
+========
+
+``ndn-pib`` is a public key and certificate management and publishing service.
+
+Usage
+-----
+
+::
+
+    ndn-pib [-h] -o owner -d database_dir -t tpm_locator
+
+Description
+-----------
+
+This command will start a PIB service process which serves signing key lookup/management for local
+applications and also public the public key certificate of signing keys.  The lookup/management
+interface listens on a prefix "/localhost/pib/[OwnerName]" and accept five types of command (get,
+default, list, update, delete). More details can be found at `Public key Info Base (PIB) Service
+<http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base>`__
+
+Since PIB service is queried through Interest/Data exchange, NFD is required to run before this
+command is executed.
+
+This command requires three arguments: ``owner`` specify the owner of the pib service, which is also
+the third name component in the local lookup/management prefix; ``database_dir`` is the path to the
+database where all the public key, certificate, identity are stored and managed; ``tpm_locator`` is
+locator of a TPM which stores the corresponding private key of the public keys in PIB.
+
+Example
+-------
+
+::
+
+    $ ndn-pib -o alice -d /var/pib -t tpm-file:/var/ndn/tpm
diff --git a/tests/pib/cert-publicher.t.cpp b/tests/pib/cert-publicher.t.cpp
new file mode 100644
index 0000000..f33f325
--- /dev/null
+++ b/tests/pib/cert-publicher.t.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 "tools/pib/cert-publisher.hpp"
+#include "identity-management-time-fixture.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class CertPublisherFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+  CertPublisherFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
+    , db(tmpPath.c_str())
+    , face(util::makeDummyClientFace(io, {true, true}))
+  {
+  }
+
+  ~CertPublisherFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  boost::asio::io_service io;
+  boost::filesystem::path tmpPath;
+  PibDb db;
+  shared_ptr<util::DummyClientFace> face;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestCertPublisher, CertPublisherFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  // Initialize id1
+  Name id1("/test/identity");
+  addIdentity(id1);
+  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
+  Name keyName11 = cert111->getPublicKeyName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
+  Name certName112 = cert112->getName();
+
+  CertPublisher certPublisher(*face, db);
+
+  // Add a certificate
+  db.addCertificate(*cert111);
+  advanceClocks(io, time::milliseconds(2), 50);
+
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+  auto interest111 = make_shared<Interest>(cert111->getName().getPrefix(-1));
+  face->receive(*interest111);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
+  face->sentDatas.clear();
+
+  // Add another certificate
+  db.addCertificate(*cert112);
+  advanceClocks(io, time::milliseconds(2), 50);
+
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+  auto interest112 = make_shared<Interest>(cert112->getName().getPrefix(-1));
+  face->receive(*interest112);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
+  face->sentDatas.clear();
+
+  Exclude exclude;
+  exclude.excludeOne(cert111->getName().get(-1));
+  interest112->setExclude(exclude);
+  face->receive(*interest112);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert112->wireEncode());
+  face->sentDatas.clear();
+
+  // delete a certificate
+  db.deleteCertificate(certName112);
+  face->receive(*interest112);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+  face->receive(*interest111);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
+  face->sentDatas.clear();
+
+  // delete another certificate
+  db.deleteCertificate(certName111);
+  face->receive(*interest112);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+  face->receive(*interest111);
+  advanceClocks(io, time::milliseconds(2), 50);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/identity-management-time-fixture.cpp b/tests/pib/identity-management-time-fixture.cpp
new file mode 100644
index 0000000..526a2e6
--- /dev/null
+++ b/tests/pib/identity-management-time-fixture.cpp
@@ -0,0 +1,58 @@
+/* -*- 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 "identity-management-time-fixture.hpp"
+
+namespace ndn {
+namespace security {
+
+IdentityManagementTimeFixture::IdentityManagementTimeFixture()
+  : m_keyChainTmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "PibIdMgmtTimeTest")
+  , m_keyChain(std::string("pib-sqlite3:").append(m_keyChainTmpPath.string()),
+               std::string("tpm-file:").append(m_keyChainTmpPath.string()))
+{
+}
+
+IdentityManagementTimeFixture::~IdentityManagementTimeFixture()
+{
+  for (const auto& identity : m_identities) {
+    m_keyChain.deleteIdentity(identity);
+  }
+
+  boost::filesystem::remove_all(m_keyChainTmpPath);
+}
+
+bool
+IdentityManagementTimeFixture::addIdentity(const Name& identity, const KeyParams& params)
+{
+  try {
+    m_keyChain.createIdentity(identity, params);
+    m_identities.push_back(identity);
+    return true;
+  }
+  catch (std::runtime_error&) {
+    return false;
+  }
+}
+
+
+} // namespace security
+} // namespace ndn
diff --git a/tests/pib/identity-management-time-fixture.hpp b/tests/pib/identity-management-time-fixture.hpp
new file mode 100644
index 0000000..4ac2e63
--- /dev/null
+++ b/tests/pib/identity-management-time-fixture.hpp
@@ -0,0 +1,61 @@
+/* -*- 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_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
+#define NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <vector>
+#include <boost/filesystem.hpp>
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace security {
+
+/**
+ * @brief IdentityManagementTimeFixture is a test suite level fixture.
+ * Test cases in the suite can use this fixture to create identities.
+ * Identities added via addIdentity method are automatically deleted
+ * during test teardown.
+ */
+class IdentityManagementTimeFixture : public tests::UnitTestTimeFixture
+{
+public:
+  IdentityManagementTimeFixture();
+
+  ~IdentityManagementTimeFixture();
+
+  /// @brief add identity, return true if succeed.
+  bool
+  addIdentity(const Name& identity, const KeyParams& params = KeyChain::DEFAULT_KEY_PARAMS);
+
+protected:
+  boost::filesystem::path m_keyChainTmpPath;
+
+  KeyChain m_keyChain;
+  std::vector<Name> m_identities;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
diff --git a/tests/pib/key-cache.t.cpp b/tests/pib/key-cache.t.cpp
new file mode 100644
index 0000000..936c132
--- /dev/null
+++ b/tests/pib/key-cache.t.cpp
@@ -0,0 +1,75 @@
+/* -*- 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 "tools/pib/key-cache.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestKeyCache)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  KeyCache keyCache(3);
+
+  Name name1("/1");
+  Name name2("/2");
+  Name name3("/3");
+  Name name4("/4");
+
+  auto key1 = make_shared<PublicKey>();
+  auto key2 = make_shared<PublicKey>();
+  auto key3 = make_shared<PublicKey>();
+  auto key4 = make_shared<PublicKey>();
+
+  keyCache.insert(name1, key1);
+  keyCache.insert(name2, key2);
+  keyCache.insert(name3, key3);
+
+  BOOST_CHECK_EQUAL(keyCache.size(), 3);
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name2)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
+  BOOST_CHECK(!static_cast<bool>(keyCache.find(name4)));
+
+  keyCache.insert(name1, key1);
+  keyCache.insert(name4, key4);
+  BOOST_CHECK_EQUAL(keyCache.size(), 3);
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
+  BOOST_CHECK(!static_cast<bool>(keyCache.find(name2)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
+
+  keyCache.erase(name1);
+  BOOST_CHECK_EQUAL(keyCache.size(), 2);
+  BOOST_CHECK(!static_cast<bool>(keyCache.find(name1)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
+  BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/pib-db.t.cpp b/tests/pib/pib-db.t.cpp
new file mode 100644
index 0000000..6d826d2
--- /dev/null
+++ b/tests/pib/pib-db.t.cpp
@@ -0,0 +1,474 @@
+/* -*- 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 "tools/pib/pib-db.hpp"
+#include "identity-management-time-fixture.hpp"
+
+#include <boost/filesystem.hpp>
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class PibDbTestFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+  PibDbTestFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
+    , db(tmpPath.c_str())
+  {
+  }
+
+  ~PibDbTestFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  boost::asio::io_service io;
+  boost::filesystem::path tmpPath;
+  PibDb db;
+  std::vector<Name> deletedIds;
+  std::vector<Name> deletedKeys;
+  std::vector<Name> deletedCerts;
+  std::vector<Name> insertedCerts;
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(TestPibDb, PibDbTestFixture)
+
+BOOST_AUTO_TEST_CASE(MgmtTest)
+{
+  Name testUser("/localhost/pib/test/mgmt");
+  addIdentity(testUser);
+  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+
+  BOOST_CHECK_EQUAL(db.getOwnerName(), "");
+  BOOST_CHECK(db.getMgmtCertificate() == nullptr);
+
+  db.updateMgmtCertificate(*testUserCert);
+  BOOST_CHECK_EQUAL(db.getOwnerName(), "test");
+  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
+  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(), testUserCertName);
+
+  db.setTpmLocator("tpmLocator");
+  BOOST_CHECK_EQUAL(db.getTpmLocator(), "tpmLocator");
+
+  Name testUser2("/localhost/pib/test2/mgmt");
+  addIdentity(testUser2);
+  Name testUser2CertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser2);
+  shared_ptr<IdentityCertificate> testUser2Cert = m_keyChain.getCertificate(testUser2CertName);
+
+  BOOST_CHECK_THROW(db.updateMgmtCertificate(*testUser2Cert), PibDb::Error);
+
+  Name testUserKeyName2 = m_keyChain.generateRsaKeyPairAsDefault(testUser);
+  shared_ptr<IdentityCertificate> testUserCert2 = m_keyChain.selfSign(testUserKeyName2);
+
+  BOOST_CHECK_NO_THROW(db.updateMgmtCertificate(*testUserCert2));
+  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
+  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(),
+                    testUserCert2->getName());
+}
+
+BOOST_AUTO_TEST_CASE(IdentityTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  Name identity("/test/identity");
+  Name identity2("/test/identity2");
+
+  // Add an identity: /test/identity
+  // Since there is no default identity,
+  // the new added identity will be set as the default identity.
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
+  db.addIdentity(identity);
+  BOOST_CHECK(db.hasIdentity(identity));
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
+
+  // Add the second identity: /test/identity2
+  // Since the default identity exists,
+  // the new added identity will not be set as the default identity.
+  db.addIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
+
+  // Set the second identity: /test/identity2 as default explicitly
+  db.setDefaultIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
+
+  // Delete identity /test/identity2, which is also the default one
+  // This will trigger the identityDeleted signal
+  // and also causes no default identity.
+  db.deleteIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), true);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
+  deletedIds.clear();
+
+  // Add the second identity back
+  // Since there is no default identity (though another identity still exists),
+  // the second identity will be set as default.
+  db.addIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
+
+  // Delete identity /test/identity
+  db.deleteIdentity(identity);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity);
+  deletedIds.clear();
+
+  // Delete identity /test/identity2
+  db.deleteIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
+  deletedIds.clear();
+}
+
+
+BOOST_AUTO_TEST_CASE(KeyTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  db.keyDeleted.connect([this] (const Name& key) {
+      this->deletedKeys.push_back(key);
+    });
+
+  // Initialize id1
+  Name id1("/test/identity");
+  addIdentity(id1);
+  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
+  Name keyName11 = cert111->getPublicKeyName();
+  PublicKey& key11 = cert111->getPublicKeyInfo();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
+  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
+  PublicKey& key12 = cert121->getPublicKeyInfo();
+
+  // Initialize id2
+  advanceClocks(io, time::milliseconds(100));
+  Name id2("/test/identity2");
+  addIdentity(id2);
+  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
+  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
+  Name keyName21 = cert211->getPublicKeyName();
+  PublicKey& key21 = cert211->getPublicKeyInfo();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
+  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
+  PublicKey& key22 = cert221->getPublicKeyInfo();
+
+  // Add a key, the corresponding identity should be added as well
+  // Since the PIB does not have any default identity set before,
+  // the added identity will be set as default.
+  // Since there is no default key for the identity,
+  // the added key will be set as default.
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
+  BOOST_CHECK(db.getKey(keyName11) == nullptr);
+  db.addKey(keyName11, key11);
+  BOOST_CHECK(db.hasIdentity(id1));
+  BOOST_CHECK(db.getKey(keyName11) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+
+  // Add the second key of /test/identity.
+  // Since the default key of /test/identity has been set,
+  // The new added key will not be set as default.
+  db.addKey(keyName12, key12);
+  BOOST_CHECK(db.getKey(keyName12) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+
+  // Explicitly set the second key as the default key of /test/identity
+  db.setDefaultKeyNameOfIdentity(keyName12);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
+
+  // Delete the second key which is also the default key.
+  // This will trigger the keyDeleted signal.
+  // This will also cause no default key for /test/identity
+  db.deleteKey(keyName12);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), false);
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
+  BOOST_CHECK_EQUAL(deletedKeys[0], keyName12);
+  deletedKeys.clear();
+
+  // Add the second key back.
+  // Since there is no default key of /test/identity (although another key still exists)
+  // The second key will be set as the default key of /test/identity
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
+  db.addKey(keyName12, key12);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
+
+  // Prepare test for identity deletion
+  db.addKey(keyName21, key21);
+  db.addKey(keyName22, key22);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+
+  // Delete the identity.
+  // All keys of the identity should also be deleted,
+  // and the keyDeleted signal should be triggered twice.
+  db.deleteIdentity(id1);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
+              deletedKeys.end());
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
+              deletedKeys.end());
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], id1);
+}
+
+BOOST_AUTO_TEST_CASE(CertTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  db.keyDeleted.connect([this] (const Name& key) {
+      this->deletedKeys.push_back(key);
+    });
+
+  db.certificateDeleted.connect([this] (const Name& certificate) {
+      this->deletedCerts.push_back(certificate);
+    });
+
+  db.certificateInserted.connect([this] (const Name& certificate) {
+      this->insertedCerts.push_back(certificate);
+    });
+
+  // Initialize id1
+  Name id1("/test/identity");
+  addIdentity(id1);
+  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
+  Name keyName11 = cert111->getPublicKeyName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
+  Name certName112 = cert112->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
+  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
+  Name certName121 = cert121->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert122 = m_keyChain.selfSign(keyName12);
+  Name certName122 = cert122->getName();
+
+  // Initialize id2
+  advanceClocks(io, time::milliseconds(100));
+  Name id2("/test/identity2");
+  addIdentity(id2);
+  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
+  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
+  Name keyName21 = cert211->getPublicKeyName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert212 = m_keyChain.selfSign(keyName21);
+  Name certName212 = cert212->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
+  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
+  Name certName221 = cert221->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert222 = m_keyChain.selfSign(keyName22);
+  Name certName222 = cert222->getName();
+
+  // Add a certificate
+  // This will also add the corresponding key and identity.
+  // Since there is no default setting before,
+  // The certificate will be set as the default one of the key, and so be the key and identity
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
+  db.addCertificate(*cert111);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName111) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Add the second certificate of the same key
+  // Since default certificate already exists, no default setting changes.
+  BOOST_CHECK(db.getCertificate(certName112) == nullptr);
+  db.addCertificate(*cert112);
+  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName112) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Explicitly set the second certificate as the default one of the key.
+  db.setDefaultCertNameOfKey(certName112);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
+
+  // Delete the default certificate
+  // This will trigger certificateDeleted signal
+  // and also causes no default certificate for the key.
+  db.deleteCertificate(certName112);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 1);
+  BOOST_CHECK_EQUAL(deletedCerts[0], certName112);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
+  deletedCerts.clear();
+
+  // Add the second certificate back
+  // Since there is no default certificate of the key (though another certificate still exists),
+  // the new added certificate will be set as default
+  db.addCertificate(*cert112);
+  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
+  insertedCerts.clear();
+
+  // Add entries for delete tests
+  db.addCertificate(*cert111); // already exists no certInserted signal emitted
+  db.addCertificate(*cert112); // already exists no certInserted signal emitted
+  db.addCertificate(*cert121);
+  db.addCertificate(*cert122);
+  db.addCertificate(*cert211);
+  db.addCertificate(*cert212);
+  db.addCertificate(*cert221);
+  db.addCertificate(*cert222);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 6);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName121) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName122) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName211) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName212) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName221) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName222) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Delete the key.
+  // All the related certificates will be deleted as well.
+  db.deleteKey(keyName11);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 2);
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
+  BOOST_CHECK_EQUAL(deletedKeys[0], keyName11);
+  deletedCerts.clear();
+  deletedKeys.clear();
+
+  // Recover deleted entries
+  db.addCertificate(*cert111);
+  db.addCertificate(*cert112);
+
+  // Delete the identity
+  // All the related certificates and keys will be deleted as well.
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+  db.deleteIdentity(id1);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 4);
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName121) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName122) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
+              deletedKeys.end());
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], id1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/pib-validator.t.cpp b/tests/pib/pib-validator.t.cpp
new file mode 100644
index 0000000..06fd373
--- /dev/null
+++ b/tests/pib/pib-validator.t.cpp
@@ -0,0 +1,137 @@
+/* -*- 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 "tools/pib/pib-validator.hpp"
+#include "tools/pib/encoding/update-param.hpp"
+#include "tools/pib/encoding/delete-param.hpp"
+#include <ndn-cxx/security/key-chain.hpp>
+
+#include "identity-management-time-fixture.hpp"
+#include <boost/filesystem.hpp>
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class PibValidatorFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+  PibValidatorFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
+    , db(tmpPath.c_str())
+  {
+  }
+
+  ~PibValidatorFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  boost::asio::io_service io;
+  boost::filesystem::path tmpPath;
+  PibDb db;
+  bool isProcessed;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestPibValidator, PibValidatorFixture)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  PibValidator validator(db);
+
+  Name testUser("/localhost/pib/test/mgmt");
+  BOOST_REQUIRE(addIdentity(testUser, RsaKeyParams()));
+  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testUser2("/localhost/pib/test2/mgmt");
+  BOOST_REQUIRE(addIdentity(testUser2, RsaKeyParams()));
+
+  db.updateMgmtCertificate(*testUserCert);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name normalId("/normal/id");
+  BOOST_REQUIRE(addIdentity(normalId, RsaKeyParams()));
+  Name normalIdCertName = m_keyChain.getDefaultCertificateNameForIdentity(normalId);
+  shared_ptr<IdentityCertificate> normalIdCert = m_keyChain.getCertificate(normalIdCertName);
+
+  db.addIdentity(normalId);
+  db.addKey(normalIdCert->getPublicKeyName(), normalIdCert->getPublicKeyInfo());
+  db.addCertificate(*normalIdCert);
+
+  Name command1("/localhost/pib/test/verb/param");
+  shared_ptr<Interest> interest1 = make_shared<Interest>(command1);
+  m_keyChain.signByIdentity(*interest1, testUser);
+  // "test" user is trusted for any command about itself, OK.
+  isProcessed = false;
+  validator.validate(*interest1,
+    [this] (const shared_ptr<const Interest>&) {
+      isProcessed = true;
+      BOOST_CHECK(true);
+    },
+    [this] (const shared_ptr<const Interest>&, const std::string&) {
+      isProcessed = true;
+      BOOST_CHECK(false);
+    });
+  BOOST_CHECK(isProcessed);
+
+  Name command2("/localhost/pib/test/verb/param");
+  shared_ptr<Interest> interest2 = make_shared<Interest>(command2);
+  m_keyChain.signByIdentity(*interest2, testUser2);
+  // "test2" user is NOT trusted for any command about other user, MUST fail
+  isProcessed = false;
+  validator.validate(*interest2,
+    [this] (const shared_ptr<const Interest>&) {
+      isProcessed = true;
+      BOOST_CHECK(false);
+    },
+    [this] (const shared_ptr<const Interest>&, const std::string&) {
+      isProcessed = true;
+      BOOST_CHECK(true);
+    });
+  BOOST_CHECK(isProcessed);
+
+  Name command3("/localhost/pib/test/verb/param");
+  shared_ptr<Interest> interest3 = make_shared<Interest>(command3);
+  m_keyChain.signByIdentity(*interest3, normalId);
+  // "normalId" is in "test" pib, can be trusted for some commands about "test".
+  // Detail checking is needed, but it is not the job of Validator, OK.
+  isProcessed = false;
+  validator.validate(*interest3,
+    [this] (const shared_ptr<const Interest>&) {
+      isProcessed = true;
+      BOOST_CHECK(true);
+    },
+    [this] (const shared_ptr<const Interest>&, const std::string&) {
+      isProcessed = true;
+      BOOST_CHECK(false);
+    });
+  BOOST_CHECK(isProcessed);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/pib.t.cpp b/tests/pib/pib.t.cpp
new file mode 100644
index 0000000..f4c4e6f
--- /dev/null
+++ b/tests/pib/pib.t.cpp
@@ -0,0 +1,1389 @@
+/* -*- 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 "tools/pib/pib.hpp"
+#include "identity-management-time-fixture.hpp"
+#include <ndn-cxx/security/sec-tpm-file.hpp>
+#include "tools/pib/encoding/pib-encoding.hpp"
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include <boost/filesystem.hpp>
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class PibTestFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+  PibTestFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "PibTest")
+    , face(util::makeDummyClientFace(io, {true, true}))
+  {
+  }
+
+  ~PibTestFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  template<class Param>
+  shared_ptr<Interest>
+  generateUnsignedInterest(Param& param, const std::string& user)
+  {
+    Name command("/localhost/pib");
+    command.append(user).append(Param::VERB).append(param.wireEncode());
+    shared_ptr<Interest> interest = make_shared<Interest>(command);
+
+    return interest;
+  }
+
+  template<class Param>
+  shared_ptr<Interest>
+  generateSignedInterest(Param& param, const std::string& user, const Name& certName)
+  {
+    shared_ptr<Interest> interest = generateUnsignedInterest(param, user);
+    m_keyChain.sign(*interest, certName);
+
+    return interest;
+  }
+
+  boost::asio::io_service io;
+  std::string owner;
+  boost::filesystem::path tmpPath;
+  shared_ptr<util::DummyClientFace> face;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestPib, PibTestFixture)
+
+BOOST_AUTO_TEST_CASE(InitCertTest1)
+{
+  // Create a PIB with full parameters
+  owner = "testUser";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK_EQUAL(pib.getOwner(), owner);
+  BOOST_CHECK_EQUAL(pib.getDb().getOwnerName(), owner);
+
+  auto mgmtCert = pib.getMgmtCert();
+  BOOST_CHECK_EQUAL(mgmtCert.getName().getPrefix(-3),
+                    Name("/localhost/pib/testUser/mgmt/KEY"));
+  BOOST_CHECK_EQUAL(mgmtCert.getName().get(5).toUri().substr(0, 4), "dsk-");
+
+  auto mgmtCert2 = pib.getDb().getMgmtCertificate();
+  BOOST_REQUIRE(mgmtCert2 != nullptr);
+  BOOST_CHECK(mgmtCert.wireEncode() == mgmtCert2->wireEncode());
+
+  BOOST_CHECK_EQUAL(pib.getDb().getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
+
+  GetParam param01;
+  shared_ptr<Interest> interest01 = generateUnsignedInterest(param01, owner);
+
+  face->receive(*interest01);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibUser result01;
+  BOOST_REQUIRE_NO_THROW(result01.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK(result01.getMgmtCert().wireEncode() == mgmtCert.wireEncode());
+  BOOST_CHECK_EQUAL(result01.getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
+}
+
+BOOST_AUTO_TEST_CASE(InitCertTest2)
+{
+  // Create a PIB from a database (assume that the database is configured)
+  std::string dbDir = tmpPath.string();
+  std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
+  owner = "testUser";
+
+  Name testUser("/localhost/pib/testUser/mgmt");
+
+  addIdentity(testUser);
+  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+  PibDb db(tmpPath.string());
+  BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+
+  db.updateMgmtCertificate(*testUserCert);
+  BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+  BOOST_CHECK_THROW(Pib(*face, dbDir, tpmLocator, "wrongUser"), Pib::Error);
+
+  db.setTpmLocator(m_keyChain.getTpm().getTpmLocator());
+  BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+  BOOST_CHECK_THROW(Pib(*face, dbDir, "tpm-file:wrong", owner), Pib::Error);
+
+  advanceClocks(io, time::milliseconds(10));
+  m_keyChain.deleteIdentity(testUser);
+  BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+}
+
+BOOST_AUTO_TEST_CASE(InitCertTest3)
+{
+  std::string dbDir = tmpPath.string();
+  std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
+  owner = "testUser";
+
+  Name testUser("/localhost/pib/testUser/mgmt");
+  addIdentity(testUser);
+  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+  Pib pib1(*face, dbDir, tpmLocator, owner);
+  BOOST_CHECK_EQUAL(pib1.getMgmtCert().getName().getPrefix(-3),
+                    Name("/localhost/pib/testUser/mgmt/KEY"));
+
+  PibDb db(tmpPath.string());
+  db.updateMgmtCertificate(*testUserCert);
+  Pib pib2(*face, dbDir, tpmLocator, owner);
+  BOOST_CHECK_EQUAL(pib2.getMgmtCert().getName(), testUserCertName);
+
+  advanceClocks(io, time::milliseconds(10));
+  m_keyChain.deleteIdentity(testUser);
+  Pib pib3(*face, dbDir, tpmLocator, owner);
+  BOOST_CHECK(pib3.getMgmtCert().getName() != testUserCertName);
+  BOOST_CHECK_EQUAL(pib3.getMgmtCert().getName().getPrefix(-3),
+                    Name("/localhost/pib/testUser/mgmt/KEY"));
+}
+
+BOOST_AUTO_TEST_CASE(GetCommandTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb db(tmpPath.string());
+
+  Name testId("/test/identity");
+  Name testIdCertName00 = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
+  Name testIdKeyName0 = cert00->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
+  Name testIdCertName01 = cert01->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName10 = cert10->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName11 = cert11->getName();
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+  db.addCertificate(*cert00);
+  db.addCertificate(*cert01);
+  db.addCertificate(*cert10);
+  db.addCertificate(*cert11);
+  db.setDefaultIdentity(testId);
+  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+  db.setDefaultCertNameOfKey(testIdCertName00);
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+  // Get Param
+  GetParam param01;
+  shared_ptr<Interest> interest01 = generateUnsignedInterest(param01, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest01);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest01->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibUser result01;
+  BOOST_REQUIRE_NO_THROW(result01.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK(result01.getMgmtCert().wireEncode() == ownerMgmtCert.wireEncode());
+
+
+  GetParam param02;
+  shared_ptr<Interest> interest02 = generateUnsignedInterest(param02, "non-existing");
+
+  face->sentDatas.clear();
+  face->receive(*interest02);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest02->getName()) == nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+
+  GetParam param03(TYPE_ID, testId);
+  shared_ptr<Interest> interest03 = generateUnsignedInterest(param03, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest03);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest03->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibIdentity result03;
+  BOOST_REQUIRE_NO_THROW(result03.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result03.getIdentity(), testId);
+
+
+  Name wrongId("/wrong/id");
+  GetParam param04(TYPE_ID, wrongId);
+  shared_ptr<Interest> interest04 = generateUnsignedInterest(param04, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest04);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest04->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result04;
+  BOOST_REQUIRE_NO_THROW(result04.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result04.getErrorCode(), ERR_NON_EXISTING_ID);
+
+
+  GetParam param05(TYPE_KEY, testIdKeyName1);
+  shared_ptr<Interest> interest05 = generateUnsignedInterest(param05, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest05);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest05->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibPublicKey result05;
+  BOOST_REQUIRE_NO_THROW(result05.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result05.getKeyName(), testIdKeyName1);
+
+
+  Name wrongKeyName1("/wrong/key/name1");
+  GetParam param06(TYPE_KEY, wrongKeyName1);
+  shared_ptr<Interest> interest06 = generateUnsignedInterest(param06, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest06);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest06->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result06;
+  BOOST_REQUIRE_NO_THROW(result06.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result06.getErrorCode(), ERR_NON_EXISTING_KEY);
+
+
+  GetParam param07(TYPE_CERT, testIdCertName00);
+  shared_ptr<Interest> interest07 = generateUnsignedInterest(param07, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest07);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest07->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibCertificate result07;
+  BOOST_REQUIRE_NO_THROW(result07.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result07.getCertificate().getName(), testIdCertName00);
+
+
+  Name wrongCertName1("/wrong/cert/name1");
+  GetParam param08(TYPE_CERT, wrongCertName1);
+  shared_ptr<Interest> interest08 = generateUnsignedInterest(param08, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest08);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest08->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result08;
+  BOOST_REQUIRE_NO_THROW(result08.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result08.getErrorCode(), ERR_NON_EXISTING_CERT);
+
+
+  Name wrongKeyName2;
+  GetParam param09(TYPE_KEY, wrongKeyName2);
+  shared_ptr<Interest> interest09 = generateUnsignedInterest(param09, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest09);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest09->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result09;
+  BOOST_REQUIRE_NO_THROW(result09.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result09.getErrorCode(), ERR_WRONG_PARAM);
+}
+
+BOOST_AUTO_TEST_CASE(DefaultCommandTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb db(tmpPath.string());
+
+  Name testId("/test/identity");
+  Name testIdCertName00 = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
+  Name testIdKeyName0 = cert00->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
+  Name testIdCertName01 = cert01->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName10 = cert10->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName11 = cert11->getName();
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+  db.addCertificate(*cert00);
+  db.addCertificate(*cert01);
+  db.addCertificate(*cert10);
+  db.addCertificate(*cert11);
+  db.setDefaultIdentity(testId);
+  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+  db.setDefaultCertNameOfKey(testIdCertName00);
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+  // Default Param
+  DefaultParam param11(TYPE_ID, TYPE_USER);
+  shared_ptr<Interest> interest11 = generateUnsignedInterest(param11, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest11);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest11->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibIdentity result11;
+  BOOST_REQUIRE_NO_THROW(result11.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result11.getIdentity(), testId);
+
+
+  DefaultParam param13(TYPE_ID, TYPE_ID);
+  shared_ptr<Interest> interest13 = generateUnsignedInterest(param13, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest13);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest13->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result13;
+  BOOST_REQUIRE_NO_THROW(result13.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result13.getErrorCode(), ERR_WRONG_PARAM);
+
+
+  DefaultParam param14(TYPE_KEY, TYPE_ID, testId);
+  shared_ptr<Interest> interest14 = generateUnsignedInterest(param14, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest14);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest14->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibPublicKey result14;
+  BOOST_REQUIRE_NO_THROW(result14.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result14.getKeyName(), testIdKeyName0);
+
+
+  DefaultParam param15(TYPE_CERT, TYPE_ID, testId);
+  shared_ptr<Interest> interest15 = generateUnsignedInterest(param15, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest15);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest15->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibCertificate result15;
+  BOOST_REQUIRE_NO_THROW(result15.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result15.getCertificate().getName(), testIdCertName00);
+
+
+  DefaultParam param16(TYPE_CERT, TYPE_USER);
+  shared_ptr<Interest> interest16 = generateUnsignedInterest(param16, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest16);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest16->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibCertificate result16;
+  BOOST_REQUIRE_NO_THROW(result16.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result16.getCertificate().getName(), testIdCertName00);
+
+
+  DefaultParam param17(TYPE_CERT, TYPE_KEY, testIdKeyName1);
+  shared_ptr<Interest> interest17 = generateUnsignedInterest(param17, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest17);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest17->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibCertificate result17;
+  BOOST_REQUIRE_NO_THROW(result17.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result17.getCertificate().getName(), testIdCertName10);
+}
+
+BOOST_AUTO_TEST_CASE(ListCommandTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb db(tmpPath.string());
+
+  Name testId("/test/identity");
+  Name testIdCertName00 = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
+  Name testIdKeyName0 = cert00->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
+  Name testIdCertName01 = cert01->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName10 = cert10->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName11 = cert11->getName();
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+  db.addCertificate(*cert00);
+  db.addCertificate(*cert01);
+  db.addCertificate(*cert10);
+  db.addCertificate(*cert11);
+  db.setDefaultIdentity(testId);
+  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+  db.setDefaultCertNameOfKey(testIdCertName00);
+
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+  Name wrongId("/wrong/id");
+
+  // List Param
+  ListParam param21;
+  shared_ptr<Interest> interest21 = generateUnsignedInterest(param21, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest21);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest21->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibNameList result21;
+  BOOST_REQUIRE_NO_THROW(result21.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result21.getNameList().size(), 1);
+
+
+  ListParam param22(TYPE_ID, testId);
+  shared_ptr<Interest> interest22 = generateUnsignedInterest(param22, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest22);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest22->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibNameList result22;
+  BOOST_REQUIRE_NO_THROW(result22.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result22.getNameList().size(), 2);
+
+
+  ListParam param23(TYPE_ID, wrongId);
+  shared_ptr<Interest> interest23 = generateUnsignedInterest(param23, owner);
+
+  face->sentDatas.clear();
+  face->receive(*interest23);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest23->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibNameList result23;
+  BOOST_REQUIRE_NO_THROW(result23.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result23.getNameList().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest1)
+{
+  // This test case is to check the access control of local management key
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+
+  UpdateQueryProcessor& pro = pib.m_updateProcessor;
+
+  Name target01("/localhost/pib");
+  Name target02("/localhost/pib/alice/mgmt");
+  Name target03("/localhost/pib/alice/mgmt/ok");
+  Name target04("/localhost/pib/alice");
+  Name target05("/test/id");
+  Name target06("/test/id/ksk-123");
+  Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
+  Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
+  Name signer02("/localhost/pib/bob/mgmt/KEY/ksk-1234/ID-CERT");
+
+  // TYPE_USER is handled separately, isUpdatedAllowed simply returns false
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_USER, target02, signer01, DEFAULT_OPT_NO), false);
+
+  // Test access control of local management key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target01, signer01, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target02, signer01, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target03, signer01, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target04, signer01, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer01, DEFAULT_OPT_NO), true);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer02, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer01, DEFAULT_OPT_NO), true);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer02, DEFAULT_OPT_NO), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer01, DEFAULT_OPT_NO), true);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer02, DEFAULT_OPT_NO), false);
+}
+
+BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest2)
+{
+  // This test case is to check the access control of regular key
+
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  PibDb db(tmpPath.string());
+
+  UpdateQueryProcessor& pro = pib.m_updateProcessor;
+
+  Name parent("/test");
+  addIdentity(parent);
+  Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
+  shared_ptr<IdentityCertificate> parentCert = m_keyChain.getCertificate(parentCertName);
+  Name parentSigner = parentCertName.getPrefix(-1);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
+  shared_ptr<IdentityCertificate> parentCert2 = m_keyChain.selfSign(parentKeyName2);
+  Name parentSigner2 = parentCert2->getName().getPrefix(-1);
+
+  db.addIdentity(parent);
+  db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
+  db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
+  db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
+  db.addCertificate(*parentCert);
+  db.setDefaultCertNameOfKey(parentCert->getName());
+  db.addCertificate(*parentCert2);
+  db.setDefaultCertNameOfKey(parentCert2->getName());
+
+  Name testId("/test/id");
+  addIdentity(testId);
+  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
+  shared_ptr<IdentityCertificate> testCert = m_keyChain.getCertificate(certName);
+  Name testKeyName = testCert->getPublicKeyName();
+  Name testSigner = certName.getPrefix(-1);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> secondCert = m_keyChain.selfSign(secondKeyName);
+  Name secondCertName = secondCert->getName();
+  Name secondSigner = secondCertName.getPrefix(-1);
+
+  db.addIdentity(testId);
+  db.addKey(testKeyName, testCert->getPublicKeyInfo());
+  db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
+  db.setDefaultKeyNameOfIdentity(testKeyName);
+  db.addCertificate(*testCert);
+  db.setDefaultCertNameOfKey(testCert->getName());
+  db.addCertificate(*secondCert);
+  db.setDefaultCertNameOfKey(secondCert->getName());
+
+  Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
+
+  // for target type = TYPE_ID
+  // one cannot add non-child
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, nonSigner, DEFAULT_OPT_NO), false);
+  // parent can add child
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_NO), true);
+  // non-default parent key cannot add a child
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner2, DEFAULT_OPT_NO), false);
+  // only DEFAULT_OPT_NO is allowed if target type is TYPE_ID
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_ID), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_KEY), false);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_USER), false);
+
+  // for target type = TYPE_KEY
+  // one can add its own key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_NO),
+                    true);
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, testSigner, DEFAULT_OPT_NO),
+                    true);
+  // one can set its default key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_ID),
+                    true);
+  // non-default key cannot add its own key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, secondSigner, DEFAULT_OPT_NO),
+                    false);
+  // non-default key cannot set its default key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, secondSigner, DEFAULT_OPT_ID),
+                    false);
+  // one can add its child's key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner, DEFAULT_OPT_NO),
+                    true);
+  // one can set its child's default key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner, DEFAULT_OPT_ID),
+                    true);
+  // non-default key cannot add its child's key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner2, DEFAULT_OPT_NO),
+                    false);
+  // non-default parent key cannot set its child's default key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner2, DEFAULT_OPT_ID),
+                    false);
+  // DEFAULT_OPT_KEY is not allowed if target type is TYPE_KEY
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_KEY),
+                    false);
+  // DEFAULT_OPT_USER is not allowed if signer is no local management key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_USER),
+                    false);
+
+  // for target type = TYPE_CERT
+  // one can add its own certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_NO),
+                    true);
+  // one can set its own default certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_ID),
+                    true);
+  // one can set its own key's default certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_KEY),
+                    true);
+  // DEFAULT_OPT_USER is not allowed if signer is no local management key
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_USER),
+                    false);
+  // non-default key can add other key's certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, secondSigner, DEFAULT_OPT_NO),
+                    false);
+  // non-default key can add its own certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_NO),
+                    true);
+  // one can add its child's certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner, DEFAULT_OPT_NO),
+                    true);
+  // non-default key cannot add its child's certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner2, DEFAULT_OPT_NO),
+                    false);
+  // non-default key cannot set add its identity default certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_ID),
+                    false);
+  // non-default key can set add its own default certificate
+  BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_KEY),
+                    true);
+}
+
+BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest1)
+{
+  // This test case is to check the access control of local management key
+
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+
+  DeleteQueryProcessor& pro = pib.m_deleteProcessor;
+
+  Name target01("/localhost/pib");
+  Name target02("/localhost/pib/alice/Mgmt");
+  Name target03("/localhost/pib/alice/Mgmt/ok");
+  Name target04("/localhost/pib/alice");
+  Name target05("/test/id");
+  Name target06("/test/id/ksk-123");
+  Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
+  Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
+  Name signer02("/localhost/pib/bob/Mgmt/KEY/ksk-1234/ID-CERT");
+
+  // TYPE_USER is handled separately
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_USER, target02, signer01), false);
+
+  // Test access control of local management key
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target01, signer01), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target02, signer01), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target03, signer01), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target04, signer01), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer01), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer01), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer01), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer02), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer02), false);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer02), false);
+}
+
+BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest2)
+{
+  // This test case is to check the access control of regular key
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  PibDb db(tmpPath.string());
+  DeleteQueryProcessor& pro = pib.m_deleteProcessor;
+
+  Name parent("/test");
+  addIdentity(parent);
+  Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
+  shared_ptr<IdentityCertificate> parentCert = m_keyChain.getCertificate(parentCertName);
+  Name parentSigner = parentCertName.getPrefix(-1);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
+  shared_ptr<IdentityCertificate> parentCert2 = m_keyChain.selfSign(parentKeyName2);
+  Name parentSigner2 = parentCert2->getName().getPrefix(-1);
+
+  db.addIdentity(parent);
+  db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
+  db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
+  db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
+  db.addCertificate(*parentCert);
+  db.setDefaultCertNameOfKey(parentCert->getName());
+  db.addCertificate(*parentCert2);
+  db.setDefaultCertNameOfKey(parentCert2->getName());
+
+  Name testId("/test/id");
+  addIdentity(testId);
+  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
+  shared_ptr<IdentityCertificate> testCert = m_keyChain.getCertificate(certName);
+  Name testKeyName = testCert->getPublicKeyName();
+  Name testSigner = certName.getPrefix(-1);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> secondCert = m_keyChain.selfSign(secondKeyName);
+  Name secondCertName = secondCert->getName();
+  Name secondSigner = secondCertName.getPrefix(-1);
+
+  db.addIdentity(testId);
+  db.addKey(testKeyName, testCert->getPublicKeyInfo());
+  db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
+  db.setDefaultKeyNameOfIdentity(testKeyName);
+  db.addCertificate(*testCert);
+  db.setDefaultCertNameOfKey(testCert->getName());
+  db.addCertificate(*secondCert);
+  db.setDefaultCertNameOfKey(secondCert->getName());
+
+  Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
+
+  // one can delete itself
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, testSigner), true);
+  // parent can delete its child
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner), true);
+  // non-default key cannot delete its identity
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, secondSigner), false);
+  // non-default key cannot delete its child
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner2), false);
+  // one cannot delete its parent
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, parent, testSigner), false);
+
+  // one can delete its own key
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, testSigner), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, testSigner), true);
+  // parent can delete its child's key
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, parentSigner), true);
+  // non-default key cannot delete other key
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, secondSigner), false);
+  // non-default key can delete itself
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, secondSigner), true);
+  // non-default key cannot delete its child's key
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner2), false);
+
+  // one can delete its own certificate
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, testSigner), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, testSigner), true);
+  // non-default key cannot delete other's certificate
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, secondSigner), false);
+  // non-default key can delete its own certificate
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, secondSigner), true);
+  // parent can delete its child's certificate
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner), true);
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, parentSigner), true);
+  // non-default parent cannot delete its child's certificate
+  BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner2), false);
+}
+
+
+BOOST_AUTO_TEST_CASE(UpdateUserTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+
+  m_keyChain.addCertificate(pib.getMgmtCert());
+
+  PibDb db(tmpPath.string());
+
+  Name bob("/localhost/pib/bob/mgmt");
+  addIdentity(bob);
+  Name bobCertName = m_keyChain.getDefaultCertificateNameForIdentity(bob);
+  shared_ptr<IdentityCertificate> bobCert = m_keyChain.getCertificate(bobCertName);
+
+  // signer is correct, but user name is wrong, should fall
+  PibUser pibUser1;
+  pibUser1.setMgmtCert(*bobCert);
+  UpdateParam param1(pibUser1);
+  auto interest1 = generateSignedInterest(param1, owner, db.getMgmtCertificate()->getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest1);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest1->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result;
+  BOOST_REQUIRE_NO_THROW(result.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
+
+  // user name is correct, but signer is wrong, should fail
+  PibUser pibUser2;
+  pibUser2.setMgmtCert(pib.getMgmtCert());
+  UpdateParam param2(pibUser2);
+  auto interest2 = generateSignedInterest(param2, owner, bobCertName);
+
+  face->sentDatas.clear();
+  face->receive(*interest2);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest2->getName()) == nullptr); // verification should fail, no response
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+  // update an existing user with a new mgmt key, signed by the old mgmt key.
+  advanceClocks(io, time::milliseconds(100));
+  Name ownerSecondKeyName =
+    m_keyChain.generateRsaKeyPair(Name("/localhost/pib/alice/mgmt"), false);
+  shared_ptr<IdentityCertificate> ownerSecondCert = m_keyChain.selfSign(ownerSecondKeyName);
+  m_keyChain.addCertificate(*ownerSecondCert);
+
+  PibUser pibUser3;
+  pibUser3.setMgmtCert(*ownerSecondCert);
+  UpdateParam param3(pibUser3);
+  auto interest3 = generateSignedInterest(param3, owner, db.getMgmtCertificate()->getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest3);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest3->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result3;
+  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK(db.getMgmtCertificate()->wireEncode() == ownerSecondCert->wireEncode());
+
+  // Add an cert and set it as user default cert.
+  Name testId("/test/id");
+  Name testIdCertName = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> testIdCert = m_keyChain.getCertificate(testIdCertName);
+  Name testIdKeyName = testIdCert->getPublicKeyName();
+  UpdateParam updateParam(*testIdCert, DEFAULT_OPT_USER);
+  auto interest4 = generateSignedInterest(updateParam, owner, ownerSecondCert->getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest4);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_REQUIRE(cache.find(interest4->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result4;
+  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+
+  BOOST_CHECK(pib.getDb().hasCertificate(testIdCertName));
+  BOOST_CHECK(pib.getDb().hasKey(testIdKeyName));
+  BOOST_CHECK(pib.getDb().hasIdentity(testId));
+
+  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultCertNameOfKey(testIdKeyName));
+  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultKeyNameOfIdentity(testId));
+  BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultIdentity());
+
+  BOOST_CHECK_EQUAL(pib.getDb().getDefaultCertNameOfKey(testIdKeyName), testIdCertName);
+  BOOST_CHECK_EQUAL(pib.getDb().getDefaultKeyNameOfIdentity(testId), testIdKeyName);
+  BOOST_CHECK_EQUAL(pib.getDb().getDefaultIdentity(), testId);
+}
+
+BOOST_AUTO_TEST_CASE(UpdateRegularKeyTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb db(tmpPath.string());
+
+  Name id0("/test/identity0");
+  Name certName000 = m_keyChain.createIdentity(id0);
+  shared_ptr<IdentityCertificate> cert000 = m_keyChain.getCertificate(certName000);
+  Name keyName00 = cert000->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert001 = m_keyChain.selfSign(keyName00);
+  Name certName001 = cert001->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName01 = m_keyChain.generateRsaKeyPair(id0);
+  shared_ptr<IdentityCertificate> cert010 = m_keyChain.selfSign(keyName01);
+  Name certName010 = cert010->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert011 = m_keyChain.selfSign(keyName01);
+  Name certName011 = cert011->getName();
+  m_keyChain.addCertificate(*cert010);
+
+  advanceClocks(io, time::milliseconds(100));
+  Name id1("/test/identity1");
+  Name certName100 = m_keyChain.createIdentity(id1);
+  shared_ptr<IdentityCertificate> cert100 = m_keyChain.getCertificate(certName100);
+  Name keyName10 = cert100->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert101 = m_keyChain.selfSign(keyName10);
+  Name certName101 = cert101->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName11 = m_keyChain.generateRsaKeyPair(id1);
+  shared_ptr<IdentityCertificate> cert110 = m_keyChain.selfSign(keyName11);
+  Name certName110 = cert110->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.selfSign(keyName11);
+  Name certName111 = cert111->getName();
+  m_keyChain.addCertificate(*cert111);
+
+
+  // Add a cert
+  BOOST_CHECK_EQUAL(db.hasIdentity(id0), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName00), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName000), false);
+  UpdateParam param1(*cert000);
+  auto interest1 = generateSignedInterest(param1, owner, ownerMgmtCert.getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest1);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result1;
+  BOOST_REQUIRE_NO_THROW(result1.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id0), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName00), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName000), true);
+
+  db.addCertificate(*cert100);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName10), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName100), true);
+
+  // Set default
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id0);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName00);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName00), certName000);
+
+  UpdateParam param2(id1, DEFAULT_OPT_USER);
+  auto interest2 = generateSignedInterest(param2, owner, ownerMgmtCert.getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest2);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result2;
+  BOOST_REQUIRE_NO_THROW(result2.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+
+  db.addCertificate(*cert010);
+  UpdateParam param3(keyName01, cert010->getPublicKeyInfo(), DEFAULT_OPT_ID);
+  auto interest3 = generateSignedInterest(param3, owner, ownerMgmtCert.getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest3);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result3;
+  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName01);
+
+  db.addCertificate(*cert011);
+  UpdateParam param4(*cert011, DEFAULT_OPT_KEY);
+  auto interest4 = generateSignedInterest(param4, owner, ownerMgmtCert.getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest4);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result4;
+  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName01), certName011);
+
+  // add key and certificate using regular keys.
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  UpdateParam param5(keyName11, cert110->getPublicKeyInfo());
+  auto interest5 = generateSignedInterest(param5, owner, cert100->getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest5);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest5->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result5;
+  BOOST_REQUIRE_NO_THROW(result5.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result5.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+
+  // add cert using its own key which has been added before
+  BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), false);
+  UpdateParam param6(*cert101);
+  auto interest6 = generateSignedInterest(param6, owner, cert100->getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest6);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest6->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result6;
+  BOOST_REQUIRE_NO_THROW(result6.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result6.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), true);
+}
+
+BOOST_AUTO_TEST_CASE(DeleteUserTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb db(tmpPath.string());
+
+  // Delete user should fail
+  DeleteParam param(Name(), TYPE_USER);
+  auto interest = generateSignedInterest(param, owner, ownerMgmtCert.getName());
+
+  face->receive(*interest);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result;
+  BOOST_REQUIRE_NO_THROW(result.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
+}
+
+BOOST_AUTO_TEST_CASE(DeleteRegularKeyTest)
+{
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+  advanceClocks(io, time::milliseconds(10), 10);
+  util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  PibDb& db = pib.getDb();
+
+  Name testId("/test/identity");
+  Name testIdCertName00 = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
+  Name testIdKeyName0 = cert00->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
+  Name testIdCertName01 = cert01->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName10 = cert10->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName11 = cert11->getName();
+  m_keyChain.addCertificate(*cert11);
+
+  db.addCertificate(*cert00);
+  db.addCertificate(*cert01);
+  db.addCertificate(*cert10);
+  db.addCertificate(*cert11);
+  db.setDefaultIdentity(testId);
+  db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+  db.setDefaultCertNameOfKey(testIdCertName00);
+  db.setDefaultCertNameOfKey(testIdCertName10);
+
+  // delete a certificate itself
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+  DeleteParam param1(testIdCertName11, TYPE_CERT);
+  auto interest1 = generateSignedInterest(param1, owner, testIdCertName11);
+
+  face->sentDatas.clear();
+  face->receive(*interest1);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result1;
+  BOOST_REQUIRE_NO_THROW(result1.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+  // delete a key itself
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+  DeleteParam param2(testIdKeyName1, TYPE_KEY);
+  auto interest2 = generateSignedInterest(param2, owner, testIdCertName11);
+
+  face->sentDatas.clear();
+  face->receive(*interest2);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result2;
+  BOOST_REQUIRE_NO_THROW(result2.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+
+  // delete an identity using non-default key, should fail
+  db.addCertificate(*cert11);
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+  DeleteParam param3(testId, TYPE_ID);
+  auto interest3 = generateSignedInterest(param3, owner, testIdCertName11);
+
+  face->sentDatas.clear();
+  face->receive(*interest3);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result3;
+  BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_WRONG_SIGNER);
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+
+  // delete an identity using identity default key, should succeed
+  DeleteParam param4(testId, TYPE_ID);
+  auto interest4 = generateSignedInterest(param4, owner, testIdCertName00);
+
+  face->sentDatas.clear();
+  face->receive(*interest4);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  PibError result4;
+  BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+  BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+  BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+}
+
+BOOST_AUTO_TEST_CASE(ReadCommandTest2)
+{
+  // Read Certificates;
+  owner = "alice";
+
+  Pib pib(*face,
+          tmpPath.string(),
+          m_keyChain.getTpm().getTpmLocator(),
+          owner);
+
+  advanceClocks(io, time::milliseconds(10), 100);
+  auto ownerMgmtCert = pib.getMgmtCert();
+  m_keyChain.addCertificate(ownerMgmtCert);
+
+  Name testId("/test/identity");
+  Name testIdCertName00 = m_keyChain.createIdentity(testId);
+  shared_ptr<IdentityCertificate> cert00 = m_keyChain.getCertificate(testIdCertName00);
+  Name testIdKeyName0 = cert00->getPublicKeyName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert01 = m_keyChain.selfSign(testIdKeyName0);
+  Name testIdCertName01 = cert01->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+  shared_ptr<IdentityCertificate> cert10 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName10 = cert10->getName();
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert11 = m_keyChain.selfSign(testIdKeyName1);
+  Name testIdCertName11 = cert11->getName();
+
+
+  UpdateParam param00(*cert00);
+  UpdateParam param01(*cert01);
+  UpdateParam param10(*cert10);
+  UpdateParam param11(*cert11);
+  auto interest00 = generateSignedInterest(param00, owner, ownerMgmtCert.getName());
+  auto interest01 = generateSignedInterest(param01, owner, ownerMgmtCert.getName());
+  auto interest10 = generateSignedInterest(param10, owner, ownerMgmtCert.getName());
+  auto interest11 = generateSignedInterest(param11, owner, ownerMgmtCert.getName());
+
+  face->sentDatas.clear();
+  face->receive(*interest00);
+  advanceClocks(io, time::milliseconds(10), 10);
+  face->receive(*interest01);
+  advanceClocks(io, time::milliseconds(10), 10);
+  face->receive(*interest10);
+  advanceClocks(io, time::milliseconds(10), 10);
+  face->receive(*interest11);
+  advanceClocks(io, time::milliseconds(10), 10);
+
+  auto interest1 = make_shared<Interest>(testIdCertName11);
+  face->sentDatas.clear();
+  face->receive(*interest1);
+  advanceClocks(io, time::milliseconds(10), 10);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert11->wireEncode());
+
+  auto interest2 = make_shared<Interest>(testIdCertName11.getPrefix(-1));
+  face->sentDatas.clear();
+  face->receive(*interest2);
+  advanceClocks(io, time::milliseconds(10), 10);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK_EQUAL(face->sentDatas[0].getName().getPrefix(-1),
+                    cert11->getName().getPrefix(-1));
+
+  auto interest3 = make_shared<Interest>(testIdCertName11.getPrefix(-1));
+  pib.getDb().deleteCertificate(testIdCertName11);
+  face->sentDatas.clear();
+  face->receive(*interest3);
+  advanceClocks(io, time::milliseconds(10), 10);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+  BOOST_CHECK(face->sentDatas[0].wireEncode() == cert10->wireEncode());
+
+  auto interest4 = make_shared<Interest>(testIdCertName11);
+  face->sentDatas.clear();
+  face->receive(*interest4);
+  advanceClocks(io, time::milliseconds(10), 10);
+  BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/response-cache.t.cpp b/tests/pib/response-cache.t.cpp
new file mode 100644
index 0000000..2653579
--- /dev/null
+++ b/tests/pib/response-cache.t.cpp
@@ -0,0 +1,64 @@
+/* -*- 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 "tools/pib/response-cache.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestResponseCache)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  ResponseCache cache;
+
+  Name dataName("/test/data");
+  dataName.appendVersion();
+  shared_ptr<Data> data = make_shared<Data>(dataName);
+
+  Name dataNameNoVersion("/test/data");
+  Name anotherDataName("/test/another");
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
+
+  cache.insert(*data);
+
+  BOOST_CHECK(static_cast<bool>(cache.find(dataNameNoVersion)));
+  BOOST_CHECK(static_cast<bool>(cache.find(dataName, true)));
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName)), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName, true)), false);
+
+  cache.erase(dataNameNoVersion);
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
+  BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/wscript b/tests/wscript
index c67d252..e44f2a4 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -10,4 +10,5 @@
         source=bld.path.ant_glob(['*.cpp'] + ['%s/**/*.cpp' % tool for tool in bld.env['BUILD_TOOLS']]),
         use=['core-objects'] + ['%s-objects' % tool for tool in bld.env['BUILD_TOOLS']],
         headers='../common.hpp boost-test.hpp',
+        defines='TMP_TESTS_PATH=\"%s/tmp-tests\"' % bld.bldnode,
         )
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',
+        )
