security: define new abstraction for identity, key, and certificate

Refs: #2451

Change-Id: I85dc7e0508bf10e2b73b0e9793dfc8e909e1a6e3
diff --git a/src/security/certificate-container.cpp b/src/security/certificate-container.cpp
new file mode 100644
index 0000000..b18bbcb
--- /dev/null
+++ b/src/security/certificate-container.cpp
@@ -0,0 +1,104 @@
+/* -*- 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 "certificate-container.hpp"
+#include "pib-impl.hpp"
+
+namespace ndn {
+namespace security {
+
+CertificateContainer::const_iterator::const_iterator(std::set<Name>::const_iterator it,
+                                                     shared_ptr<PibImpl> impl)
+  : m_it(it)
+  , m_impl(impl)
+{
+}
+
+IdentityCertificate
+CertificateContainer::const_iterator::operator*()
+{
+  return m_impl->getCertificate(*m_it);
+}
+
+CertificateContainer::const_iterator&
+CertificateContainer::const_iterator::operator++()
+{
+  ++m_it;
+  return *this;
+}
+
+CertificateContainer::const_iterator
+CertificateContainer::const_iterator::operator++(int)
+{
+  const_iterator it(m_it, m_impl);
+  ++m_it;
+  return it;
+}
+
+bool
+CertificateContainer::const_iterator::operator==(const const_iterator& other)
+{
+  return (m_impl == other.m_impl && m_it == other.m_it);
+}
+
+bool
+CertificateContainer::const_iterator::operator!=(const const_iterator& other)
+{
+  return !(*this == other);
+}
+
+CertificateContainer::CertificateContainer()
+{
+}
+
+CertificateContainer::CertificateContainer(std::set<Name>&& certNames,
+                                           shared_ptr<PibImpl> impl)
+  : m_certNames(certNames)
+  , m_impl(impl)
+{
+}
+
+CertificateContainer::const_iterator
+CertificateContainer::begin() const
+{
+  return const_iterator(m_certNames.begin(), m_impl);
+}
+
+CertificateContainer::const_iterator
+CertificateContainer::end() const
+{
+  return const_iterator(m_certNames.end(), m_impl);
+}
+
+CertificateContainer::const_iterator
+CertificateContainer::find(const Name& certName) const
+{
+  return const_iterator(m_certNames.find(certName), m_impl);
+}
+
+size_t
+CertificateContainer::size() const
+{
+  return m_certNames.size();
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/certificate-container.hpp b/src/security/certificate-container.hpp
new file mode 100644
index 0000000..1d7b6b4
--- /dev/null
+++ b/src/security/certificate-container.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_SECURITY_CERTIFICATE_CONTAINER_HPP
+#define NDN_SECURITY_CERTIFICATE_CONTAINER_HPP
+
+#include <set>
+#include "identity-certificate.hpp"
+
+namespace ndn {
+namespace security {
+
+class PibImpl;
+
+/// @brief A handler to search or enumerate certificates of a key.
+class CertificateContainer
+{
+public:
+  class const_iterator
+  {
+  public:
+    friend class CertificateContainer;
+
+  public:
+    IdentityCertificate
+    operator*();
+
+    const_iterator&
+    operator++();
+
+    const_iterator
+    operator++(int);
+
+    bool
+    operator==(const const_iterator& other);
+
+    bool
+    operator!=(const const_iterator& other);
+
+  private:
+    const_iterator(std::set<Name>::const_iterator it, shared_ptr<PibImpl> impl);
+
+  private:
+    std::set<Name>::const_iterator m_it;
+    shared_ptr<PibImpl> m_impl;
+  };
+
+  typedef const_iterator iterator;
+
+public:
+  CertificateContainer();
+
+  CertificateContainer(std::set<Name>&& certNames, shared_ptr<PibImpl> impl);
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  const_iterator
+  find(const Name& certName) const;
+
+  size_t
+  size() const;
+
+private:
+  std::set<Name> m_certNames;
+  shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_CERTIFICATE_CONTAINER_HPP
diff --git a/src/security/identity-container.cpp b/src/security/identity-container.cpp
new file mode 100644
index 0000000..756a75a
--- /dev/null
+++ b/src/security/identity-container.cpp
@@ -0,0 +1,104 @@
+/* -*- 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-container.hpp"
+#include "pib-impl.hpp"
+
+namespace ndn {
+namespace security {
+
+IdentityContainer::const_iterator::const_iterator(std::set<Name>::const_iterator it,
+                                                  shared_ptr<PibImpl> impl)
+  : m_it(it)
+  , m_impl(impl)
+{
+}
+
+Identity
+IdentityContainer::const_iterator::operator*()
+{
+  return Identity(*m_it, m_impl);
+}
+
+IdentityContainer::const_iterator&
+IdentityContainer::const_iterator::operator++()
+{
+  ++m_it;
+  return *this;
+}
+
+IdentityContainer::const_iterator
+IdentityContainer::const_iterator::operator++(int)
+{
+  const_iterator it(*this);
+  ++m_it;
+  return it;
+}
+
+bool
+IdentityContainer::const_iterator::operator==(const const_iterator& other)
+{
+  return (m_impl == other.m_impl && m_it == other.m_it);
+}
+
+bool
+IdentityContainer::const_iterator::operator!=(const const_iterator& other)
+{
+  return !(*this == other);
+}
+
+IdentityContainer::IdentityContainer()
+{
+}
+
+IdentityContainer::IdentityContainer(std::set<Name>&& identities,
+                                     shared_ptr<PibImpl> impl)
+  : m_identities(identities)
+  , m_impl(impl)
+{
+}
+
+IdentityContainer::const_iterator
+IdentityContainer::begin() const
+{
+  return const_iterator(m_identities.begin(), m_impl);
+}
+
+IdentityContainer::const_iterator
+IdentityContainer::end() const
+{
+  return const_iterator(m_identities.end(), m_impl);
+}
+
+IdentityContainer::const_iterator
+IdentityContainer::find(const Name& identity) const
+{
+  return const_iterator(m_identities.find(identity), m_impl);
+}
+
+size_t
+IdentityContainer::size() const
+{
+  return m_identities.size();
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/identity-container.hpp b/src/security/identity-container.hpp
new file mode 100644
index 0000000..dee80dd
--- /dev/null
+++ b/src/security/identity-container.hpp
@@ -0,0 +1,94 @@
+/* -*- 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_SECURITY_IDENTITY_CONTAINER_HPP
+#define NDN_SECURITY_IDENTITY_CONTAINER_HPP
+
+#include <set>
+#include "identity.hpp"
+
+namespace ndn {
+namespace security {
+
+class PibImpl;
+
+/// @brief A handler to search or enumerate identities in PIB.
+class IdentityContainer
+{
+public:
+  class const_iterator
+  {
+  public:
+    friend class IdentityContainer;
+
+  public:
+    Identity
+    operator*();
+
+    const_iterator&
+    operator++();
+
+    const_iterator
+    operator++(int);
+
+    bool
+    operator==(const const_iterator& other);
+
+    bool
+    operator!=(const const_iterator& other);
+
+  private:
+    const_iterator(std::set<Name>::const_iterator it, shared_ptr<PibImpl> impl);
+
+  private:
+    Name m_identity;
+    std::set<Name>::const_iterator m_it;
+    shared_ptr<PibImpl> m_impl;
+  };
+
+  typedef const_iterator iterator;
+
+public:
+  IdentityContainer();
+
+  IdentityContainer(std::set<Name>&& identities, shared_ptr<PibImpl> impl);
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  const_iterator
+  find(const Name& keyId) const;
+
+  size_t
+  size() const;
+
+private:
+  std::set<Name> m_identities;
+  shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_IDENTITY_CONTAINER_HPP
diff --git a/src/security/identity.cpp b/src/security/identity.cpp
new file mode 100644
index 0000000..7662a0a
--- /dev/null
+++ b/src/security/identity.cpp
@@ -0,0 +1,164 @@
+/* -*- 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.hpp"
+#include "pib-impl.hpp"
+#include "pib.hpp"
+
+namespace ndn {
+namespace security {
+
+const name::Component Identity::EMPTY_KEY_ID;
+
+Identity::Identity()
+  : m_hasDefaultKey(false)
+  , m_needRefreshKeys(false)
+  , m_impl(nullptr)
+{
+}
+
+Identity::Identity(const Name& identityName, shared_ptr<PibImpl> impl, bool needInit)
+  : m_name(identityName)
+  , m_hasDefaultKey(false)
+  , m_needRefreshKeys(true)
+  , m_impl(impl)
+{
+  validityCheck();
+
+  if (needInit)
+    m_impl->addIdentity(m_name);
+  else if (!m_impl->hasIdentity(m_name))
+    throw Pib::Error("Identity: " + m_name.toUri() + " does not exist");
+}
+
+const Name&
+Identity::getName() const
+{
+  validityCheck();
+
+  return m_name;
+}
+
+Key
+Identity::addKey(const PublicKey& publicKey, const name::Component& keyId)
+{
+  validityCheck();
+
+  name::Component actualKeyId = keyId;
+  if (actualKeyId == EMPTY_KEY_ID) {
+    const Block& digest = publicKey.computeDigest();
+    actualKeyId = name::Component(digest.wire(), digest.size());
+  }
+
+  if (!m_needRefreshKeys && m_keys.find(actualKeyId) == m_keys.end()) {
+    // if we have already loaded all the keys, but the new key is not one of them
+    // the KeyContainer should be refreshed
+    m_needRefreshKeys = true;
+  }
+
+  return Key(m_name, actualKeyId, publicKey, m_impl);
+}
+
+void
+Identity::removeKey(const name::Component& keyId)
+{
+  validityCheck();
+
+  if (m_hasDefaultKey && m_defaultKey.getKeyId() == keyId)
+    m_hasDefaultKey = false;
+
+  m_impl->removeKey(m_name, keyId);
+  m_needRefreshKeys = true;
+}
+
+Key
+Identity::getKey(const name::Component& keyId)
+{
+  validityCheck();
+
+  return Key(m_name, keyId, m_impl);
+}
+
+const KeyContainer&
+Identity::getKeys()
+{
+  validityCheck();
+
+  if (m_needRefreshKeys) {
+    m_keys = std::move(KeyContainer(m_name, m_impl->getKeysOfIdentity(m_name), m_impl));
+    m_needRefreshKeys = false;
+  }
+
+  return m_keys;
+}
+
+Key&
+Identity::setDefaultKey(const name::Component& keyId)
+{
+  validityCheck();
+
+  m_defaultKey = std::move(Key(m_name, keyId, m_impl));
+  m_hasDefaultKey = true;
+
+  m_impl->setDefaultKeyOfIdentity(m_name, keyId);
+  return m_defaultKey;
+}
+
+Key&
+Identity::setDefaultKey(const PublicKey& publicKey, const name::Component& keyId)
+{
+  const Key& keyEntry = addKey(publicKey, keyId);
+  return setDefaultKey(keyEntry.getKeyId());
+}
+
+Key&
+Identity::getDefaultKey()
+{
+  validityCheck();
+
+  if (!m_hasDefaultKey) {
+    m_defaultKey = std::move(Key(m_name, m_impl->getDefaultKeyOfIdentity(m_name), m_impl));
+    m_hasDefaultKey = true;
+  }
+
+  return m_defaultKey;
+}
+
+Identity::operator bool() const
+{
+  return !(this->operator!());
+}
+
+bool
+Identity::operator!() const
+{
+  return (m_impl == nullptr);
+}
+
+void
+Identity::validityCheck() const
+{
+  if (m_impl == nullptr)
+    throw std::domain_error("Invalid Identity instance");
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/identity.hpp b/src/security/identity.hpp
new file mode 100644
index 0000000..ecc42eb
--- /dev/null
+++ b/src/security/identity.hpp
@@ -0,0 +1,191 @@
+/* -*- 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_SECURITY_IDENTITY_HPP
+#define NDN_SECURITY_IDENTITY_HPP
+
+#include "key-container.hpp"
+
+namespace ndn {
+namespace security {
+
+class PibImpl;
+class Pib;
+class IdentityContainer;
+
+/**
+ * @brief represents an identity
+ *
+ * Identity is at the top level in PIB's Identity-Key-Certificate hierarchy.
+ * An identity has a Name, and contains one or more keys, one of which is set
+ * as the default key of this identity.  Properties of a key can be accessed
+ * after obtaining a Key object.
+ *
+ * @throw PibImpl::Error when underlying implementation has non-semantic error.
+ */
+class Identity
+{
+public:
+  friend class Pib;
+  friend class IdentityContainer;
+
+public:
+  /**
+   * @brief Default Constructor
+   *
+   * Identity created using this default constructor is just a place holder.
+   * It must obtain an actual instance from Pib::getIdentity(...).  A typical
+   * usage would be for exception handling:
+   *
+   *   Identity id;
+   *   try {
+   *     id = pib.getIdentity(...);
+   *   }
+   *   catch (Pib::Error&) {
+   *     ...
+   *   }
+   *
+   * An Identity instance created using the constructor is invalid. Calling a
+   * member method on an invalid Identity instance may cause an std::domain_error.
+   */
+  Identity();
+
+  /// @brief Get the name of the identity.
+  const Name&
+  getName() const;
+
+  /**
+   * @brief Add a key.
+   *
+   * If the key already exists, do nothing.
+   *
+   * If no default key is set before, the new key will be set as the default key of the identity.
+   *
+   * @param publicKey The public key to add.
+   * @param keyId The key id component of the new key to add.
+   *              By default, the keyId will be set to the hash of the public key bits.
+   * @return the added key or existing key with the same key id.
+   */
+  Key
+  addKey(const PublicKey& publicKey, const name::Component& keyId = EMPTY_KEY_ID);
+
+  /**
+   * @brief Remove a key.
+   *
+   * @param keyId The key id component of the key to delete.
+   */
+  void
+  removeKey(const name::Component& keyId);
+
+  /**
+   * @brief Get a key with id @keyId.
+   *
+   * @param identityName The name for the identity to get.
+   * @throw Pib::Error if the identity does not exist.
+   */
+  Key
+  getKey(const name::Component& keyId);
+
+  /// @brief Get all the keys for this Identity.
+  const KeyContainer&
+  getKeys();
+
+  /**
+   * @brief Set the key with id @p keyId as the default key.
+   *
+   * @param keyId The key id component of the default key.
+   * @return The default key
+   * @throws Pib::Error if the key does not exist.
+   */
+  Key&
+  setDefaultKey(const name::Component& keyId);
+
+  /**
+   * @brief Set the default key.
+   *
+   * If the key does not exist, add the key and set it as the default of the Identity.
+   * If the key exists, simply set it as the default key of the Identity.
+   *
+   * @param publicKey The public key to add.
+   * @param keyId The key id component of the default key.
+   * @return the default key
+   */
+  Key&
+  setDefaultKey(const PublicKey& publicKey, const name::Component& keyId = EMPTY_KEY_ID);
+
+  /**
+   * @brief Get the default key for this Identity.
+   *
+   * @throws Pib::Error if the default key does not exist.
+   */
+  Key&
+  getDefaultKey();
+
+  /// @brief Check if the Identity instance is valid
+  operator bool() const;
+
+  /// @brief Check if the Identity instance is invalid
+  bool
+  operator!() const;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Create an Identity with @p identityName.
+   *
+   * @param identityName The name of the Identity.
+   * @param impl The backend implementation.
+   * @param needInit If true, create the identity in backend when the identity does not exist.
+   *                 Otherwise, throw Pib::Error when the identity does not exist.
+   */
+  Identity(const Name& identityName, shared_ptr<PibImpl> impl, bool needInit = false);
+
+  /**
+   * @brief Check the validity of this instance
+   *
+   * @throws std::domain_error if the instance is invalid
+   */
+  void
+  validityCheck() const;
+
+public:
+  /**
+   * @brief The default value of keyId when add a new key.
+   *
+   * An empty keyId implies that the key digest should be used as the actual keyId.
+   */
+  static const name::Component EMPTY_KEY_ID;
+
+private:
+  Name m_name;
+
+  bool m_hasDefaultKey;
+  Key m_defaultKey;
+
+  bool m_needRefreshKeys;
+  KeyContainer m_keys;
+
+  shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_IDENTITY_HPP
diff --git a/src/security/key-container.cpp b/src/security/key-container.cpp
new file mode 100644
index 0000000..51ffac5
--- /dev/null
+++ b/src/security/key-container.cpp
@@ -0,0 +1,108 @@
+/* -*- 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 "key-container.hpp"
+#include "pib-impl.hpp"
+
+namespace ndn {
+namespace security {
+
+KeyContainer::const_iterator::const_iterator(const Name& identity,
+                                             std::set<name::Component>::const_iterator it,
+                                             shared_ptr<PibImpl> impl)
+  : m_identity(identity)
+  , m_it(it)
+  , m_impl(impl)
+{
+}
+
+Key
+KeyContainer::const_iterator::operator*()
+{
+  return Key(m_identity, *m_it, m_impl);
+}
+
+KeyContainer::const_iterator&
+KeyContainer::const_iterator::operator++()
+{
+  ++m_it;
+  return *this;
+}
+
+KeyContainer::const_iterator
+KeyContainer::const_iterator::operator++(int)
+{
+  const_iterator it(*this);
+  ++m_it;
+  return it;
+}
+
+bool
+KeyContainer::const_iterator::operator==(const const_iterator& other)
+{
+  return (m_impl == other.m_impl && m_identity == other.m_identity && m_it == other.m_it);
+}
+
+bool
+KeyContainer::const_iterator::operator!=(const const_iterator& other)
+{
+  return !(*this == other);
+}
+
+KeyContainer::KeyContainer()
+{
+}
+
+KeyContainer::KeyContainer(const Name& identity,
+                           std::set<name::Component>&& keyIds,
+                           shared_ptr<PibImpl> impl)
+  : m_identity(identity)
+  , m_keyIds(keyIds)
+  , m_impl(impl)
+{
+}
+
+KeyContainer::const_iterator
+KeyContainer::begin() const
+{
+  return const_iterator(m_identity, m_keyIds.begin(), m_impl);
+}
+
+KeyContainer::const_iterator
+KeyContainer::end() const
+{
+  return const_iterator(m_identity, m_keyIds.end(), m_impl);
+}
+
+KeyContainer::const_iterator
+KeyContainer::find(const name::Component& keyId) const
+{
+  return const_iterator(m_identity, m_keyIds.find(keyId), m_impl);
+}
+
+size_t
+KeyContainer::size() const
+{
+  return m_keyIds.size();
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/key-container.hpp b/src/security/key-container.hpp
new file mode 100644
index 0000000..9799d03
--- /dev/null
+++ b/src/security/key-container.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_SECURITY_KEY_CONTAINER_HPP
+#define NDN_SECURITY_KEY_CONTAINER_HPP
+
+#include <set>
+#include "key.hpp"
+
+namespace ndn {
+namespace security {
+
+class PibImpl;
+
+/// @brief A handler to search or enumerate keys of an identity.
+class KeyContainer
+{
+public:
+  class const_iterator
+  {
+  public:
+    friend class KeyContainer;
+
+  public:
+    Key
+    operator*();
+
+    const_iterator&
+    operator++();
+
+    const_iterator
+    operator++(int);
+
+    bool
+    operator==(const const_iterator& other);
+
+    bool
+    operator!=(const const_iterator& other);
+
+  private:
+    const_iterator(const Name& identity,
+                   std::set<name::Component>::const_iterator it,
+                   shared_ptr<PibImpl> impl);
+
+  private:
+    Name m_identity;
+    std::set<name::Component>::const_iterator m_it;
+    shared_ptr<PibImpl> m_impl;
+  };
+
+  typedef const_iterator iterator;
+
+public:
+  KeyContainer();
+
+  KeyContainer(const Name& identity,
+               std::set<name::Component>&& keyIds,
+               shared_ptr<PibImpl> impl);
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  const_iterator
+  find(const name::Component& keyId) const;
+
+  size_t
+  size() const;
+
+private:
+  Name m_identity;
+  std::set<name::Component> m_keyIds;
+  shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_KEY_CONTAINER_HPP
diff --git a/src/security/key.cpp b/src/security/key.cpp
new file mode 100644
index 0000000..d7a1a6f
--- /dev/null
+++ b/src/security/key.cpp
@@ -0,0 +1,201 @@
+/* -*- 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 "key.hpp"
+#include "pib-impl.hpp"
+#include "pib.hpp"
+
+namespace ndn {
+namespace security {
+
+Key::Key()
+  : m_hasDefaultCertificate(false)
+  , m_needRefreshCerts(false)
+  , m_impl(nullptr)
+{
+}
+
+Key::Key(const Name& identityName, const name::Component& keyId,
+         const PublicKey& publicKey, shared_ptr<PibImpl> impl)
+  : m_id(identityName)
+  , m_keyId(keyId)
+  , m_key(publicKey)
+  , m_hasDefaultCertificate(false)
+  , m_needRefreshCerts(true)
+  , m_impl(impl)
+{
+  validityCheck();
+
+  m_keyName = m_id;
+  m_keyName.append(m_keyId);
+
+  m_impl->addIdentity(m_id);
+  m_impl->addKey(m_id, m_keyId, publicKey);
+}
+
+Key::Key(const Name& identityName, const name::Component& keyId,
+         shared_ptr<PibImpl> impl)
+  : m_id(identityName)
+  , m_keyId(keyId)
+  , m_hasDefaultCertificate(false)
+  , m_needRefreshCerts(true)
+  , m_impl(impl)
+{
+  validityCheck();
+
+  m_keyName = m_id;
+  m_keyName.append(m_keyId);
+
+  m_key = m_impl->getKeyBits(m_id, m_keyId);
+}
+
+const Name&
+Key::getName() const
+{
+  validityCheck();
+
+  return m_keyName;
+}
+
+const Name&
+Key::getIdentity() const
+{
+  validityCheck();
+
+  return m_id;
+}
+
+const name::Component&
+Key::getKeyId() const
+{
+  validityCheck();
+
+  return m_keyId;
+}
+
+const PublicKey&
+Key::getPublicKey() const
+{
+  validityCheck();
+
+  return m_key;
+}
+
+void
+Key::addCertificate(const IdentityCertificate& certificate)
+{
+  validityCheck();
+
+  if (!m_needRefreshCerts &&
+      m_certificates.find(certificate.getName()) == m_certificates.end()) {
+    // if we have already loaded all the certificate, but the new certificate is not one of them
+    // the CertificateContainer should be refreshed
+    m_needRefreshCerts = true;
+  }
+
+  m_impl->addCertificate(certificate);
+}
+
+void
+Key::removeCertificate(const Name& certName)
+{
+  validityCheck();
+
+  if (m_hasDefaultCertificate && m_defaultCertificate.getName() == certName)
+    m_hasDefaultCertificate = false;
+
+  m_impl->removeCertificate(certName);
+  m_needRefreshCerts = true;
+}
+
+IdentityCertificate
+Key::getCertificate(const Name& certName)
+{
+  validityCheck();
+
+  return m_impl->getCertificate(certName);
+}
+
+CertificateContainer
+Key::getCertificates()
+{
+  validityCheck();
+
+  if (m_needRefreshCerts) {
+    m_certificates = std::move(CertificateContainer(m_impl->getCertificatesOfKey(m_id, m_keyId),
+                                                    m_impl));
+    m_needRefreshCerts = false;
+  }
+
+  return m_certificates;
+}
+
+const IdentityCertificate&
+Key::setDefaultCertificate(const Name& certName)
+{
+  validityCheck();
+
+  m_defaultCertificate = m_impl->getCertificate(certName);
+  m_impl->setDefaultCertificateOfKey(m_id, m_keyId, certName);
+  m_hasDefaultCertificate = true;
+  return m_defaultCertificate;
+}
+
+const IdentityCertificate&
+Key::setDefaultCertificate(const IdentityCertificate& certificate)
+{
+  addCertificate(certificate);
+  return setDefaultCertificate(certificate.getName());
+}
+
+const IdentityCertificate&
+Key::getDefaultCertificate()
+{
+  validityCheck();
+
+  if (!m_hasDefaultCertificate) {
+    m_defaultCertificate = m_impl->getDefaultCertificateOfKey(m_id, m_keyId);
+    m_hasDefaultCertificate = true;
+  }
+
+  return m_defaultCertificate;
+}
+
+Key::operator bool() const
+{
+  return !(this->operator!());
+}
+
+bool
+Key::operator!() const
+{
+  return (m_impl == nullptr);
+}
+
+void
+Key::validityCheck() const
+{
+  if (m_impl == nullptr)
+    throw std::domain_error("Invalid Key instance");
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/key.hpp b/src/security/key.hpp
new file mode 100644
index 0000000..b3e4f96
--- /dev/null
+++ b/src/security/key.hpp
@@ -0,0 +1,204 @@
+/* -*- 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_SECURITY_KEY_HPP
+#define NDN_SECURITY_KEY_HPP
+
+#include "identity-certificate.hpp"
+#include "certificate-container.hpp"
+
+namespace ndn {
+namespace security {
+
+class PibImpl;
+class Identity;
+class KeyContainer;
+
+/**
+ * @brief represents a key
+ *
+ * Key is at the second level in PIB's Identity-Key-Certificate hierarchy.
+ * An Key has a Name (identity + keyId), and contains one or more certificates,
+ * one of which is set as the default certificate of this key.  A certificate
+ * can be directly accessed from a Key object.
+ *
+ * @throw PibImpl::Error when underlying implementation has non-semantic error.
+ */
+class Key
+{
+public:
+  friend class Identity;
+  friend class KeyContainer;
+
+public:
+  /**
+   * @brief Default Constructor
+   *
+   * Key created using this default constructor is just a place holder.
+   * It must obtain an actual instance from Identity::getKey(...).  A typical
+   * usage would be for exception handling:
+   *
+   *   Key key;
+   *   try {
+   *     key = Identity.getKey(...);
+   *   }
+   *   catch (Pib::Error&) {
+   *     ...
+   *   }
+   *
+   * A Key instance created using the constructor is invalid. Calling a
+   * member method on an invalid Key instance may cause an std::domain_error.
+   */
+  Key();
+
+  /// @brief Get the name of the key.
+  const Name&
+  getName() const;
+
+  /// @brief Get the name of the belonging identity.
+  const Name&
+  getIdentity() const;
+
+  /// @brief Get the key id of the key.
+  const name::Component&
+  getKeyId() const;
+
+  /// @brief Get public key
+  const PublicKey&
+  getPublicKey() const;
+
+  /**
+   * @brief Add a certificate.
+   *
+   * @param certificate The certificate to add.
+   */
+  void
+  addCertificate(const IdentityCertificate& certificate);
+
+  /**
+   * @brief Remove a certificate.
+   *
+   * @param certName The name of the certificate to delete.
+   */
+  void
+  removeCertificate(const Name& certName);
+
+  /**
+   * @brief Get a certificate.
+   *
+   * @return the certificate
+   * @throws Pib::Error if the certificate does not exist.
+   */
+  IdentityCertificate
+  getCertificate(const Name& certName);
+
+  /// @brief Get all the certificates for this key.
+  CertificateContainer
+  getCertificates();
+
+  /**
+   * @brief Set the default certificate.
+   *
+   * @param certName The name of the default certificate of the key.
+   * @return the default certificate
+   * @throws Pib::Error if the certificate does not exist.
+   */
+  const IdentityCertificate&
+  setDefaultCertificate(const Name& certName);
+
+  /**
+   * @brief Set the default certificate.
+   *
+   * If the certificate does not exist, add it and set it as the default certificate of the key.
+   * If the certificate exists, simply set it as the default certificate of the key.
+   *
+   * @param certificate The certificate to add.
+   * @return the default certificate
+   */
+  const IdentityCertificate&
+  setDefaultCertificate(const IdentityCertificate& certificate);
+
+  /**
+   * @brief Get the default certificate for this Key.
+   *
+   * @throws Pib::Error if the default certificate does not exist.
+   */
+  const IdentityCertificate&
+  getDefaultCertificate();
+
+  /// @brief Check if the Key instance is valid
+  operator bool() const;
+
+  /// @brief Check if the Key instance is invalid
+  bool
+  operator!() const;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Create a Key with @p identityName and @p keyId.
+   *
+   * If the key/identity does not exist in the backend, create it in backend.
+   *
+   * @param identityName The name of the Identity.
+   * @param keyId The key id of the key.
+   * @param publicKey The public key to add.
+   * @param impl The actual backend implementation.
+   */
+  Key(const Name& identityName, const name::Component& keyId,
+      const PublicKey& publicKey, shared_ptr<PibImpl> impl);
+
+  /**
+   * @brief Create an KeyEntry with @p identityName and @p keyId.
+   *
+   * @param identityName The name of the Identity.
+   * @param keyId The key id of the key.
+   * @param impl The actual backend implementation.
+   * @throws Pib::Error if the key does not exist.
+   */
+  Key(const Name& identityName, const name::Component& keyId, shared_ptr<PibImpl> impl);
+
+  /**
+   * @brief Check the validity of this instance
+   *
+   * @throws std::domain_error if the instance is invalid
+   */
+  void
+  validityCheck() const;
+
+private:
+  Name m_id;
+  name::Component m_keyId;
+  Name m_keyName;
+  PublicKey m_key;
+
+  bool m_hasDefaultCertificate;
+  IdentityCertificate m_defaultCertificate;
+
+  bool m_needRefreshCerts;
+  CertificateContainer m_certificates;
+
+  shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_HPP
diff --git a/src/security/pib.cpp b/src/security/pib.cpp
new file mode 100644
index 0000000..28ca508
--- /dev/null
+++ b/src/security/pib.cpp
@@ -0,0 +1,96 @@
+/* -*- 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 "pib-impl.hpp"
+
+namespace ndn {
+namespace security {
+
+Pib::Pib(const std::string scheme, const std::string& location, shared_ptr<PibImpl> impl)
+  : m_scheme(scheme)
+  , m_location(location)
+  , m_impl(impl)
+{
+}
+
+Pib::~Pib()
+{
+}
+
+std::string
+Pib::getPibLocator() const
+{
+  return m_scheme + ":" + m_location;
+}
+
+void
+Pib::setTpmLocator(const std::string& tpmLocator)
+{
+  m_impl->setTpmLocator(tpmLocator);
+}
+
+std::string
+Pib::getTpmLocator() const
+{
+  return m_impl->getTpmLocator();
+}
+
+Identity
+Pib::addIdentity(const Name& identity)
+{
+  return Identity(identity, m_impl, true);
+}
+
+void
+Pib::removeIdentity(const Name& identity)
+{
+  m_impl->removeIdentity(identity);
+}
+
+Identity
+Pib::getIdentity(const Name& identity)
+{
+  return Identity(identity, m_impl, false);
+}
+
+IdentityContainer
+Pib::getIdentities() const
+{
+  return IdentityContainer(m_impl->getIdentities(), m_impl);
+}
+
+Identity
+Pib::setDefaultIdentity(const Name& identityName)
+{
+  m_impl->setDefaultIdentity(identityName);
+  return Identity(identityName, m_impl, true);
+}
+
+Identity
+Pib::getDefaultIdentity()
+{
+  return Identity(m_impl->getDefaultIdentity(), m_impl, false);
+}
+
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib.hpp b/src/security/pib.hpp
index e010177..fd8d7cb 100644
--- a/src/security/pib.hpp
+++ b/src/security/pib.hpp
@@ -22,11 +22,15 @@
 #ifndef NDN_SECURITY_PIB_HPP
 #define NDN_SECURITY_PIB_HPP
 
-#include "../common.hpp"
+#include "identity-container.hpp"
 
 namespace ndn {
+class KeyChain;
+
 namespace security {
 
+class PibImpl;
+
 /**
  * @brief represents the PIB
  *
@@ -45,6 +49,9 @@
 class Pib : noncopyable
 {
 public:
+  friend class KeyChain;
+
+public:
   /// @brief represents a semantic error
   class Error : public std::runtime_error
   {
@@ -56,7 +63,114 @@
     }
   };
 
-  //TODO: Add Pib interfaces
+public:
+
+  ~Pib();
+
+  /**
+   * @brief return the scheme of the PibLocator
+   */
+  std::string
+  getScheme() const
+  {
+    return m_scheme;
+  }
+
+  /**
+   * @brief Get PIB Locator
+   */
+  std::string
+  getPibLocator() const;
+
+  /**
+   * @brief Set the corresponding TPM information to @p tpmLocator.
+   *
+   * If the provided @p tpmLocator is different from the existing one, the
+   * PIB will be reset, otherwise nothing will be changed.
+   *
+   * @param tmpLocator The name for the new tmpLocator
+   */
+  void
+  setTpmLocator(const std::string& tpmLocator);
+
+  /**
+   * @brief Get TPM Locator
+   */
+  std::string
+  getTpmLocator() const;
+
+  /*
+   * @brief Create an identity with name @p identityName and return a reference to it.
+   *
+   * If there already exists an identity for the name @p identityName, then it is returned.
+   * If no default identity is set, the newly created identity will be set as the default.
+   *
+   * @param identityName The name for the identity to be added
+   */
+  Identity
+  addIdentity(const Name& identityName);
+
+  /*
+   * @brief Remove an identity with name @p identityName.
+   *
+   * @param identityName The name for the identity to be deleted
+   */
+  void
+  removeIdentity(const Name& identityName);
+
+  /**
+   * @brief Get an identity with name @p identityName.
+   *
+   * @param identityName The name for the identity to get.
+   * @throw Pib::Error if the identity does not exist.
+   */
+  Identity
+  getIdentity(const Name& identityName);
+
+  /// @brief Get all the identities
+  IdentityContainer
+  getIdentities() const;
+
+  /**
+   * @brief Set an identity with name @p identityName as the default identity.
+   *
+   * Also create the identity if it does not exist.
+   *
+   * @param identityName The name for the default identity.
+   * @return the default identity
+   */
+  Identity
+  setDefaultIdentity(const Name& identityName);
+
+  /**
+   * @brief Get the default identity.
+   *
+   * @return the default identity.
+   * @throws Pib::Error if no default identity.
+   */
+  Identity
+  getDefaultIdentity();
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /*
+   * @brief Create a new Pib with the specified @p location
+   *
+   * @param scheme The scheme for the Pib
+   * @param location The location for the Pib
+   * @param impl The backend implementation
+   */
+  Pib(const std::string scheme, const std::string& location, shared_ptr<PibImpl> impl);
+
+  shared_ptr<PibImpl>
+  getImpl()
+  {
+    return m_impl;
+  }
+
+protected:
+  std::string m_scheme;
+  std::string m_location;
+  shared_ptr<PibImpl> m_impl;
 };
 
 } // namespace security
diff --git a/tests/unit-tests/security/certificate-container.t.cpp b/tests/unit-tests/security/certificate-container.t.cpp
new file mode 100644
index 0000000..496d950
--- /dev/null
+++ b/tests/unit-tests/security/certificate-container.t.cpp
@@ -0,0 +1,78 @@
+/* -*- 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 "security/certificate-container.hpp"
+#include "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityCertificateContainer)
+
+BOOST_FIXTURE_TEST_CASE(TestCertificateContainer, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  Pib pib("pib-memory", "", pibImpl);
+
+  Identity identity1 = pib.addIdentity(id1);
+  Key key11 = identity1.addKey(id1Key1, id1Key1Name.get(-1));
+  key11.addCertificate(id1Key1Cert1);
+  key11.addCertificate(id1Key1Cert2);
+
+  CertificateContainer container = key11.getCertificates();
+  BOOST_CHECK_EQUAL(container.size(), 2);
+  BOOST_CHECK(container.find(id1Key1Cert1.getName()) != container.end());
+  BOOST_CHECK(container.find(id1Key1Cert2.getName()) != container.end());
+
+  std::set<Name> certNames;
+  certNames.insert(id1Key1Cert1.getName());
+  certNames.insert(id1Key1Cert2.getName());
+
+  CertificateContainer::const_iterator it = container.begin();
+  std::set<Name>::const_iterator testIt = certNames.begin();
+  BOOST_CHECK_EQUAL((*it).getName(), *testIt);
+  it++;
+  testIt++;
+  BOOST_CHECK_EQUAL((*it).getName(), *testIt);
+  ++it;
+  testIt++;
+  BOOST_CHECK(it == container.end());
+
+  size_t count = 0;
+  testIt = certNames.begin();
+  for (const auto& cert : container) {
+    BOOST_CHECK_EQUAL(cert.getName(), *testIt);
+    testIt++;
+    count++;
+  }
+  BOOST_CHECK_EQUAL(count, 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/identity-container.t.cpp b/tests/unit-tests/security/identity-container.t.cpp
new file mode 100644
index 0000000..cdcc024
--- /dev/null
+++ b/tests/unit-tests/security/identity-container.t.cpp
@@ -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.
+ */
+
+#include "security/identity-container.hpp"
+#include "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityIdentityContainer)
+
+BOOST_FIXTURE_TEST_CASE(TestIdentityContainer, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  Pib pib("pib-memory", "", pibImpl);
+
+  Identity identity1 = pib.addIdentity(id1);
+  Identity identity2 = pib.addIdentity(id2);
+
+  IdentityContainer container = pib.getIdentities();
+  BOOST_CHECK_EQUAL(container.size(), 2);
+  BOOST_CHECK(container.find(id1) != container.end());
+  BOOST_CHECK(container.find(id2) != container.end());
+
+  std::set<Name> idNames;
+  idNames.insert(id1);
+  idNames.insert(id2);
+
+  IdentityContainer::const_iterator it = container.begin();
+  std::set<Name>::const_iterator testIt = idNames.begin();
+  BOOST_CHECK_EQUAL((*it).getName(), *testIt);
+  it++;
+  testIt++;
+  BOOST_CHECK_EQUAL((*it).getName(), *testIt);
+  ++it;
+  testIt++;
+  BOOST_CHECK(it == container.end());
+
+  size_t count = 0;
+  testIt = idNames.begin();
+  for (const auto& identity : container) {
+    BOOST_CHECK_EQUAL(identity.getName(), *testIt);
+    testIt++;
+    count++;
+  }
+  BOOST_CHECK_EQUAL(count, 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/identity.t.cpp b/tests/unit-tests/security/identity.t.cpp
new file mode 100644
index 0000000..c55c00f
--- /dev/null
+++ b/tests/unit-tests/security/identity.t.cpp
@@ -0,0 +1,86 @@
+/* -*- 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 "security/identity.hpp"
+#include "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityIdentity)
+
+BOOST_FIXTURE_TEST_CASE(ValidityChecking, PibDataFixture)
+{
+  // identity
+  Identity id;
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(id), false);
+  BOOST_CHECK_EQUAL(!id, true);
+
+  if (id)
+    BOOST_CHECK(false);
+  else
+    BOOST_CHECK(true);
+
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  id = Identity(id1, pibImpl, true);
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(id), true);
+  BOOST_CHECK_EQUAL(!id, false);
+
+  if (id)
+    BOOST_CHECK(true);
+  else
+    BOOST_CHECK(false);
+}
+
+BOOST_FIXTURE_TEST_CASE(TestKeyOperation, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+
+  Identity identity1(id1, pibImpl, true);
+
+  BOOST_CHECK_THROW(identity1.getKey(id1Key1Name.get(-1)), Pib::Error);
+  Key key11 = identity1.addKey(id1Key1, id1Key1Name.get(-1));
+  BOOST_CHECK_NO_THROW(identity1.getKey(id1Key1Name.get(-1)));
+  identity1.removeKey(id1Key1Name.get(-1));
+  BOOST_CHECK_THROW(identity1.getKey(id1Key1Name.get(-1)), Pib::Error);
+
+  BOOST_CHECK_THROW(identity1.getDefaultKey(), Pib::Error);
+  BOOST_REQUIRE_THROW(identity1.setDefaultKey(id1Key1Name.get(-1)), Pib::Error);
+  BOOST_REQUIRE_NO_THROW(identity1.setDefaultKey(id1Key1, id1Key1Name.get(-1)));
+  BOOST_REQUIRE_NO_THROW(identity1.getDefaultKey());
+  BOOST_CHECK_EQUAL(identity1.getDefaultKey().getKeyId(), id1Key1Name.get(-1));
+  identity1.removeKey(id1Key1Name.get(-1));
+  BOOST_CHECK_THROW(identity1.getKey(id1Key1Name.get(-1)), Pib::Error);
+  BOOST_CHECK_THROW(identity1.getDefaultKey(), Pib::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/key-container.t.cpp b/tests/unit-tests/security/key-container.t.cpp
new file mode 100644
index 0000000..99f6285
--- /dev/null
+++ b/tests/unit-tests/security/key-container.t.cpp
@@ -0,0 +1,79 @@
+/* -*- 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 "security/key-container.hpp"
+#include "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityKeyContainer)
+
+BOOST_FIXTURE_TEST_CASE(TestKeyContainer, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  Pib pib("pib-memory", "", pibImpl);
+
+  Identity identity1 = pib.addIdentity(id1);
+
+  Key key11 = identity1.addKey(id1Key1, id1Key1Name.get(-1));
+  Key key12 = identity1.addKey(id1Key2, id1Key2Name.get(-1));
+
+  KeyContainer container = identity1.getKeys();
+  BOOST_CHECK_EQUAL(container.size(), 2);
+  BOOST_CHECK(container.find(id1Key1Name.get(-1)) != container.end());
+  BOOST_CHECK(container.find(id1Key2Name.get(-1)) != container.end());
+
+  std::set<name::Component> keyNames;
+  keyNames.insert(id1Key1Name.get(-1));
+  keyNames.insert(id1Key2Name.get(-1));
+
+  KeyContainer::const_iterator it = container.begin();
+  std::set<name::Component>::const_iterator testIt = keyNames.begin();
+  BOOST_CHECK_EQUAL((*it).getKeyId(), *testIt);
+  it++;
+  testIt++;
+  BOOST_CHECK_EQUAL((*it).getKeyId(), *testIt);
+  ++it;
+  testIt++;
+  BOOST_CHECK(it == container.end());
+
+  size_t count = 0;
+  testIt = keyNames.begin();
+  for (const auto& key : container) {
+    BOOST_CHECK_EQUAL(key.getIdentity(), id1);
+    BOOST_CHECK_EQUAL(key.getKeyId(), *testIt);
+    testIt++;
+    count++;
+  }
+  BOOST_CHECK_EQUAL(count, 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/key.t.cpp b/tests/unit-tests/security/key.t.cpp
new file mode 100644
index 0000000..3d3c4e3
--- /dev/null
+++ b/tests/unit-tests/security/key.t.cpp
@@ -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.
+ */
+
+#include "security/key.hpp"
+#include "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityKey)
+
+BOOST_FIXTURE_TEST_CASE(ValidityChecking, PibDataFixture)
+{
+  // key
+  Key key;
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(key), false);
+  BOOST_CHECK_EQUAL(!key, true);
+
+  if (key)
+    BOOST_CHECK(false);
+  else
+    BOOST_CHECK(true);
+
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  key = Key(id1, id1Key1Name.get(-1), id1Key1, pibImpl);
+
+  BOOST_CHECK_EQUAL(static_cast<bool>(key), true);
+  BOOST_CHECK_EQUAL(!key, false);
+
+  if (key)
+    BOOST_CHECK(true);
+  else
+    BOOST_CHECK(false);
+}
+
+BOOST_FIXTURE_TEST_CASE(TestCertificateOperation, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+
+  Key key11(id1, id1Key1Name.get(-1), id1Key1, pibImpl);
+
+  BOOST_CHECK_THROW(key11.getCertificate(id1Key1Cert1.getName()), Pib::Error);
+  key11.addCertificate(id1Key1Cert1);
+  BOOST_CHECK_NO_THROW(key11.getCertificate(id1Key1Cert1.getName()));
+  key11.removeCertificate(id1Key1Cert1.getName());
+  BOOST_CHECK_THROW(key11.getCertificate(id1Key1Cert1.getName()), Pib::Error);
+
+  BOOST_CHECK_THROW(key11.getDefaultCertificate(), Pib::Error);
+  BOOST_REQUIRE_THROW(key11.setDefaultCertificate(id1Key1Cert1.getName()), Pib::Error);
+  BOOST_REQUIRE_NO_THROW(key11.setDefaultCertificate(id1Key1Cert1));
+  BOOST_REQUIRE_NO_THROW(key11.getDefaultCertificate());
+
+  const IdentityCertificate& defaultCert = key11.getDefaultCertificate();
+  BOOST_CHECK_EQUAL_COLLECTIONS(defaultCert.wireEncode().wire(),
+                                defaultCert.wireEncode().wire() + defaultCert.wireEncode().size(),
+                                id1Key1Cert1.wireEncode().wire(),
+                                id1Key1Cert1.wireEncode().wire() + id1Key1Cert1.wireEncode().size());
+
+  key11.removeCertificate(id1Key1Cert1.getName());
+  BOOST_CHECK_THROW(key11.getCertificate(id1Key1Cert1.getName()), Pib::Error);
+  BOOST_CHECK_THROW(key11.getDefaultCertificate(), Pib::Error);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
diff --git a/tests/unit-tests/security/pib.t.cpp b/tests/unit-tests/security/pib.t.cpp
new file mode 100644
index 0000000..5210df6
--- /dev/null
+++ b/tests/unit-tests/security/pib.t.cpp
@@ -0,0 +1,85 @@
+/* -*- 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 "security/pib.hpp"
+#include "security/in-memory-pib-impl.hpp"
+#include "pib-data-fixture.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SecurityPib)
+
+BOOST_FIXTURE_TEST_CASE(ValidityChecking, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  Pib pib("pib-memory", "", pibImpl);
+
+  Identity id = pib.addIdentity(id1);
+
+  BOOST_CHECK_EQUAL(bool(id), true);
+  BOOST_CHECK_EQUAL(!id, false);
+
+  if (id)
+    BOOST_CHECK(true);
+  else
+    BOOST_CHECK(false);
+
+  // key
+  Key key = id.addKey(id1Key1, id1Key1Name.get(-1));
+
+  BOOST_CHECK_EQUAL(bool(key), true);
+  BOOST_CHECK_EQUAL(!key, false);
+
+  if (key)
+    BOOST_CHECK(true);
+  else
+    BOOST_CHECK(false);
+}
+
+BOOST_FIXTURE_TEST_CASE(TestIdentityOperation, PibDataFixture)
+{
+  auto pibImpl = make_shared<InMemoryPibImpl>();
+  Pib pib("pib-memory", "", pibImpl);
+
+  BOOST_CHECK_THROW(pib.getIdentity(id1), Pib::Error);
+  Identity identity1 = pib.addIdentity(id1);
+  BOOST_CHECK_NO_THROW(pib.getIdentity(id1));
+  pib.removeIdentity(id1);
+  BOOST_CHECK_THROW(pib.getIdentity(id1), Pib::Error);
+
+  BOOST_CHECK_THROW(pib.getDefaultIdentity(), Pib::Error);
+  BOOST_REQUIRE_NO_THROW(pib.setDefaultIdentity(id1));
+  BOOST_REQUIRE_NO_THROW(pib.getDefaultIdentity());
+  BOOST_CHECK_EQUAL(pib.getDefaultIdentity().getName(), id1);
+  pib.removeIdentity(id1);
+  BOOST_CHECK_THROW(pib.getIdentity(id1), Pib::Error);
+  BOOST_CHECK_THROW(pib.getDefaultIdentity(), Pib::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace security
+} // namespace ndn