| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /* |
| * Copyright (c) 2013-2024 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_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP |
| #define NDN_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP |
| |
| #include "ndn-cxx/interest.hpp" |
| #include "ndn-cxx/security/certificate.hpp" |
| #include "ndn-cxx/security/trust-anchor-group.hpp" |
| |
| #include <boost/multi_index_container.hpp> |
| #include <boost/multi_index/hashed_index.hpp> |
| #include <boost/multi_index/ordered_index.hpp> |
| #include <boost/multi_index/mem_fun.hpp> |
| |
| namespace ndn::security { |
| |
| /** |
| * @brief A container for trust anchors. |
| * |
| * There are two kinds of anchors: |
| * - static anchors that are permanent for the lifetime of the container |
| * - dynamic anchors that are periodically updated. |
| * |
| * Trust anchors are organized in groups. Each group has a unique group id. The same anchor |
| * certificate (same name without considering the implicit digest) can be inserted into |
| * multiple groups, but no more than once into each. |
| * |
| * Dynamic groups are created using the appropriate TrustAnchorContainer::insert method. Once |
| * created, the dynamic anchor group cannot be updated. |
| * |
| * The returned pointer to Certificate from `find` methods is only guaranteed to be valid until |
| * the next invocation of `find` and may be invalidated afterwards. |
| */ |
| class TrustAnchorContainer : noncopyable |
| { |
| public: |
| class Error : public std::runtime_error |
| { |
| public: |
| using std::runtime_error::runtime_error; |
| }; |
| |
| /** |
| * @brief Insert a static trust anchor. |
| * |
| * @param groupId Certificate group id. |
| * @param cert Certificate to insert. |
| * |
| * If @p cert (same name without considering implicit digest) already exists in the group @p |
| * groupId, this method has no effect. |
| * |
| * @throw Error @p groupId is a dynamic anchor group . |
| */ |
| void |
| insert(const std::string& groupId, Certificate&& cert); |
| |
| /** |
| * @brief Insert dynamic trust anchors from path. |
| * |
| * @param groupId Certificate group id, must not be empty. |
| * @param path Specifies the path to load the trust anchors. |
| * @param refreshPeriod Refresh period for the trust anchors, must be positive. |
| * Relevant trust anchors will only be updated when find is called |
| * @param isDir Tells whether the path is a directory or a single file. |
| * |
| * @throw std::invalid_argument @p refreshPeriod is not positive |
| * @throw Error a group with @p groupId already exists |
| */ |
| void |
| insert(const std::string& groupId, const std::filesystem::path& path, |
| time::nanoseconds refreshPeriod, bool isDir = false); |
| |
| /** |
| * @brief Remove all static or dynamic anchors. |
| */ |
| void |
| clear(); |
| |
| /** |
| * @brief Search for certificate across all groups (longest prefix match). |
| * @param keyName Key name prefix for searching the certificate. |
| * @return The found certificate, nullptr if not found. |
| * |
| * @note The returned value may be invalidated after next call to one of `find` methods. |
| */ |
| const Certificate* |
| find(const Name& keyName) const; |
| |
| /** |
| * @brief Find certificate given interest. |
| * @param interest The input interest packet. |
| * @return The found certificate, nullptr if not found. |
| * |
| * @note The returned value may be invalidated after next call to one of `find` methods. |
| * @note Interest with implicit digest is not supported. |
| */ |
| const Certificate* |
| find(const Interest& interest) const; |
| |
| /** |
| * @brief Get trusted anchor group. |
| * @throw Error @p groupId does not exist |
| */ |
| TrustAnchorGroup& |
| getGroup(const std::string& groupId) const; |
| |
| /** |
| * @brief Get number of trust anchors across all groups. |
| */ |
| size_t |
| size() const; |
| |
| private: |
| void |
| refresh(); |
| |
| private: |
| using AnchorContainerBase = boost::multi_index::multi_index_container< |
| Certificate, |
| boost::multi_index::indexed_by< |
| boost::multi_index::ordered_unique< |
| boost::multi_index::const_mem_fun<Data, const Name&, &Data::getName> |
| > |
| > |
| >; |
| |
| class AnchorContainer : public CertContainerInterface, |
| public AnchorContainerBase |
| { |
| public: |
| void |
| add(Certificate&& cert) final; |
| |
| void |
| remove(const Name& certName) final; |
| |
| void |
| clear(); |
| }; |
| |
| using GroupContainer = boost::multi_index::multi_index_container< |
| shared_ptr<TrustAnchorGroup>, |
| boost::multi_index::indexed_by< |
| boost::multi_index::hashed_unique< |
| boost::multi_index::const_mem_fun<TrustAnchorGroup, const std::string&, &TrustAnchorGroup::getId> |
| > |
| > |
| >; |
| |
| GroupContainer m_groups; |
| AnchorContainer m_anchors; |
| }; |
| |
| } // namespace ndn::security |
| |
| #endif // NDN_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP |