security: Change the ownership model of Pib and its related entities

Change-Id: I6816a0fd5c7af490f7e98db196e0214219f4b05c
Refs: #3349
diff --git a/src/security/pib/certificate-container.hpp b/src/security/pib/certificate-container.hpp
index eba765e..42e9534 100644
--- a/src/security/pib/certificate-container.hpp
+++ b/src/security/pib/certificate-container.hpp
@@ -23,6 +23,7 @@
 #define NDN_SECURITY_PIB_CERTIFICATE_CONTAINER_HPP
 
 #include <set>
+#include <unordered_map>
 #include "../v2/certificate.hpp"
 
 namespace ndn {
@@ -31,16 +32,24 @@
 
 class PibImpl;
 
-/// @brief A handler to search or enumerate certificates of a key.
-class CertificateContainer
+namespace detail {
+class KeyImpl;
+} // namespace detail
+
+/**
+ * @brief Container of certificates of a key
+ *
+ * The container is used to search/enumerate certificates of a key.
+ * The container can be created only by detail::KeyImpl.
+ */
+class CertificateContainer : noncopyable
 {
 public:
-  class const_iterator
+  class const_iterator : public std::iterator<std::forward_iterator_tag, const v2::Certificate>
   {
   public:
-    friend class CertificateContainer;
+    const_iterator();
 
-  public:
     v2::Certificate
     operator*();
 
@@ -51,26 +60,24 @@
     operator++(int);
 
     bool
-    operator==(const const_iterator& other);
+    operator==(const const_iterator& other) const;
 
     bool
-    operator!=(const const_iterator& other);
+    operator!=(const const_iterator& other) const;
 
   private:
-    const_iterator(std::set<Name>::const_iterator it, shared_ptr<PibImpl> impl);
+    const_iterator(std::set<Name>::const_iterator it, const CertificateContainer& container);
 
   private:
     std::set<Name>::const_iterator m_it;
-    shared_ptr<PibImpl> m_impl;
+    const CertificateContainer* m_container;
+
+    friend class CertificateContainer;
   };
 
   typedef const_iterator iterator;
 
 public:
-  CertificateContainer();
-
-  CertificateContainer(std::set<Name>&& certNames, shared_ptr<PibImpl> impl);
-
   const_iterator
   begin() const;
 
@@ -83,9 +90,64 @@
   size_t
   size() const;
 
+  /**
+   * @brief Add @p certificate into the container
+   * @throw std::invalid_argument the name of @p certificate does not match the key name
+   */
+  void
+  add(const v2::Certificate& certificate);
+
+  /**
+   * @brief Remove a certificate with @p certName from the container
+   * @throw std::invalid_argument @p certName does not match the key name
+   */
+  void
+  remove(const Name& certName);
+
+  /**
+   * @brief Get a certificate with @p certName from the container
+   * @throw std::invalid_argument @p certName does not match the key name
+   * @throw Pib::Error the certificate does not exist
+   */
+  v2::Certificate
+  get(const Name& certName) const;
+
+  /**
+   * @brief Check if the container is consistent with the backend storage
+   *
+   * @note this method is heavyweight and should be used in debugging mode only.
+   */
+  bool
+  isConsistent() const;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /**
+   * @brief Create certificate container for a key with @p keyName
+   * @param impl The PIB backend implementation.
+   */
+  CertificateContainer(const Name& keyName, shared_ptr<PibImpl> impl);
+
+  const std::set<Name>&
+  getCertNames() const
+  {
+    return m_certNames;
+  }
+
+  const std::unordered_map<Name, v2::Certificate>&
+  getCache() const
+  {
+    return m_certs;
+  }
+
 private:
+  Name m_keyName;
   std::set<Name> m_certNames;
+  /// @brief Cache of loaded certificates
+  mutable std::unordered_map<Name, v2::Certificate> m_certs;
+
   shared_ptr<PibImpl> m_impl;
+
+  friend class detail::KeyImpl;
 };
 
 } // namespace pib