security: Move PIB-related code into security/pib/
Change-Id: I94ea7ce646e66382f7c534ca1c8d6cbeeb87b1a4
diff --git a/src/security/pib/certificate-container.cpp b/src/security/pib/certificate-container.cpp
new file mode 100644
index 0000000..a05dd52
--- /dev/null
+++ b/src/security/pib/certificate-container.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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)
+{
+}
+
+v1::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/pib/certificate-container.hpp b/src/security/pib/certificate-container.hpp
new file mode 100644
index 0000000..8e77e43
--- /dev/null
+++ b/src/security/pib/certificate-container.hpp
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_CERTIFICATE_CONTAINER_HPP
+#define NDN_SECURITY_PIB_CERTIFICATE_CONTAINER_HPP
+
+#include <set>
+#include "../v1/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:
+ v1::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_PIB_CERTIFICATE_CONTAINER_HPP
diff --git a/src/security/pib/identity-container.cpp b/src/security/pib/identity-container.cpp
new file mode 100644
index 0000000..605be8b
--- /dev/null
+++ b/src/security/pib/identity-container.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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/pib/identity-container.hpp b/src/security/pib/identity-container.hpp
new file mode 100644
index 0000000..1de18c7
--- /dev/null
+++ b/src/security/pib/identity-container.hpp
@@ -0,0 +1,94 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_IDENTITY_CONTAINER_HPP
+#define NDN_SECURITY_PIB_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_PIB_IDENTITY_CONTAINER_HPP
diff --git a/src/security/pib/identity.cpp b/src/security/pib/identity.cpp
new file mode 100644
index 0000000..176814c
--- /dev/null
+++ b/src/security/pib/identity.cpp
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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))
+ BOOST_THROW_EXCEPTION(Pib::Error("Identity: " + m_name.toUri() + " does not exist"));
+}
+
+const Name&
+Identity::getName() const
+{
+ validityCheck();
+
+ return m_name;
+}
+
+Key
+Identity::addKey(const v1::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) const
+{
+ validityCheck();
+
+ return Key(m_name, keyId, m_impl);
+}
+
+const KeyContainer&
+Identity::getKeys() const
+{
+ validityCheck();
+
+ if (m_needRefreshKeys) {
+ m_keys = 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 = Key(m_name, keyId, m_impl);
+ m_hasDefaultKey = true;
+
+ m_impl->setDefaultKeyOfIdentity(m_name, keyId);
+ return m_defaultKey;
+}
+
+Key&
+Identity::setDefaultKey(const v1::PublicKey& publicKey, const name::Component& keyId)
+{
+ const Key& keyEntry = addKey(publicKey, keyId);
+ return setDefaultKey(keyEntry.getKeyId());
+}
+
+Key&
+Identity::getDefaultKey() const
+{
+ validityCheck();
+
+ if (!m_hasDefaultKey) {
+ m_defaultKey = 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)
+ BOOST_THROW_EXCEPTION(std::domain_error("Invalid Identity instance"));
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib/identity.hpp b/src/security/pib/identity.hpp
new file mode 100644
index 0000000..3c081ef
--- /dev/null
+++ b/src/security/pib/identity.hpp
@@ -0,0 +1,194 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_IDENTITY_HPP
+#define NDN_SECURITY_PIB_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;
+ friend class KeyChain;
+
+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 Get a key with id @p keyId.
+ *
+ * @param keyId The id of the key to get.
+ * @throw Pib::Error if the key does not exist.
+ */
+ Key
+ getKey(const name::Component& keyId) const;
+
+ /// @brief Get all the keys for this Identity.
+ const KeyContainer&
+ getKeys() const;
+
+ /**
+ * @brief Get the default key for this Identity.
+ *
+ * @throws Pib::Error if the default key does not exist.
+ */
+ Key&
+ getDefaultKey() const;
+
+ /// @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: // write operations should be private
+
+ /**
+ * @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 v1::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 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 v1::PublicKey& publicKey, const name::Component& keyId = EMPTY_KEY_ID);
+
+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;
+
+ mutable bool m_hasDefaultKey;
+ mutable Key m_defaultKey;
+
+ mutable bool m_needRefreshKeys;
+ mutable KeyContainer m_keys;
+
+ shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_IDENTITY_HPP
diff --git a/src/security/pib/key-container.cpp b/src/security/pib/key-container.cpp
new file mode 100644
index 0000000..ca30ab9
--- /dev/null
+++ b/src/security/pib/key-container.cpp
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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/pib/key-container.hpp b/src/security/pib/key-container.hpp
new file mode 100644
index 0000000..7d88da9
--- /dev/null
+++ b/src/security/pib/key-container.hpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_KEY_CONTAINER_HPP
+#define NDN_SECURITY_PIB_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_PIB_KEY_CONTAINER_HPP
diff --git a/src/security/pib/key.cpp b/src/security/pib/key.cpp
new file mode 100644
index 0000000..c59a39d
--- /dev/null
+++ b/src/security/pib/key.cpp
@@ -0,0 +1,200 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 v1::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 v1::PublicKey&
+Key::getPublicKey() const
+{
+ validityCheck();
+
+ return m_key;
+}
+
+void
+Key::addCertificate(const v1::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;
+}
+
+v1::IdentityCertificate
+Key::getCertificate(const Name& certName) const
+{
+ validityCheck();
+
+ return m_impl->getCertificate(certName);
+}
+
+const CertificateContainer&
+Key::getCertificates() const
+{
+ validityCheck();
+
+ if (m_needRefreshCerts) {
+ m_certificates = CertificateContainer(m_impl->getCertificatesOfKey(m_id, m_keyId), m_impl);
+ m_needRefreshCerts = false;
+ }
+
+ return m_certificates;
+}
+
+const v1::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 v1::IdentityCertificate&
+Key::setDefaultCertificate(const v1::IdentityCertificate& certificate)
+{
+ addCertificate(certificate);
+ return setDefaultCertificate(certificate.getName());
+}
+
+const v1::IdentityCertificate&
+Key::getDefaultCertificate() const
+{
+ 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)
+ BOOST_THROW_EXCEPTION(std::domain_error("Invalid Key instance"));
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib/key.hpp b/src/security/pib/key.hpp
new file mode 100644
index 0000000..7118149
--- /dev/null
+++ b/src/security/pib/key.hpp
@@ -0,0 +1,207 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_KEY_HPP
+#define NDN_SECURITY_PIB_KEY_HPP
+
+#include "../v1/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;
+ friend class KeyChain;
+
+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 v1::PublicKey&
+ getPublicKey() const;
+
+ /**
+ * @brief Get a certificate.
+ *
+ * @return the certificate
+ * @throws Pib::Error if the certificate does not exist.
+ */
+ v1::IdentityCertificate
+ getCertificate(const Name& certName) const;
+
+ /// @brief Get all the certificates for this key.
+ const CertificateContainer&
+ getCertificates() const;
+
+ /**
+ * @brief Get the default certificate for this Key.
+ *
+ * @throws Pib::Error if the default certificate does not exist.
+ */
+ const v1::IdentityCertificate&
+ getDefaultCertificate() const;
+
+ /// @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: // write operations should be private
+
+ /**
+ * @brief Add a certificate.
+ *
+ * @param certificate The certificate to add.
+ */
+ void
+ addCertificate(const v1::IdentityCertificate& certificate);
+
+ /**
+ * @brief Remove a certificate.
+ *
+ * @param certName The name of the certificate to delete.
+ */
+ void
+ removeCertificate(const Name& certName);
+
+ /**
+ * @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 v1::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 v1::IdentityCertificate&
+ setDefaultCertificate(const v1::IdentityCertificate& certificate);
+
+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 v1::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;
+ v1::PublicKey m_key;
+
+ mutable bool m_hasDefaultCertificate;
+ mutable v1::IdentityCertificate m_defaultCertificate;
+
+ mutable bool m_needRefreshCerts;
+ mutable CertificateContainer m_certificates;
+
+ shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_PIB_HPP
diff --git a/src/security/pib/pib-impl.hpp b/src/security/pib/pib-impl.hpp
new file mode 100644
index 0000000..7aa47a2
--- /dev/null
+++ b/src/security/pib/pib-impl.hpp
@@ -0,0 +1,304 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_PIB_IMPL_HPP
+#define NDN_SECURITY_PIB_PIB_IMPL_HPP
+
+#include <set>
+#include "../v1/identity-certificate.hpp"
+
+namespace ndn {
+namespace security {
+
+/**
+ * @brief Abstract class of PIB implementation
+ *
+ * This class defines the interface that an actual PIB (e.g., one based on sqlite3)
+ * implementation should provide.
+ */
+class PibImpl
+{
+public:
+ /**
+ * @brief represents a non-semantic error
+ *
+ * A subclass of PibImpl may throw a subclass of this type when
+ * there's a non-semantic error, such as a storage problem.
+ */
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+public:
+
+ virtual
+ ~PibImpl()
+ {
+ }
+
+public: // TpmLocator management
+
+ /**
+ * @brief Set the corresponding TPM information to @p tpmLocator.
+ *
+ * If the provided @p tpmLocator is different from the existing one, the
+ * content in PIB will be cleaned up, otherwise nothing will be changed.
+ *
+ * @param tpmLocator The name for the new TPM locator
+ */
+ virtual void
+ setTpmLocator(const std::string& tpmLocator) = 0;
+
+ /**
+ * @brief Get TPM Locator
+ */
+ virtual std::string
+ getTpmLocator() const = 0;
+
+public: // Identity management
+
+ /**
+ * @brief Check the existence of an identity.
+ *
+ * @param identity The name of the identity.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ hasIdentity(const Name& identity) const = 0;
+
+ /**
+ * @brief Add an identity.
+ *
+ * If the identity already exists, do nothing.
+ * If no default identity has been set, set the added one as default identity.
+ *
+ * @param identity The name of the identity to add.
+ */
+ virtual void
+ addIdentity(const Name& identity) = 0;
+
+ /**
+ * @brief Remove an identity
+ *
+ * If the identity does not exist, do nothing.
+ * Remove related keys and certificates as well.
+ *
+ * @param identity The name of the identity to remove.
+ */
+ virtual void
+ removeIdentity(const Name& identity) = 0;
+
+ /// @brief Get the name of all the identities
+ virtual std::set<Name>
+ getIdentities() const = 0;
+
+ /**
+ * @brief Set an identity with name @p identityName as the default identity.
+ *
+ * Since adding an identity only requires the identity name, create the
+ * identity if it does not exist.
+ *
+ * @param identityName The name for the default identity.
+ */
+ virtual void
+ setDefaultIdentity(const Name& identityName) = 0;
+
+ /**
+ * @brief Get the default identity.
+ *
+ * @return The name for the default identity.
+ * @throws Pib::Error if no default identity.
+ */
+ virtual Name
+ getDefaultIdentity() const = 0;
+
+public: // Key management
+
+ /**
+ * @brief Check the existence of a key.
+ *
+ * @param identity The name of the belonged identity.
+ * @param keyId The key id component.
+ * @return true if the key exists, otherwise false. Return false if the identity does not exist
+ */
+ virtual bool
+ hasKey(const Name& identity, const name::Component& keyId) const = 0;
+
+ /**
+ * @brief Add a key.
+ *
+ * If the key already exists, do nothing.
+ * If the identity does not exist, add the identity as well.
+ * If no default key of the identity has been set, set the added one as default
+ * key of the identity.
+ *
+ * @param identity The name of the belonged identity.
+ * @param keyId The key id component.
+ * @param publicKey The public key bits.
+ */
+ virtual void
+ addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey) = 0;
+
+ /**
+ * @brief Remove a key.
+ *
+ * If the key does not exist, do nothing.
+ * Remove related certificates as well.
+ *
+ * @param identity The name of the belonged identity.
+ * @param keyId The key id component.
+ */
+ virtual void
+ removeKey(const Name& identity, const name::Component& keyId) = 0;
+
+ /**
+ * @brief Get the key bits of a key.
+ *
+ * @param identity The name of the belonged identity.
+ * @param keyId The key id component.
+ * @return key bits
+ * @throws Pib::Error if the key does not exist.
+ */
+ virtual v1::PublicKey
+ getKeyBits(const Name& identity, const name::Component& keyId) const = 0;
+
+ /**
+ * @brief Get all the key ids of an identity with name @p identity
+ *
+ * The returned key ids can be used to create a KeyContainer.
+ * With key id, identity name, backend implementation, one can create a Key frontend instance.
+ *
+ * @return the key id name component set. If the identity does not exist, return an empty set.
+ */
+ virtual std::set<name::Component>
+ getKeysOfIdentity(const Name& identity) const = 0;
+
+ /**
+ * @brief Set an key with id @p keyId as the default key of an identity with name @p identity.
+ *
+ * @param identity The name of the belonged identity.
+ * @param keyId The key id component.
+ * @throws Pib::Error if the key does not exist.
+ */
+ virtual void
+ setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId) = 0;
+
+ /**
+ * @brief Get the id of the default key of an identity with name @p identity.
+ *
+ * @param identity The name of the belonged identity.
+ * @throws Pib::Error if no default key or the identity does not exist.
+ */
+ virtual name::Component
+ getDefaultKeyOfIdentity(const Name& identity) const = 0;
+
+public: // Certificate Management
+
+ /**
+ * @brief Check the existence of a certificate with name @p certName.
+ *
+ * @param certName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ hasCertificate(const Name& certName) const = 0;
+
+ /**
+ * @brief Add a certificate.
+ *
+ * If the certificate already exists, do nothing.
+ * If the key or identity do not exist, add them as well.
+ * If no default certificate of the key has been set, set the added one as
+ * default certificate of the key.
+ *
+ * @param certificate The certificate to add.
+ */
+ virtual void
+ addCertificate(const v1::IdentityCertificate& certificate) = 0;
+
+ /**
+ * @brief Remove a certificate with name @p certName.
+ *
+ * If the certificate does not exist, do nothing.
+ *
+ * @param certName The name of the certificate.
+ */
+ virtual void
+ removeCertificate(const Name& certName) = 0;
+
+ /**
+ * @brief Get a certificate with name @p certName.
+ *
+ * @param certName The name of the certificate.
+ * @return the certificate.
+ * @throws Pib::Error if the certificate does not exist.
+ */
+ virtual v1::IdentityCertificate
+ getCertificate(const Name& certName) const = 0;
+
+ /**
+ * @brief Get a list of certificate names of a key with id @p keyId of @p identity.
+ *
+ * The returned certificate names can be used to create a CertificateContainer.
+ * With certificate name and backend implementation, one can obtain the certificate directly.
+ *
+ * @param identity The name of the belonging identity.
+ * @param keyId The key id.
+ * @return The certificate name set. If the key does not exist, return an empty set.
+ */
+ virtual std::set<Name>
+ getCertificatesOfKey(const Name& identity, const name::Component& keyId) const = 0;
+
+ /**
+ * @brief Set a cert with name @p certName as the default of a key with id @p keyId of @p identity.
+ *
+ * @param identity The name of the belonging identity.
+ * @param keyId The key id.
+ * @param certName The name of the certificate.
+ * @throws Pib::Error if the certificate with name @p certName does not exist.
+ */
+ virtual void
+ setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId,
+ const Name& certName) = 0;
+
+ /**
+ * @brief Get the default certificate of a key with id @p keyId of @p identity.
+ *
+ * @param identity The name of the belonging identity.
+ * @param keyId The key id.
+ * @return a pointer to the certificate, null if no default certificate for the key.
+ * @throws Pib::Error if the default certificate does not exist.
+ */
+ virtual v1::IdentityCertificate
+ getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const = 0;
+
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_PIB_IMPL_HPP
diff --git a/src/security/pib/pib-memory.cpp b/src/security/pib/pib-memory.cpp
new file mode 100644
index 0000000..c472863
--- /dev/null
+++ b/src/security/pib/pib-memory.cpp
@@ -0,0 +1,257 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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-memory.hpp"
+#include "pib.hpp"
+
+namespace ndn {
+namespace security {
+
+PibMemory::PibMemory()
+ : m_hasDefaultIdentity(false)
+{
+}
+
+void
+PibMemory::setTpmLocator(const std::string& tpmLocator)
+{
+ BOOST_THROW_EXCEPTION(Error("PibMemory does not need a locator"));
+}
+
+std::string
+PibMemory::getTpmLocator() const
+{
+ return "tpm-memory:";
+}
+
+bool
+PibMemory::hasIdentity(const Name& identity) const
+{
+ return (m_identities.count(identity) > 0);
+}
+
+void
+PibMemory::addIdentity(const Name& identity)
+{
+ m_identities.insert(identity);
+
+ if (!m_hasDefaultIdentity) {
+ m_defaultIdentity = identity;
+ m_hasDefaultIdentity = true;
+ }
+}
+
+void
+PibMemory::removeIdentity(const Name& identity)
+{
+ m_identities.erase(identity);
+ if (identity == m_defaultIdentity)
+ m_hasDefaultIdentity = false;
+
+ auto keyIds = this->getKeysOfIdentity(identity);
+ for (const name::Component& keyId : keyIds) {
+ this->removeKey(identity, keyId);
+ }
+}
+
+std::set<Name>
+PibMemory::getIdentities() const
+{
+ return m_identities;
+}
+
+void
+PibMemory::setDefaultIdentity(const Name& identityName)
+{
+ addIdentity(identityName);
+ m_defaultIdentity = identityName;
+ m_hasDefaultIdentity = true;
+}
+
+Name
+PibMemory::getDefaultIdentity() const
+{
+ if (m_hasDefaultIdentity)
+ return m_defaultIdentity;
+
+ BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
+}
+
+bool
+PibMemory::hasKey(const Name& identity, const name::Component& keyId) const
+{
+ return (m_keys.count(getKeyName(identity, keyId)) > 0);
+}
+
+void
+PibMemory::addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey)
+{
+ this->addIdentity(identity);
+
+ Name keyName = getKeyName(identity, keyId);
+ m_keys[keyName] = publicKey;
+
+ if (m_defaultKey.find(identity) == m_defaultKey.end())
+ m_defaultKey[identity] = keyName;
+}
+
+void
+PibMemory::removeKey(const Name& identity, const name::Component& keyId)
+{
+ Name keyName = getKeyName(identity, keyId);
+ m_keys.erase(keyName);
+ m_defaultKey.erase(identity);
+
+
+ auto certNames = this->getCertificatesOfKey(identity, keyId);
+ for (const auto& certName : certNames) {
+ this->removeCertificate(certName);
+ }
+}
+
+v1::PublicKey
+PibMemory::getKeyBits(const Name& identity, const name::Component& keyId) const
+{
+ if (!hasKey(identity, keyId))
+ BOOST_THROW_EXCEPTION(Pib::Error("No key"));
+
+ auto it = m_keys.find(getKeyName(identity, keyId));
+ return it->second;
+}
+
+std::set<name::Component>
+PibMemory::getKeysOfIdentity(const Name& identity) const
+{
+ std::set<name::Component> ids;
+ for (const auto& it : m_keys) {
+ if (identity == it.first.getPrefix(-1))
+ ids.insert(it.first.get(-1));
+ }
+ return ids;
+}
+
+void
+PibMemory::setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId)
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ if (!hasKey(identity, keyId))
+ BOOST_THROW_EXCEPTION(Pib::Error("No key"));
+
+ m_defaultKey[identity] = keyName;
+}
+
+name::Component
+PibMemory::getDefaultKeyOfIdentity(const Name& identity) const
+{
+ auto it = m_defaultKey.find(identity);
+ if (it == m_defaultKey.end())
+ BOOST_THROW_EXCEPTION(Pib::Error("No default key"));
+
+ return it->second.get(-1);
+}
+
+Name
+PibMemory::getKeyName(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = identity;
+ keyName.append(keyId);
+ return keyName;
+}
+
+bool
+PibMemory::hasCertificate(const Name& certName) const
+{
+ return (m_certs.count(certName) > 0);
+}
+
+void
+PibMemory::addCertificate(const v1::IdentityCertificate& certificate)
+{
+ this->addKey(certificate.getPublicKeyName().getPrefix(-1),
+ certificate.getPublicKeyName().get(-1),
+ certificate.getPublicKeyInfo());
+
+ m_certs[certificate.getName()] = certificate;
+
+ const Name& keyName = certificate.getPublicKeyName();
+ if (m_defaultCert.find(keyName) == m_defaultCert.end())
+ m_defaultCert[keyName] = certificate.getName();
+}
+
+void
+PibMemory::removeCertificate(const Name& certName)
+{
+ m_certs.erase(certName);
+ m_defaultCert.erase(v1::IdentityCertificate::certificateNameToPublicKeyName(certName));
+}
+
+v1::IdentityCertificate
+PibMemory::getCertificate(const Name& certName) const
+{
+ if (!hasCertificate(certName))
+ BOOST_THROW_EXCEPTION(Pib::Error("No cert"));
+
+ auto it = m_certs.find(certName);
+ return it->second;
+}
+
+std::set<Name>
+PibMemory::getCertificatesOfKey(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ std::set<Name> certNames;
+ for (const auto& it : m_certs) {
+ if (it.second.getPublicKeyName() == keyName)
+ certNames.insert(it.first);
+ }
+ return certNames;
+}
+
+void
+PibMemory::setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId, const Name& certName)
+{
+ if (!hasCertificate(certName))
+ BOOST_THROW_EXCEPTION(Pib::Error("No cert"));
+
+ Name keyName = getKeyName(identity, keyId);
+ m_defaultCert[keyName] = certName;
+}
+
+v1::IdentityCertificate
+PibMemory::getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ auto it = m_defaultCert.find(keyName);
+ if (it == m_defaultCert.end())
+ BOOST_THROW_EXCEPTION(Pib::Error("No default certificate"));
+
+ auto certIt = m_certs.find(it->second);
+ if (certIt == m_certs.end())
+ BOOST_THROW_EXCEPTION(Pib::Error("No default certificate"));
+ else
+ return certIt->second;
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib/pib-memory.hpp b/src/security/pib/pib-memory.hpp
new file mode 100644
index 0000000..0cfe7c1
--- /dev/null
+++ b/src/security/pib/pib-memory.hpp
@@ -0,0 +1,153 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_PIB_MEMORY_HPP
+#define NDN_SECURITY_PIB_PIB_MEMORY_HPP
+
+#include "pib-impl.hpp"
+
+namespace ndn {
+namespace security {
+
+/**
+ * @brief An in-memory implementation of Pib
+ *
+ * All the contents in Pib are stored in memory
+ * and have the same lifetime as the implementation instance.
+ */
+class PibMemory : public PibImpl
+{
+public:
+ class Error : public PibImpl::Error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : PibImpl::Error(what)
+ {
+ }
+ };
+
+public:
+ PibMemory();
+
+public: // TpmLocator management
+
+ void
+ setTpmLocator(const std::string& tpmLocator) override;
+
+ std::string
+ getTpmLocator() const override;
+
+public: // Identity management
+
+ bool
+ hasIdentity(const Name& identity) const override;
+
+ void
+ addIdentity(const Name& identity) override;
+
+ void
+ removeIdentity(const Name& identity) override;
+
+ std::set<Name>
+ getIdentities() const override;
+
+ void
+ setDefaultIdentity(const Name& identityName) override;
+
+ Name
+ getDefaultIdentity() const override;
+
+public: // Key management
+
+ bool
+ hasKey(const Name& identity, const name::Component& keyId) const override;
+
+ void
+ addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey) override;
+
+ void
+ removeKey(const Name& identity, const name::Component& keyId) override;
+
+ v1::PublicKey
+ getKeyBits(const Name& identity, const name::Component& keyId) const override;
+
+ std::set<name::Component>
+ getKeysOfIdentity(const Name& identity) const override;
+
+ void
+ setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId) override;
+
+ name::Component
+ getDefaultKeyOfIdentity(const Name& identity) const override;
+
+public: // Certificate management
+
+ bool
+ hasCertificate(const Name& certName) const override;
+
+ void
+ addCertificate(const v1::IdentityCertificate& certificate) override;
+
+ void
+ removeCertificate(const Name& certName) override;
+
+ v1::IdentityCertificate
+ getCertificate(const Name& certName) const override;
+
+ std::set<Name>
+ getCertificatesOfKey(const Name& identity, const name::Component& keyId) const override;
+
+ void
+ setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId, const Name& certName) override;
+
+ v1::IdentityCertificate
+ getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const override;
+
+private: // Key management
+
+ Name
+ getKeyName(const Name& identity, const name::Component& keyId) const;
+
+private:
+
+ std::set<Name> m_identities;
+ bool m_hasDefaultIdentity;
+ Name m_defaultIdentity;
+
+ /// @brief keyName => keyBits
+ std::map<Name, v1::PublicKey> m_keys;
+
+ /// @brief identity => default key Name
+ std::map<Name, Name> m_defaultKey;
+
+ /// @brief certificate Name => certificate
+ std::map<Name, v1::IdentityCertificate> m_certs;
+
+ /// @brief keyName => default certificate Name
+ std::map<Name, Name> m_defaultCert;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_PIB_MEMORY_HPP
diff --git a/src/security/pib/pib-sqlite3.cpp b/src/security/pib/pib-sqlite3.cpp
new file mode 100644
index 0000000..dc21610
--- /dev/null
+++ b/src/security/pib/pib-sqlite3.cpp
@@ -0,0 +1,565 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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-sqlite3.hpp"
+
+#include "common.hpp"
+#include "pib.hpp"
+#include "util/sqlite3-statement.hpp"
+
+#include <sqlite3.h>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
+
+namespace ndn {
+namespace security {
+
+using std::string;
+using util::Sqlite3Statement;
+
+static const string INITIALIZATION =
+ "CREATE TABLE IF NOT EXISTS \n"
+ " tpmInfo( \n"
+ " tpm_locator BLOB \n"
+ " ); \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " tpm_update_trigger \n"
+ " BEFORE UPDATE ON tpmInfo \n"
+ " WHEN NEW.tpm_locator!=OLD.tpm_locator \n"
+ " BEGIN \n"
+ " DELETE FROM certificates; \n"
+ " DELETE FROM keys; \n"
+ " DELETE FROM identities; \n"
+ " END; \n"
+ " \n"
+ " \n"
+ "CREATE TABLE IF NOT EXISTS \n"
+ " identities( \n"
+ " id INTEGER PRIMARY KEY,\n"
+ " identity BLOB NOT NULL, \n"
+ " is_default INTEGER DEFAULT 0 \n"
+ " ); \n"
+ " \n"
+ "CREATE UNIQUE INDEX IF NOT EXISTS \n"
+ " identityIndex ON identities(identity); \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " identity_default_before_insert_trigger \n"
+ " BEFORE INSERT ON identities \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 \n"
+ " BEGIN \n"
+ " UPDATE identities SET is_default=0; \n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " identity_default_after_insert_trigger \n"
+ " AFTER INSERT ON identities \n"
+ " FOR EACH ROW \n"
+ " WHEN NOT EXISTS \n"
+ " (SELECT id \n"
+ " FROM identities \n"
+ " WHERE is_default=1) \n"
+ " BEGIN \n"
+ " UPDATE identities \n"
+ " SET is_default=1 \n"
+ " WHERE identity=NEW.identity; \n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " identity_default_update_trigger \n"
+ " BEFORE UPDATE ON identities \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
+ " BEGIN \n"
+ " UPDATE identities SET is_default=0; \n"
+ " END; \n"
+ " \n"
+ " \n"
+ "CREATE TABLE IF NOT EXISTS \n"
+ " keys( \n"
+ " id INTEGER PRIMARY KEY,\n"
+ " identity_id INTEGER NOT NULL, \n"
+ " key_name BLOB NOT NULL, \n"
+ " key_type INTEGER NOT NULL, \n"
+ " key_bits BLOB NOT NULL, \n"
+ " is_default INTEGER DEFAULT 0, \n"
+ " FOREIGN KEY(identity_id) \n"
+ " REFERENCES identities(id) \n"
+ " ON DELETE CASCADE \n"
+ " ON UPDATE CASCADE \n"
+ " ); \n"
+ " \n"
+ "CREATE UNIQUE INDEX IF NOT EXISTS \n"
+ " keyIndex ON keys(key_name); \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " key_default_before_insert_trigger \n"
+ " BEFORE INSERT ON keys \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 \n"
+ " BEGIN \n"
+ " UPDATE keys \n"
+ " SET is_default=0 \n"
+ " WHERE identity_id=NEW.identity_id; \n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " key_default_after_insert_trigger \n"
+ " AFTER INSERT ON keys \n"
+ " FOR EACH ROW \n"
+ " WHEN NOT EXISTS \n"
+ " (SELECT id \n"
+ " FROM keys \n"
+ " WHERE is_default=1 \n"
+ " AND identity_id=NEW.identity_id) \n"
+ " BEGIN \n"
+ " UPDATE keys \n"
+ " SET is_default=1 \n"
+ " WHERE key_name=NEW.key_name; \n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " key_default_update_trigger \n"
+ " BEFORE UPDATE ON keys \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
+ " BEGIN \n"
+ " UPDATE keys \n"
+ " SET is_default=0 \n"
+ " WHERE identity_id=NEW.identity_id; \n"
+ " END; \n"
+ " \n"
+ " \n"
+ "CREATE TABLE IF NOT EXISTS \n"
+ " certificates( \n"
+ " id INTEGER PRIMARY KEY,\n"
+ " key_id INTEGER NOT NULL, \n"
+ " certificate_name BLOB NOT NULL, \n"
+ " certificate_data BLOB NOT NULL, \n"
+ " is_default INTEGER DEFAULT 0, \n"
+ " FOREIGN KEY(key_id) \n"
+ " REFERENCES keys(id) \n"
+ " ON DELETE CASCADE \n"
+ " ON UPDATE CASCADE \n"
+ " ); \n"
+ " \n"
+ "CREATE UNIQUE INDEX IF NOT EXISTS \n"
+ " certIndex ON certificates(certificate_name);\n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " cert_default_before_insert_trigger \n"
+ " BEFORE INSERT ON certificates \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 \n"
+ " BEGIN \n"
+ " UPDATE certificates \n"
+ " SET is_default=0 \n"
+ " WHERE key_id=NEW.key_id; \n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " cert_default_after_insert_trigger \n"
+ " AFTER INSERT ON certificates \n"
+ " FOR EACH ROW \n"
+ " WHEN NOT EXISTS \n"
+ " (SELECT id \n"
+ " FROM certificates \n"
+ " WHERE is_default=1 \n"
+ " AND key_id=NEW.key_id) \n"
+ " BEGIN \n"
+ " UPDATE certificates \n"
+ " SET is_default=1 \n"
+ " WHERE certificate_name=NEW.certificate_name;\n"
+ " END; \n"
+ " \n"
+ "CREATE TRIGGER IF NOT EXISTS \n"
+ " cert_default_update_trigger \n"
+ " BEFORE UPDATE ON certificates \n"
+ " FOR EACH ROW \n"
+ " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
+ " BEGIN \n"
+ " UPDATE certificates \n"
+ " SET is_default=0 \n"
+ " WHERE key_id=NEW.key_id; \n"
+ " END; \n";
+
+static Name
+getKeyName(const Name& identity, const name::Component& keyId)
+{
+ Name keyName = identity;
+ keyName.append(keyId);
+ return keyName;
+}
+
+PibSqlite3::PibSqlite3(const string& dir)
+{
+ // Determine the path of PIB DB
+ boost::filesystem::path actualDir;
+ if (dir == "") {
+#ifdef NDN_CXX_HAVE_TESTS
+ if (getenv("TEST_HOME") != nullptr) {
+ actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
+ }
+ else
+#endif // NDN_CXX_HAVE_TESTS
+ if (getenv("HOME") != nullptr) {
+ actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
+ }
+ else {
+ actualDir = boost::filesystem::path(".") / ".ndn";
+ }
+ }
+ else {
+ actualDir = boost::filesystem::path(dir);
+ }
+ boost::filesystem::create_directories(actualDir);
+
+ // Open PIB
+ int result = sqlite3_open_v2((actualDir / "pib.db").c_str(), &m_database,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
+ "unix-dotfile"
+#else
+ nullptr
+#endif
+ );
+
+ if (result != SQLITE_OK)
+ BOOST_THROW_EXCEPTION(PibImpl::Error("PIB DB cannot be opened/created: " + dir));
+
+
+ // enable foreign key
+ sqlite3_exec(m_database, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
+
+ // initialize PIB tables
+ char* errorMessage = nullptr;
+ result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
+ if (result != SQLITE_OK && errorMessage != nullptr) {
+ sqlite3_free(errorMessage);
+ BOOST_THROW_EXCEPTION(PibImpl::Error("PIB DB cannot be initialized"));
+ }
+}
+
+PibSqlite3::~PibSqlite3()
+{
+ sqlite3_close(m_database);
+}
+
+void
+PibSqlite3::setTpmLocator(const std::string& tpmLocator)
+{
+ Sqlite3Statement statement(m_database, "UPDATE tpmInfo SET tpm_locator=?");
+ statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
+ statement.step();
+
+ // no row is updated, tpm_locator does not exist, insert it directly
+ if (0 == sqlite3_changes(m_database)) {
+ Sqlite3Statement insertStatement(m_database, "INSERT INTO tpmInfo (tpm_locator) values (?)");
+ insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
+ insertStatement.step();
+ }
+}
+
+std::string
+PibSqlite3::getTpmLocator() const
+{
+ Sqlite3Statement statement(m_database, "SELECT tpm_locator FROM tpmInfo");
+ int res = statement.step();
+
+ string tpmLocator;
+ if (res == SQLITE_ROW)
+ return statement.getString(0);
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("TPM info does not exist"));
+}
+
+bool
+PibSqlite3::hasIdentity(const Name& identity) const
+{
+ Sqlite3Statement statement(m_database, "SELECT id FROM identities WHERE identity=?");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+ return (statement.step() == SQLITE_ROW);
+}
+
+void
+PibSqlite3::addIdentity(const Name& identity)
+{
+ Sqlite3Statement statement(m_database, "INSERT INTO identities (identity) values (?)");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+void
+PibSqlite3::removeIdentity(const Name& identity)
+{
+ Sqlite3Statement statement(m_database, "DELETE FROM identities WHERE identity=?");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+std::set<Name>
+PibSqlite3::getIdentities() const
+{
+ std::set<Name> identities;
+ Sqlite3Statement statement(m_database, "SELECT identity FROM identities");
+
+ while (statement.step() == SQLITE_ROW)
+ identities.insert(Name(statement.getBlock(0)));
+
+ return identities;
+}
+
+void
+PibSqlite3::setDefaultIdentity(const Name& identityName)
+{
+ Sqlite3Statement statement(m_database, "UPDATE identities SET is_default=1 WHERE identity=?");
+ statement.bind(1, identityName.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+Name
+PibSqlite3::getDefaultIdentity() const
+{
+ Sqlite3Statement statement(m_database, "SELECT identity FROM identities WHERE is_default=1");
+
+ if (statement.step() == SQLITE_ROW)
+ return Name(statement.getBlock(0));
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
+}
+
+bool
+PibSqlite3::hasKey(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database, "SELECT id FROM keys WHERE key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+ return (statement.step() == SQLITE_ROW);
+}
+
+void
+PibSqlite3::addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey)
+{
+ if (hasKey(identity, keyId)) {
+ return;
+ }
+
+ // ensure identity exists
+ addIdentity(identity);
+
+ // add key
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database,
+ "INSERT INTO keys (identity_id, key_name, key_type, key_bits) "
+ "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(2, keyName.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(3, static_cast<int>(publicKey.getKeyType()));
+ statement.bind(4, publicKey.get().buf(), publicKey.get().size(), SQLITE_STATIC);
+ statement.step();
+}
+
+void
+PibSqlite3::removeKey(const Name& identity, const name::Component& keyId)
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database, "DELETE FROM keys WHERE key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+v1::PublicKey
+PibSqlite3::getKeyBits(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database, "SELECT key_bits FROM keys WHERE key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+ if (statement.step() == SQLITE_ROW)
+ return v1::PublicKey(statement.getBlob(0), statement.getSize(0));
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("Key does not exist"));
+}
+
+std::set<name::Component>
+PibSqlite3::getKeysOfIdentity(const Name& identity) const
+{
+ std::set<name::Component> keyNames;
+
+ Sqlite3Statement statement(m_database,
+ "SELECT key_name "
+ "FROM keys JOIN identities ON keys.identity_id=identities.id "
+ "WHERE identities.identity=?");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+
+ while (statement.step() == SQLITE_ROW) {
+ Name keyName(statement.getBlock(0));
+ keyNames.insert(keyName.get(-1));
+ }
+
+ return keyNames;
+}
+
+void
+PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId)
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ if (!hasKey(identity, keyId)) {
+ BOOST_THROW_EXCEPTION(Pib::Error("No such key"));
+ }
+
+ Sqlite3Statement statement(m_database, "UPDATE keys SET is_default=1 WHERE key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+name::Component
+PibSqlite3::getDefaultKeyOfIdentity(const Name& identity) const
+{
+ if (!hasIdentity(identity)) {
+ BOOST_THROW_EXCEPTION(Pib::Error("Identity does not exist"));
+ }
+
+ Sqlite3Statement statement(m_database,
+ "SELECT key_name "
+ "FROM keys JOIN identities ON keys.identity_id=identities.id "
+ "WHERE identities.identity=? AND keys.is_default=1");
+ statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
+
+ if (statement.step() == SQLITE_ROW) {
+ Name keyName(statement.getBlock(0));
+ return keyName.get(-1);
+ }
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("No default key"));
+}
+
+bool
+PibSqlite3::hasCertificate(const Name& certName) const
+{
+ Sqlite3Statement statement(m_database, "SELECT id FROM certificates WHERE certificate_name=?");
+ statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
+ return (statement.step() == SQLITE_ROW);
+}
+
+void
+PibSqlite3::addCertificate(const v1::IdentityCertificate& certificate)
+{
+ const Name& certName = certificate.getName();
+ const Name& keyName = certificate.getPublicKeyName();
+
+ name::Component keyId = keyName.get(-1);
+ Name identityName = keyName.getPrefix(-1);
+
+ // ensure key exists
+ addKey(identityName, keyId, certificate.getPublicKeyInfo());
+
+ Sqlite3Statement statement(m_database,
+ "INSERT INTO certificates "
+ "(key_id, certificate_name, certificate_data) "
+ "VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(2, certName.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(3, certificate.wireEncode(), SQLITE_STATIC);
+ statement.step();
+}
+
+void
+PibSqlite3::removeCertificate(const Name& certName)
+{
+ Sqlite3Statement statement(m_database, "DELETE FROM certificates WHERE certificate_name=?");
+ statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+v1::IdentityCertificate
+PibSqlite3::getCertificate(const Name& certName) const
+{
+ Sqlite3Statement statement(m_database,
+ "SELECT certificate_data FROM certificates WHERE certificate_name=?");
+ statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
+
+ if (statement.step() == SQLITE_ROW)
+ return v1::IdentityCertificate(statement.getBlock(0));
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exit"));
+}
+
+std::set<Name>
+PibSqlite3::getCertificatesOfKey(const Name& identity, const name::Component& keyId) const
+{
+ std::set<Name> certNames;
+
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database,
+ "SELECT certificate_name "
+ "FROM certificates JOIN keys ON certificates.key_id=keys.id "
+ "WHERE keys.key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+ while (statement.step() == SQLITE_ROW)
+ certNames.insert(Name(statement.getBlock(0)));
+
+ return certNames;
+}
+
+void
+PibSqlite3::setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId,
+ const Name& certName)
+{
+ if (!hasCertificate(certName)) {
+ BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exist"));
+ }
+
+ Sqlite3Statement statement(m_database,
+ "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
+ statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
+ statement.step();
+}
+
+v1::IdentityCertificate
+PibSqlite3::getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const
+{
+ Name keyName = getKeyName(identity, keyId);
+
+ Sqlite3Statement statement(m_database,
+ "SELECT certificate_data "
+ "FROM certificates JOIN keys ON certificates.key_id=keys.id "
+ "WHERE certificates.is_default=1 AND keys.key_name=?");
+ statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+ if (statement.step() == SQLITE_ROW)
+ return v1::IdentityCertificate(statement.getBlock(0));
+ else
+ BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exit"));
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib/pib-sqlite3.hpp b/src/security/pib/pib-sqlite3.hpp
new file mode 100644
index 0000000..7e4b2c5
--- /dev/null
+++ b/src/security/pib/pib-sqlite3.hpp
@@ -0,0 +1,143 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_SECURITTY_PIB_PIB_SQLITE3_HPP
+#define NDN_SECURITTY_PIB_PIB_SQLITE3_HPP
+
+#include "pib-impl.hpp"
+
+struct sqlite3;
+
+namespace ndn {
+namespace security {
+
+/**
+ * @brief Pib backend implementation based on SQLite3 database
+ *
+ * All the contents in Pib are stored in a SQLite3 database file.
+ * This backend provides more persistent storage than PibMemory.
+ */
+class PibSqlite3 : public PibImpl
+{
+public:
+ /**
+ * @brief Constructor of PibSqlite3
+ *
+ * This method will create a SQLite3 database file under the directory @p dir.
+ * If the directory does not exist, it will be created automatically.
+ * It assumes that the directory does not contain a PIB database of an older version,
+ * It is user's responsibility to update the older version database or remove the database.
+ *
+ * @param dir The directory where the database file is located. By default, it points to the
+ * $HOME/.ndn directory.
+ * @throws PibImpl::Error when initialization fails.
+ */
+ explicit
+ PibSqlite3(const std::string& dir = "");
+
+ /**
+ * @brief Destruct and cleanup internal state
+ */
+ ~PibSqlite3();
+
+public: // TpmLocator management
+
+ void
+ setTpmLocator(const std::string& tpmLocator) final;
+
+ std::string
+ getTpmLocator() const final;
+
+public: // Identity management
+
+ bool
+ hasIdentity(const Name& identity) const final;
+
+ void
+ addIdentity(const Name& identity) final;
+
+ void
+ removeIdentity(const Name& identity) final;
+
+ std::set<Name>
+ getIdentities() const final;
+
+ void
+ setDefaultIdentity(const Name& identityName) final;
+
+ Name
+ getDefaultIdentity() const final;
+
+public: // Key management
+
+ bool
+ hasKey(const Name& identity, const name::Component& keyId) const final;
+
+ void
+ addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey) final;
+
+ void
+ removeKey(const Name& identity, const name::Component& keyId) final;
+
+ v1::PublicKey
+ getKeyBits(const Name& identity, const name::Component& keyId) const final;
+
+ std::set<name::Component>
+ getKeysOfIdentity(const Name& identity) const final;
+
+ void
+ setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId) final;
+
+ name::Component
+ getDefaultKeyOfIdentity(const Name& identity) const final;
+
+public: // Certificate Management
+
+ bool
+ hasCertificate(const Name& certName) const final;
+
+ void
+ addCertificate(const v1::IdentityCertificate& certificate) final;
+
+ void
+ removeCertificate(const Name& certName) final;
+
+ v1::IdentityCertificate
+ getCertificate(const Name& certName) const final;
+
+ std::set<Name>
+ getCertificatesOfKey(const Name& identity, const name::Component& keyId) const final;
+
+ void
+ setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId,
+ const Name& certName) final;
+
+ v1::IdentityCertificate
+ getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const final;
+
+private:
+ sqlite3* m_database;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITTY_PIB_PIB_SQLITE3_HPP
diff --git a/src/security/pib/pib.cpp b/src/security/pib/pib.cpp
new file mode 100644
index 0000000..511c96a
--- /dev/null
+++ b/src/security/pib/pib.cpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_hasDefaultIdentity(false)
+ , m_needRefreshIdentities(true)
+ , 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)
+{
+ if (!m_needRefreshIdentities && m_identities.find(identity) == m_identities.end()) {
+ // if we have already loaded all the identities, but the new identity is not one of them
+ // the IdentityContainer should be refreshed
+ m_needRefreshIdentities = true;
+ }
+ return Identity(identity, m_impl, true);
+}
+
+void
+Pib::removeIdentity(const Name& identity)
+{
+ if (m_hasDefaultIdentity && m_defaultIdentity.getName() == identity)
+ m_hasDefaultIdentity = false;
+
+ m_impl->removeIdentity(identity);
+ m_needRefreshIdentities = true;
+}
+
+Identity
+Pib::getIdentity(const Name& identity) const
+{
+ return Identity(identity, m_impl, false);
+}
+
+const IdentityContainer&
+Pib::getIdentities() const
+{
+ if (m_needRefreshIdentities) {
+ m_identities = IdentityContainer(m_impl->getIdentities(), m_impl);
+ m_needRefreshIdentities = false;
+ }
+
+ return m_identities;
+}
+
+Identity&
+Pib::setDefaultIdentity(const Name& identityName)
+{
+ m_defaultIdentity = addIdentity(identityName);
+ m_hasDefaultIdentity = true;
+
+ m_impl->setDefaultIdentity(identityName);
+ return m_defaultIdentity;
+}
+
+Identity&
+Pib::getDefaultIdentity() const
+{
+ if (!m_hasDefaultIdentity) {
+ m_defaultIdentity = Identity(m_impl->getDefaultIdentity(), m_impl, false);
+ m_hasDefaultIdentity = true;
+ }
+
+ return m_defaultIdentity;
+}
+
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/pib/pib.hpp b/src/security/pib/pib.hpp
new file mode 100644
index 0000000..5c5a11c
--- /dev/null
+++ b/src/security/pib/pib.hpp
@@ -0,0 +1,187 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_PIB_PIB_HPP
+#define NDN_SECURITY_PIB_PIB_HPP
+
+#include "identity-container.hpp"
+
+namespace ndn {
+namespace security {
+
+class KeyChain;
+class PibImpl;
+
+/**
+ * @brief represents the PIB
+ *
+ * The PIB (Public Information Base) stores the public portion of a user's cryptography keys.
+ * The format and location of stored information is indicated by the PibLocator.
+ * The PIB is designed to work with a TPM (Trusted Platform Module) which stores private keys.
+ * There is a one-to-one association between PIB and TPM, and therefore the TpmLocator is recorded
+ * by the PIB to enforce this association and prevent one from operating on mismatched PIB and TPM.
+ *
+ * Information in the PIB is organized in a hierarchy of Identity-Key-Certificate. At the top level,
+ * the Pib class provides access to identities, and allows setting a default identity. Properties of
+ * an identity can be accessed after obtaining an Identity object.
+ *
+ * @throw PibImpl::Error when underlying implementation has non-semantic error.
+ */
+class Pib : noncopyable
+{
+public:
+ friend class KeyChain;
+
+public:
+ /// @brief represents a semantic error
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+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 tpmLocator The name for the new TPM locator
+ */
+ void
+ setTpmLocator(const std::string& tpmLocator);
+
+ /**
+ * @brief Get TPM Locator
+ */
+ std::string
+ getTpmLocator() const;
+
+ /**
+ * @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) const;
+
+ /// @brief Get all the identities
+ const IdentityContainer&
+ getIdentities() const;
+
+ /**
+ * @brief Get the default identity.
+ *
+ * @return the default identity.
+ * @throws Pib::Error if no default identity.
+ */
+ Identity&
+ getDefaultIdentity() const;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE: // write operations should be private
+
+ /*
+ * @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 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);
+
+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;
+
+ mutable bool m_hasDefaultIdentity;
+ mutable Identity m_defaultIdentity;
+
+ mutable bool m_needRefreshIdentities;
+ mutable IdentityContainer m_identities;
+
+ shared_ptr<PibImpl> m_impl;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_PIB_PIB_HPP