blob: c02cf2f2ff1aab89e10685df3e507ac47e742e34 [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
45 /**
46 * \deprecated Use the other version of the constructor
47 */
48 ValidatorConfig(const shared_ptr<Face>& face,
49 const shared_ptr<CertificateCache>& certificateCache = DEFAULT_CERTIFICATE_CACHE,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070050 const int stepLimit = 10);
51
52 virtual
53 ~ValidatorConfig()
54 {
55 }
56
57 void
58 load(const std::string& filename);
59
60 void
61 load(const std::string& input, const std::string& filename);
62
63 void
64 load(std::istream& input, const std::string& filename);
65
Yingdi Yudfa9d732014-04-09 09:53:01 -070066 void
67 load(const security::conf::ConfigSection& configSection,
68 const std::string& filename);
69
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070070protected:
71 virtual void
72 checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070073 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070074 const OnDataValidated& onValidated,
75 const OnDataValidationFailed& onValidationFailed,
76 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
77
78 virtual void
79 checkPolicy(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070080 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070081 const OnInterestValidated& onValidated,
82 const OnInterestValidationFailed& onValidationFailed,
83 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
84
85private:
86 template<class Packet, class OnValidated, class OnFailed>
87 void
88 checkSignature(const Packet& packet,
89 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070090 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070091 const OnValidated& onValidated,
92 const OnFailed& onValidationFailed,
93 std::vector<shared_ptr<ValidationRequest> >& nextSteps);
94
95 template<class Packet, class OnValidated, class OnFailed>
96 void
97 onCertValidated(const shared_ptr<const Data>& signCertificate,
98 const shared_ptr<const Packet>& packet,
99 const OnValidated& onValidated,
100 const OnFailed& onValidationFailed);
101
102 template<class Packet, class OnFailed>
103 void
104 onCertFailed(const shared_ptr<const Data>& signCertificate,
105 const std::string& failureInfo,
106 const shared_ptr<const Packet>& packet,
107 const OnFailed& onValidationFailed);
108
109 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700110 onConfigRule(const security::conf::ConfigSection& section,
111 const std::string& filename);
112
113 void
114 onConfigTrustAnchor(const security::conf::ConfigSection& section,
115 const std::string& filename);
116
117private:
118 typedef security::conf::Rule<Interest> InterestRule;
119 typedef security::conf::Rule<Data> DataRule;
120 typedef std::vector<shared_ptr<InterestRule> > InterestRuleList;
121 typedef std::vector<shared_ptr<DataRule> > DataRuleList;
122 typedef std::map<Name, shared_ptr<IdentityCertificate> > AnchorList;
123
124 int m_stepLimit;
125 shared_ptr<CertificateCache> m_certificateCache;
126
127 InterestRuleList m_interestRules;
128 DataRuleList m_dataRules;
129 AnchorList m_anchors;
130};
131
132template<class Packet, class OnValidated, class OnFailed>
133void
134ValidatorConfig::checkSignature(const Packet& packet,
135 const Signature& signature,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700136 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700137 const OnValidated& onValidated,
138 const OnFailed& onValidationFailed,
139 std::vector<shared_ptr<ValidationRequest> >& nextSteps)
140{
141 if (signature.getType() == Signature::Sha256)
142 {
143 SignatureSha256 sigSha256(signature);
144
145 if (verifySignature(packet, sigSha256))
146 return onValidated(packet.shared_from_this());
147 else
148 return onValidationFailed(packet.shared_from_this(),
149 "Sha256 Signature cannot be verified!");
150 }
151
152 if (signature.getType() == Signature::Sha256WithRsa)
153 {
154 SignatureSha256WithRsa sigSha256Rsa(signature);
155 Name keyLocatorName = sigSha256Rsa.getKeyLocator().getName();
156
157 shared_ptr<const Certificate> trustedCert;
158
159 AnchorList::const_iterator it = m_anchors.find(keyLocatorName);
160 if (m_anchors.end() == it)
161 trustedCert = m_certificateCache->getCertificate(keyLocatorName);
162 else
163 trustedCert = it->second;
164
165 if (static_cast<bool>(trustedCert))
166 {
167 if (verifySignature(packet, sigSha256Rsa, trustedCert->getPublicKeyInfo()))
168 return onValidated(packet.shared_from_this());
169 else
170 return onValidationFailed(packet.shared_from_this(),
171 "Cannot verify signature");
172 }
173 else
174 {
175 OnDataValidated onCertValidated =
176 bind(&ValidatorConfig::onCertValidated<Packet, OnValidated, OnFailed>,
177 this, _1, packet.shared_from_this(), onValidated, onValidationFailed);
178
179 OnDataValidationFailed onCertValidationFailed =
180 bind(&ValidatorConfig::onCertFailed<Packet, OnFailed>,
181 this, _1, _2, packet.shared_from_this(), onValidationFailed);
182
183 Interest certInterest(keyLocatorName);
184
185 shared_ptr<ValidationRequest> nextStep =
186 make_shared<ValidationRequest>(boost::cref(certInterest),
187 onCertValidated,
188 onCertValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700189 1, nSteps + 1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700190
191 nextSteps.push_back(nextStep);
192 return;
193 }
194 }
195 return onValidationFailed(packet.shared_from_this(), "Unsupported Signature Type!");
196}
197
198template<class Packet, class OnValidated, class OnFailed>
199void
200ValidatorConfig::onCertValidated(const shared_ptr<const Data>& signCertificate,
201 const shared_ptr<const Packet>& packet,
202 const OnValidated& onValidated,
203 const OnFailed& onValidationFailed)
204{
205 shared_ptr<IdentityCertificate> certificate =
206 make_shared<IdentityCertificate>(boost::cref(*signCertificate));
207
208 if (!certificate->isTooLate() && !certificate->isTooEarly())
209 {
210 m_certificateCache->insertCertificate(certificate);
211
212 if (verifySignature(*packet, certificate->getPublicKeyInfo()))
213 return onValidated(packet);
214 else
215 return onValidationFailed(packet,
216 "Cannot verify signature: " +
217 packet->getName().toUri());
218 }
219 else
220 {
221 return onValidationFailed(packet,
222 "Signing certificate " +
223 signCertificate->getName().toUri() +
224 " is no longer valid.");
225 }
226}
227
228template<class Packet, class OnFailed>
229void
230ValidatorConfig::onCertFailed(const shared_ptr<const Data>& signCertificate,
231 const std::string& failureInfo,
232 const shared_ptr<const Packet>& packet,
233 const OnFailed& onValidationFailed)
234{
235 onValidationFailed(packet, failureInfo);
236}
237
238} // namespace ndn
239
240#endif // NDN_SECURITY_VALIDATOR_CONFIG_HPP