blob: 00d7c66376c377cbdf533ca91e3db4a93f002ea6 [file] [log] [blame]
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070013 */
14
15#ifndef NDN_SECURITY_VALIDATOR_CONFIG_HPP
16#define NDN_SECURITY_VALIDATOR_CONFIG_HPP
17
18#include "validator.hpp"
19#include "certificate-cache.hpp"
20#include "conf/rule.hpp"
21#include "conf/common.hpp"
22
23namespace ndn {
24
25class ValidatorConfig : public Validator
26{
27public:
28 class Error : public Validator::Error
29 {
30 public:
31 explicit
32 Error(const std::string& what)
33 : Validator::Error(what)
34 {
35 }
36 };
37
38 static const shared_ptr<CertificateCache> DEFAULT_CERTIFICATE_CACHE;
39
Yingdi Yu96e64062014-04-15 19:57:33 -070040 explicit
41 ValidatorConfig(Face& face,
42 const shared_ptr<CertificateCache>& certificateCache = DEFAULT_CERTIFICATE_CACHE,
43 const int stepLimit = 10);
44
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070045 virtual
46 ~ValidatorConfig()
47 {
48 }
49
50 void
51 load(const std::string& filename);
52
53 void
54 load(const std::string& input, const std::string& filename);
55
56 void
57 load(std::istream& input, const std::string& filename);
58
Yingdi Yudfa9d732014-04-09 09:53:01 -070059 void
60 load(const security::conf::ConfigSection& configSection,
61 const std::string& filename);
62
Yingdi Yu58f33712014-04-16 16:57:47 -070063 inline void
64 reset();
65
66 inline bool
67 isEmpty();
68
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069protected:
70 virtual void
71 checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070072 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070073 const OnDataValidated& onValidated,
74 const OnDataValidationFailed& onValidationFailed,
75 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
76
77 virtual void
78 checkPolicy(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070079 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070080 const OnInterestValidated& onValidated,
81 const OnInterestValidationFailed& onValidationFailed,
82 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
83
84private:
85 template<class Packet, class OnValidated, class OnFailed>
86 void
87 checkSignature(const Packet& packet,
88 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070089 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070090 const OnValidated& onValidated,
91 const OnFailed& onValidationFailed,
92 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
93
94 template<class Packet, class OnValidated, class OnFailed>
95 void
96 onCertValidated(const shared_ptr<const Data>& signCertificate,
97 const shared_ptr<const Packet>& packet,
98 const OnValidated& onValidated,
99 const OnFailed& onValidationFailed);
100
101 template<class Packet, class OnFailed>
102 void
103 onCertFailed(const shared_ptr<const Data>& signCertificate,
104 const std::string& failureInfo,
105 const shared_ptr<const Packet>& packet,
106 const OnFailed& onValidationFailed);
107
108 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 onConfigRule(const security::conf::ConfigSection& section,
110 const std::string& filename);
111
112 void
113 onConfigTrustAnchor(const security::conf::ConfigSection& section,
114 const std::string& filename);
115
116private:
117 typedef security::conf::Rule<Interest> InterestRule;
118 typedef security::conf::Rule<Data> DataRule;
119 typedef std::vector<shared_ptr<InterestRule> > InterestRuleList;
120 typedef std::vector<shared_ptr<DataRule> > DataRuleList;
121 typedef std::map<Name, shared_ptr<IdentityCertificate> > AnchorList;
122
Yingdi Yu44d190c2014-04-16 17:05:46 -0700123 /**
124 * @brief gives whether validation should be preformed
125 *
126 * If false, no validation occurs, and any packet is considered validated immediately.
127 */
128 bool m_shouldValidate;
129
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700130 int m_stepLimit;
131 shared_ptr<CertificateCache> m_certificateCache;
132
133 InterestRuleList m_interestRules;
134 DataRuleList m_dataRules;
135 AnchorList m_anchors;
136};
137
Yingdi Yu58f33712014-04-16 16:57:47 -0700138inline void
139ValidatorConfig::reset()
140{
141 m_certificateCache->reset();
142 m_interestRules.clear();
143 m_dataRules.clear();
144 m_anchors.clear();
145}
146
147inline bool
148ValidatorConfig::isEmpty()
149{
150 if (m_certificateCache->isEmpty() &&
151 m_interestRules.empty() &&
152 m_dataRules.empty() &&
153 m_anchors.empty())
154 return true;
155 return false;
156}
157
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700158template<class Packet, class OnValidated, class OnFailed>
159void
160ValidatorConfig::checkSignature(const Packet& packet,
161 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700162 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700163 const OnValidated& onValidated,
164 const OnFailed& onValidationFailed,
165 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
166{
167 if (signature.getType() == Signature::Sha256)
168 {
169 SignatureSha256 sigSha256(signature);
170
171 if (verifySignature(packet, sigSha256))
172 return onValidated(packet.shared_from_this());
173 else
174 return onValidationFailed(packet.shared_from_this(),
175 "Sha256 Signature cannot be verified!");
176 }
177
178 if (signature.getType() == Signature::Sha256WithRsa)
179 {
180 SignatureSha256WithRsa sigSha256Rsa(signature);
181 Name keyLocatorName = sigSha256Rsa.getKeyLocator().getName();
182
183 shared_ptr<const Certificate> trustedCert;
184
185 AnchorList::const_iterator it = m_anchors.find(keyLocatorName);
186 if (m_anchors.end() == it)
187 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
188 else
189 trustedCert = it->second;
190
191 if (static_cast<bool>(trustedCert))
192 {
193 if (verifySignature(packet, sigSha256Rsa, trustedCert->getPublicKeyInfo()))
194 return onValidated(packet.shared_from_this());
195 else
196 return onValidationFailed(packet.shared_from_this(),
197 "Cannot verify signature");
198 }
199 else
200 {
201 OnDataValidated onCertValidated =
202 bind(&ValidatorConfig::onCertValidated<Packet, OnValidated, OnFailed>,
203 this, _1, packet.shared_from_this(), onValidated, onValidationFailed);
204
205 OnDataValidationFailed onCertValidationFailed =
206 bind(&ValidatorConfig::onCertFailed<Packet, OnFailed>,
207 this, _1, _2, packet.shared_from_this(), onValidationFailed);
208
209 Interest certInterest(keyLocatorName);
210
211 shared_ptr<ValidationRequest> nextStep =
212 make_shared<ValidationRequest>(boost::cref(certInterest),
213 onCertValidated,
214 onCertValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700215 1, nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700216
217 nextSteps.push_back(nextStep);
218 return;
219 }
220 }
221 return onValidationFailed(packet.shared_from_this(), "Unsupported Signature Type!");
222}
223
224template<class Packet, class OnValidated, class OnFailed>
225void
226ValidatorConfig::onCertValidated(const shared_ptr<const Data>& signCertificate,
227 const shared_ptr<const Packet>& packet,
228 const OnValidated& onValidated,
229 const OnFailed& onValidationFailed)
230{
231 shared_ptr<IdentityCertificate> certificate =
232 make_shared<IdentityCertificate>(boost::cref(*signCertificate));
233
234 if (!certificate->isTooLate() && !certificate->isTooEarly())
235 {
236 m_certificateCache->insertCertificate(certificate);
237
238 if (verifySignature(*packet, certificate->getPublicKeyInfo()))
239 return onValidated(packet);
240 else
241 return onValidationFailed(packet,
242 "Cannot verify signature: " +
243 packet->getName().toUri());
244 }
245 else
246 {
247 return onValidationFailed(packet,
248 "Signing certificate " +
249 signCertificate->getName().toUri() +
250 " is no longer valid.");
251 }
252}
253
254template<class Packet, class OnFailed>
255void
256ValidatorConfig::onCertFailed(const shared_ptr<const Data>& signCertificate,
257 const std::string& failureInfo,
258 const shared_ptr<const Packet>& packet,
259 const OnFailed& onValidationFailed)
260{
261 onValidationFailed(packet, failureInfo);
262}
263
264} // namespace ndn
265
266#endif // NDN_SECURITY_VALIDATOR_CONFIG_HPP