blob: bcd2f36ad11f5d3b35062b6d25768ff0500ac695 [file] [log] [blame]
Manika Mittal95c80702017-01-27 09:54:41 -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_CERTIFICATE_BUNDLE_FETCHER_HPP
23#define NDN_SECURITY_V2_CERTIFICATE_BUNDLE_FETCHER_HPP
24
25#include "certificate-fetcher-from-network.hpp"
26
27namespace ndn {
28namespace security {
29namespace v2 {
30
31/**
32 * @brief Fetch certificate bundle from the network
33 *
34 * Currently bundle fetching is attempted only for Data validation. This may change in the
35 * future. Bundle fetching always goes to the infrastructure regardless of the inner
36 * fetcher. Inner fetcher is used when the bundle interest times out or returns a Nack or when
37 * additional certificates are needed for validation.
38 *
39 * @sa https://redmine.named-data.net/projects/ndn-cxx/wiki/Certificate_Bundle_Packet_Format
40 */
41class CertificateBundleFetcher : public CertificateFetcher
42{
43public:
44 explicit
45 CertificateBundleFetcher(unique_ptr<CertificateFetcher> inner,
46 Face& face);
47
48 /**
49 * @brief Set the lifetime of certificate bundle interest
50 */
51 void
52 setBundleInterestLifetime(time::milliseconds time);
53
54 /**
55 * @return The lifetime of certificate bundle interest
56 */
57 time::milliseconds
58 getBundleInterestLifetime() const;
59
60 /**
61 * Set the storage for this and inner certificate fetcher
62 */
63 void
64 setCertificateStorage(CertificateStorage& certStorage) override;
65
66protected:
67 void
68 doFetch(const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state,
69 const ValidationContinuation& continueValidation) override;
70
71private:
72 /**
73 * @brief Fetch the first bundle segment.
74 *
75 * After deriving the bundle name prefix, the exact version of the bundle is not yet known.
76 * This method express Interest for the bundle prefix to (1) retrieve first segment of the bundle and
77 * (2) discover bundle version. The bundle version will be recorded in the validation state as BundleNameTag
78 * and will be used in subsequent @p fetchNextBundleSegment calls to fetch further bundle segments if needed.
79 */
80 void
81 fetchFirstBundleSegment(const Name& bundleNamePrefix,
82 const shared_ptr<CertificateRequest>& certRequest,
83 const shared_ptr<ValidationState>& state,
84 const ValidationContinuation& continueValidation);
85
86 /**
87 * @brief Fetch the specified bundle segment.
88 */
89 void
90 fetchNextBundleSegment(const Name& fullBundleName, const name::Component& segmentNo,
91 const shared_ptr<CertificateRequest>& certRequest,
92 const shared_ptr<ValidationState>& state,
93 const ValidationContinuation& continueValidation);
94
95 /**
96 * @brief Derive bundle name from data name.
97 *
98 * Current naming conventions are as follows:
99 * /<derived(data_name)>/BUNDLE/<trust-model>/<version>/<seg>
100 *
101 * Current rules for derived(data_name):
102 * (1) If the last component is Implicit Digest AND the second last component is Segment number
103 * then derived(data_name) = data_name.getPrefix(-2)
104 * (2) If the last component is Implicit Digest
105 * then derived(data_name) = data_name.getPrefix(-1)
106 * (3) If the last component is Segment number
107 * then derived(data_name) = data_name.getPrefix(-1)
108 *
109 * <trust-model> component is "00" for single hierarchy trust models.
110 */
111 static Name
112 deriveBundleName(const Name& name);
113
114 /**
115 * @brief Callback invoked when certificate bundle is retrieved.
116 */
117 void
118 dataCallback(const Data& data, bool isSegmentZeroExpected,
119 const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state,
120 const ValidationContinuation& continueValidation);
121
122 /**
123 * @brief Callback invoked when interest for fetching certificate bundle gets NACKed.
124 */
125 void
126 nackCallback(const lp::Nack& nack,
127 const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state,
128 const ValidationContinuation& continueValidation, const Name& bundleName);
129
130 /**
131 * @brief Callback invoked when interest for fetching certificate times out.
132 */
133 void
134 timeoutCallback(const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state,
135 const ValidationContinuation& continueValidation, const Name& bundleName);
136
137private:
138 unique_ptr<CertificateFetcher> m_inner;
139 Face& m_face;
140 using BundleNameTag = SimpleTag<Name, 1000>;
141 using FinalBlockIdTag = SimpleTag<name::Component, 1001>;
142 time::milliseconds m_bundleInterestLifetime;
143};
144
145} // namespace v2
146} // namespace security
147} // namespace ndn
148
149#endif // NDN_SECURITY_V2_CERTIFICATE_BUNDLE_FETCHER_HPP