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