blob: 49e4999eb36c0d9b338a4b1893525a99d13ade91 [file] [log] [blame]
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2017 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_SECURITY_V2_TRUST_ANCHOR_CONTAINER_HPP
23#define NDN_SECURITY_V2_TRUST_ANCHOR_CONTAINER_HPP
24
25#include "trust-anchor-group.hpp"
26#include "certificate.hpp"
27#include "../../interest.hpp"
28
29#include <boost/multi_index_container.hpp>
30#include <boost/multi_index/hashed_index.hpp>
31#include <boost/multi_index/ordered_index.hpp>
32#include <boost/multi_index/mem_fun.hpp>
33
34namespace ndn {
35namespace security {
36namespace v2 {
37
38/**
39 * @brief represents a container for trust anchors.
40 *
41 * There are two kinds of anchors:
42 * - static anchors that are permanent for the lifetime of the container
43 * - dynamic anchors that are periodically updated.
44 *
45 * Trust anchors are organized in groups. Each group has a unique group id. The same anchor
46 * certificate (same name without considering the implicit digest) can be inserted into
47 * multiple groups, but no more than once into each.
48 *
49 * Dynamic groups are created using the appropriate TrustAnchorContainer::insert method. Once
50 * created, the dynamic anchor group cannot be updated.
51 *
52 * The returned pointer to Certificate from `find` methods is only guaranteed to be valid until
53 * the next invocation of `find` and may be invalidated afterwards.
54 */
55class TrustAnchorContainer : noncopyable
56{
57public:
58 class Error : public std::runtime_error
59 {
60 public:
61 explicit
62 Error(const std::string& what)
63 : std::runtime_error(what)
64 {
65 }
66 };
67
68 /**
69 * @brief Insert a static trust anchor.
70 *
71 * @param groupId Certificate group id.
72 * @param cert Certificate to insert.
73 *
74 * If @p cert (same name without considering implicit digest) already exists in the group @p
75 * groupId, this method has no effect.
76 *
77 * @throw Error @p groupId is a dynamic anchor group .
78 */
79 void
80 insert(const std::string& groupId, Certificate&& cert);
81
82 /**
83 * @brief Insert dynamic trust anchors from path.
84 *
85 * @param groupId Certificate group id, must not be empty.
86 * @param path Specifies the path to load the trust anchors.
87 * @param refreshPeriod Refresh period for the trust anchors, must be positive.
88 * Relevant trust anchors will only be updated when find is called
89 * @param isDir Tells whether the path is a directory or a single file.
90 *
91 * @throw std::invalid_argument @p refreshPeriod is not positive
92 * @throw Error a group with @p groupId already exists
93 */
94 void
95 insert(const std::string& groupId, const boost::filesystem::path& path,
96 time::nanoseconds refreshPeriod, bool isDir = false);
97
98 /**
99 * @brief Search for certificate across all groups (longest prefix match)
100 * @param keyName Key name prefix for searching the certificate.
101 * @return The found certificate, nullptr if not found.
102 *
103 * @note The returned value may be invalidated after next call to one of `find` methods.
104 */
105 const Certificate*
106 find(const Name& keyName) const;
107
108 /**
109 * @brief Find certificate given interest
110 * @param interest The input interest packet.
111 * @return The found certificate, nullptr if not found.
112 *
113 * @note The returned value may be invalidated after next call to one of `find` methods.
114 *
115 * @note Interest with implicit digest is not supported.
116 *
117 * @note ChildSelector is not supported.
118 */
119 const Certificate*
120 find(const Interest& interest) const;
121
122 /**
123 * @brief Get trusted anchor group
124 * @throw Error @p groupId does not exist
125 */
126 TrustAnchorGroup&
127 getGroup(const std::string& groupId) const;
128
129 /**
130 * @brief Get number of trust anchors across all groups
131 */
132 size_t
133 size() const;
134
135private:
136 void
137 refresh();
138
139private:
140 using AnchorContainerBase = boost::multi_index::multi_index_container<
141 Certificate,
142 boost::multi_index::indexed_by<
143 boost::multi_index::ordered_unique<
144 boost::multi_index::const_mem_fun<Data, const Name&, &Data::getName>
145 >
146 >
147 >;
148
149 class AnchorContainer : public CertContainerInterface,
150 public AnchorContainerBase
151 {
152 public:
153 void
154 add(Certificate&& cert) final;
155
156 void
157 remove(const Name& certName) final;
158 };
159
160 using GroupContainer = boost::multi_index::multi_index_container<
161 shared_ptr<TrustAnchorGroup>,
162 boost::multi_index::indexed_by<
163 boost::multi_index::hashed_unique<
164 boost::multi_index::const_mem_fun<TrustAnchorGroup, const std::string&, &TrustAnchorGroup::getId>
165 >
166 >
167 >;
168
169 GroupContainer m_groups;
170 AnchorContainer m_anchors;
171};
172
173} // namespace v2
174} // namespace security
175} // namespace ndn
176
177#endif // NDN_SECURITY_V2_TRUST_ANCHOR_CONTAINER_HPP