blob: c17ce823d228b65ce1c7830541ade296de59519c [file] [log] [blame]
Alexander Afanasyev7e721412017-01-11 13:36:08 -08001/* -*- 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_VALIDATOR_HPP
23#define NDN_SECURITY_V2_VALIDATOR_HPP
24
25#include "certificate.hpp"
26#include "certificate-cache.hpp"
27#include "certificate-request.hpp"
28#include "trust-anchor-container.hpp"
29#include "validation-callback.hpp"
30#include "validation-policy.hpp"
31#include "validation-state.hpp"
32
33namespace ndn {
34
35class Face;
36
37namespace lp {
38class Nack;
39} // namespace lp
40
41namespace security {
42namespace v2 {
43
44/**
45 * @brief Interface for validating data and interest packets.
46 *
47 * Every time a validation process initiated, it creates a ValidationState that exist until
48 * validation finishes with either success or failure. This state serves several purposes:
49 * - record Interest or Data packet being validated
50 * - record failure callback
51 * - record certificates in the certification chain for the Interest or Data packet being validated
52 * - record names of the requested certificates to detect loops in the certificate chain
53 * - keep track of the validation chain size (aka validation "depth")
54 *
55 * During validation, policy can augment validation state with policy- and fetcher-specific
56 * information using ndn::Tag's.
57 *
58 * A validator has a trust anchor cache to save static and dynamic trust anchors, a verified
59 * certificate cache for saving certificates that are already verified and an unverified
60 * certificate cache for saving prefetched but not yet verified certificates.
61 *
62 * @todo Limit the maximum time the validation process is allowed to run before declaring failure
63 * @todo Ability to customize maximum lifetime for trusted and untrusted certificate caches.
64 * Current implementation hard-codes them to be 1 hour and 5 minutes.
65 */
66class Validator : noncopyable
67{
68public:
69 /**
70 * @brief Validator constructor.
71 *
72 * @param policy Validation policy to be associated with the validator
73 * @param face Face for fetching certificates from network. If provided, the Validator
74 * operates in online mode; otherwise, the Validator operates in offline mode.
75 */
76 explicit
77 Validator(unique_ptr<ValidationPolicy> policy, Face* face = nullptr);
78
79 ~Validator();
80
81 /**
82 * @brief Set the maximum depth of the certificate chain
83 */
84 void
85 setMaxDepth(size_t depth);
86
87 /**
88 * @return The maximum depth of the certificate chain
89 */
90 size_t
91 getMaxDepth() const;
92
93 /**
94 * @brief Asynchronously validate @p data
95 *
96 * @note @p successCb and @p failureCb must not be nullptr
97 */
98 void
99 validate(const Data& data,
100 const DataValidationSuccessCallback& successCb,
101 const DataValidationFailureCallback& failureCb);
102
103 /**
104 * @brief Asynchronously validate @p interest
105 *
106 * @note @p successCb and @p failureCb must not be nullptr
107 */
108 void
109 validate(const Interest& interest,
110 const InterestValidationSuccessCallback& successCb,
111 const InterestValidationFailureCallback& failureCb);
112
113public: // anchor management
114 /**
115 * @brief load static trust anchor.
116 *
117 * Static trust anchors are permanently associated with the validator and never expire.
118 *
119 * @param groupId Certificate group id.
120 * @param cert Certificate to load as a trust anchor.
121 */
122 void
123 loadAnchor(const std::string& groupId, Certificate&& cert);
124
125 /**
126 * @brief load dynamic trust anchors.
127 *
128 * Dynamic trust anchors are associated with the validator for as long as the underlying
129 * trust anchor file (set of files) exist(s).
130 *
131 * @param groupId Certificate group id, must not be empty.
132 * @param certfilePath Specifies the path to load the trust anchors.
133 * @param refreshPeriod Refresh period for the trust anchors, must be positive.
134 * @param isDir Tells whether the path is a directory or a single file.
135 */
136 void
137 loadAnchor(const std::string& groupId, const std::string& certfilePath,
138 time::nanoseconds refreshPeriod, bool isDir = false);
139
140 /**
141 * @brief Cache verified @p cert a period of time (1 hour)
142 *
143 * @todo Add ability to customize time period
144 */
145 void
146 cacheVerifiedCertificate(Certificate&& cert);
147
148 /**
149 * @brief Cache unverified @p cert for a period of time (5 minutes)
150 *
151 * @todo Add ability to customize time period
152 */
153 void
154 cacheUnverifiedCertificate(Certificate&& cert);
155
156 /**
157 * @return Trust anchor container
158 */
159 const TrustAnchorContainer&
160 getTrustAnchors() const;
161
162 /**
163 * @return Verified certificate cache
164 */
165 const CertificateCache&
166 getVerifiedCertificateCache() const;
167
168 /**
169 * @return Unverified certificate cache
170 */
171 const CertificateCache&
172 getUnverifiedCertificateCache() const;
173
174 /**
175 * @brief Check if certificate with @p certName exists in verified or unverified cache
176 */
177 bool
178 isCertificateCached(const Name& certName) const;
179
180private: // Common validator operations
181 /**
182 * @brief Recursive validation of the certificate in the certification chain
183 *
184 * @param cert The certificate to check.
185 * @param state The current validation state.
186 */
187 void
188 validate(const Certificate& cert, const shared_ptr<ValidationState>& state);
189
190 /**
191 * @brief Request certificate for further validation.
192 *
193 * @param certRequest Certificate request.
194 * @param state The current validation state.
195 */
196 void
197 requestCertificate(const shared_ptr<CertificateRequest>& certRequest,
198 const shared_ptr<ValidationState>& state);
199
200 /**
201 * @brief Find trusted certificate among trust anchors and verified certificates.
202 *
203 * @param interestForCertificate Interest for certificate
204 * @param state The current validation state.
205 *
206 * @return found certificate, nullptr if not found.
207 *
208 * @note The returned pointer may get invalidated after next findTrustedCert call.
209 */
210 const Certificate*
211 findTrustedCert(const Interest& interestForCertificate,
212 const shared_ptr<ValidationState>& state);
213
214 /**
215 * @brief fetch certificate from network based on certificate request.
216 *
217 * @param certRequest Certificate request.
218 * @param state The current validation state.
219 */
220 void
221 fetchCertificateFromNetwork(const shared_ptr<CertificateRequest>& certRequest,
222 const shared_ptr<ValidationState>& state);
223
224 /**
225 * @brief Callback invoked when certificated is retrieved.
226 *
227 * @param data Retrieved certificate.
228 * @param certRequest Certificate request.
229 * @param state The current validation state.
230 * @param isFromNetwork Flag to indicate that the data packet is retrieved (to avoid re-caching).
231 */
232 void
233 dataCallback(const Data& data,
234 const shared_ptr<CertificateRequest>& certRequest,
235 const shared_ptr<ValidationState>& state,
236 bool isFromNetwork = true);
237
238 /**
239 * @brief Callback invoked when interest for fetching certificate gets NACKed.
240 *
241 * It will retry for pre-configured amount of retries.
242 *
243 * @param nack Received NACK
244 * @param certRequest Certificate request.
245 * @param state The current validation state.
246 */
247 void
248 nackCallback(const lp::Nack& nack, const shared_ptr<CertificateRequest>& certRequest,
249 const shared_ptr<ValidationState>& state);
250
251 /**
252 * @brief Callback invoked when interest for fetching certificate times out.
253 *
254 * It will retry for pre-configured amount of retries.
255 *
256 * @param certRequest Certificate request.
257 * @param state The current validation state.
258 */
259 void
260 timeoutCallback(const shared_ptr<CertificateRequest>& certRequest,
261 const shared_ptr<ValidationState>& state);
262
263private:
264 unique_ptr<ValidationPolicy> m_policy;
265 Face* m_face;
266 TrustAnchorContainer m_trustAnchors;
267 CertificateCache m_verifiedCertificateCache;
268 CertificateCache m_unverifiedCertificateCache;
269 size_t m_maxDepth;
270};
271
272} // namespace v2
273} // namespace security
274} // namespace ndn
275
276#endif // NDN_SECURITY_V2_VALIDATOR_HPP