blob: 6759ee1811bf8a512b1b11e4f54825c59f295fd9 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022 */
23
24#ifndef NDN_SECURITY_VALIDATOR_CONFIG_HPP
25#define NDN_SECURITY_VALIDATOR_CONFIG_HPP
26
27#include "validator.hpp"
28#include "certificate-cache.hpp"
29#include "conf/rule.hpp"
30#include "conf/common.hpp"
31
32namespace ndn {
33
34class ValidatorConfig : public Validator
35{
36public:
37 class Error : public Validator::Error
38 {
39 public:
40 explicit
41 Error(const std::string& what)
42 : Validator::Error(what)
43 {
44 }
45 };
46
47 static const shared_ptr<CertificateCache> DEFAULT_CERTIFICATE_CACHE;
48
Yingdi Yu96e64062014-04-15 19:57:33 -070049 explicit
50 ValidatorConfig(Face& face,
51 const shared_ptr<CertificateCache>& certificateCache = DEFAULT_CERTIFICATE_CACHE,
52 const int stepLimit = 10);
53
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070054 virtual
55 ~ValidatorConfig()
56 {
57 }
58
59 void
60 load(const std::string& filename);
61
62 void
63 load(const std::string& input, const std::string& filename);
64
65 void
66 load(std::istream& input, const std::string& filename);
67
Yingdi Yudfa9d732014-04-09 09:53:01 -070068 void
69 load(const security::conf::ConfigSection& configSection,
70 const std::string& filename);
71
Yingdi Yu58f33712014-04-16 16:57:47 -070072 inline void
73 reset();
74
75 inline bool
76 isEmpty();
77
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070078protected:
79 virtual void
80 checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070081 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070082 const OnDataValidated& onValidated,
83 const OnDataValidationFailed& onValidationFailed,
84 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
85
86 virtual void
87 checkPolicy(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070088 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070089 const OnInterestValidated& onValidated,
90 const OnInterestValidationFailed& onValidationFailed,
91 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
92
93private:
94 template<class Packet, class OnValidated, class OnFailed>
95 void
96 checkSignature(const Packet& packet,
97 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070098 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070099 const OnValidated& onValidated,
100 const OnFailed& onValidationFailed,
101 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
102
103 template<class Packet, class OnValidated, class OnFailed>
104 void
105 onCertValidated(const shared_ptr<const Data>& signCertificate,
106 const shared_ptr<const Packet>& packet,
107 const OnValidated& onValidated,
108 const OnFailed& onValidationFailed);
109
110 template<class Packet, class OnFailed>
111 void
112 onCertFailed(const shared_ptr<const Data>& signCertificate,
113 const std::string& failureInfo,
114 const shared_ptr<const Packet>& packet,
115 const OnFailed& onValidationFailed);
116
117 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700118 onConfigRule(const security::conf::ConfigSection& section,
119 const std::string& filename);
120
121 void
122 onConfigTrustAnchor(const security::conf::ConfigSection& section,
123 const std::string& filename);
124
125private:
126 typedef security::conf::Rule<Interest> InterestRule;
127 typedef security::conf::Rule<Data> DataRule;
128 typedef std::vector<shared_ptr<InterestRule> > InterestRuleList;
129 typedef std::vector<shared_ptr<DataRule> > DataRuleList;
130 typedef std::map<Name, shared_ptr<IdentityCertificate> > AnchorList;
131
Yingdi Yu44d190c2014-04-16 17:05:46 -0700132 /**
133 * @brief gives whether validation should be preformed
134 *
135 * If false, no validation occurs, and any packet is considered validated immediately.
136 */
137 bool m_shouldValidate;
138
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700139 int m_stepLimit;
140 shared_ptr<CertificateCache> m_certificateCache;
141
142 InterestRuleList m_interestRules;
143 DataRuleList m_dataRules;
144 AnchorList m_anchors;
145};
146
Yingdi Yu58f33712014-04-16 16:57:47 -0700147inline void
148ValidatorConfig::reset()
149{
150 m_certificateCache->reset();
151 m_interestRules.clear();
152 m_dataRules.clear();
153 m_anchors.clear();
154}
155
156inline bool
157ValidatorConfig::isEmpty()
158{
159 if (m_certificateCache->isEmpty() &&
160 m_interestRules.empty() &&
161 m_dataRules.empty() &&
162 m_anchors.empty())
163 return true;
164 return false;
165}
166
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700167template<class Packet, class OnValidated, class OnFailed>
168void
169ValidatorConfig::checkSignature(const Packet& packet,
170 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700171 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700172 const OnValidated& onValidated,
173 const OnFailed& onValidationFailed,
174 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
175{
176 if (signature.getType() == Signature::Sha256)
177 {
178 SignatureSha256 sigSha256(signature);
179
180 if (verifySignature(packet, sigSha256))
181 return onValidated(packet.shared_from_this());
182 else
183 return onValidationFailed(packet.shared_from_this(),
184 "Sha256 Signature cannot be verified!");
185 }
186
187 if (signature.getType() == Signature::Sha256WithRsa)
188 {
189 SignatureSha256WithRsa sigSha256Rsa(signature);
190 Name keyLocatorName = sigSha256Rsa.getKeyLocator().getName();
191
192 shared_ptr<const Certificate> trustedCert;
193
194 AnchorList::const_iterator it = m_anchors.find(keyLocatorName);
195 if (m_anchors.end() == it)
196 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
197 else
198 trustedCert = it->second;
199
200 if (static_cast<bool>(trustedCert))
201 {
202 if (verifySignature(packet, sigSha256Rsa, trustedCert->getPublicKeyInfo()))
203 return onValidated(packet.shared_from_this());
204 else
205 return onValidationFailed(packet.shared_from_this(),
206 "Cannot verify signature");
207 }
208 else
209 {
210 OnDataValidated onCertValidated =
211 bind(&ValidatorConfig::onCertValidated<Packet, OnValidated, OnFailed>,
212 this, _1, packet.shared_from_this(), onValidated, onValidationFailed);
213
214 OnDataValidationFailed onCertValidationFailed =
215 bind(&ValidatorConfig::onCertFailed<Packet, OnFailed>,
216 this, _1, _2, packet.shared_from_this(), onValidationFailed);
217
218 Interest certInterest(keyLocatorName);
219
220 shared_ptr<ValidationRequest> nextStep =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700221 make_shared<ValidationRequest>(certInterest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700222 onCertValidated,
223 onCertValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700224 1, nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700225
226 nextSteps.push_back(nextStep);
227 return;
228 }
229 }
230 return onValidationFailed(packet.shared_from_this(), "Unsupported Signature Type!");
231}
232
233template<class Packet, class OnValidated, class OnFailed>
234void
235ValidatorConfig::onCertValidated(const shared_ptr<const Data>& signCertificate,
236 const shared_ptr<const Packet>& packet,
237 const OnValidated& onValidated,
238 const OnFailed& onValidationFailed)
239{
240 shared_ptr<IdentityCertificate> certificate =
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700241 make_shared<IdentityCertificate>(*signCertificate);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700242
243 if (!certificate->isTooLate() && !certificate->isTooEarly())
244 {
245 m_certificateCache->insertCertificate(certificate);
246
247 if (verifySignature(*packet, certificate->getPublicKeyInfo()))
248 return onValidated(packet);
249 else
250 return onValidationFailed(packet,
251 "Cannot verify signature: " +
252 packet->getName().toUri());
253 }
254 else
255 {
256 return onValidationFailed(packet,
257 "Signing certificate " +
258 signCertificate->getName().toUri() +
259 " is no longer valid.");
260 }
261}
262
263template<class Packet, class OnFailed>
264void
265ValidatorConfig::onCertFailed(const shared_ptr<const Data>& signCertificate,
266 const std::string& failureInfo,
267 const shared_ptr<const Packet>& packet,
268 const OnFailed& onValidationFailed)
269{
270 onValidationFailed(packet, failureInfo);
271}
272
273} // namespace ndn
274
275#endif // NDN_SECURITY_VALIDATOR_CONFIG_HPP