blob: 8ab76e3f1477306ec4896627c60c180a13dcd454 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu6ac97982014-01-30 14:49:21 -08002/**
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/>
22 * @author Jeff Thompson <jefft0@remap.ucla.edu>
Yingdi Yu6ac97982014-01-30 14:49:21 -080023 */
24
Yingdi Yufc40d872014-02-18 12:56:04 -080025#ifndef NDN_SECURITY_VALIDATOR_HPP
26#define NDN_SECURITY_VALIDATOR_HPP
Yingdi Yu6ac97982014-01-30 14:49:21 -080027
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080028#include "../common.hpp"
29
Yingdi Yu6ac97982014-01-30 14:49:21 -080030#include "../data.hpp"
31#include "../face.hpp"
32#include "public-key.hpp"
33#include "signature-sha256-with-rsa.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080034#include "signature-sha256.hpp"
Yingdi Yu6ac97982014-01-30 14:49:21 -080035#include "validation-request.hpp"
36
37namespace ndn {
38/**
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070039 * @brief Validator is one of the main classes of the security library.
Yingdi Yu6ac97982014-01-30 14:49:21 -080040 *
41 * The Validator class provides the interfaces for packet validation.
42 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070043class Validator
44{
Yingdi Yu6ac97982014-01-30 14:49:21 -080045public:
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070046 class Error : public std::runtime_error
47 {
48 public:
49 explicit
50 Error(const std::string& what)
51 : std::runtime_error(what)
52 {
53 }
54 };
Yingdi Yu6ac97982014-01-30 14:49:21 -080055
Yingdi Yu96e64062014-04-15 19:57:33 -070056 Validator();
Yingdi Yu6ac97982014-01-30 14:49:21 -080057
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070058 explicit
Yingdi Yu96e64062014-04-15 19:57:33 -070059 Validator(Face& face);
Yingdi Yu6ac97982014-01-30 14:49:21 -080060
61 /**
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070062 * @brief Validate Data and call either onValidated or onValidationFailed.
63 *
Yingdi Yu6ac97982014-01-30 14:49:21 -080064 * @param data The Data with the signature to check.
65 * @param onValidated If the Data is validated, this calls onValidated(data).
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070066 * @param onValidationFailed If validation fails, this calls onValidationFailed(data).
Yingdi Yu6ac97982014-01-30 14:49:21 -080067 */
68 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069 validate(const Data& data,
70 const OnDataValidated& onValidated,
71 const OnDataValidationFailed& onValidationFailed)
72 {
73 validate(data, onValidated, onValidationFailed, 0);
74 }
Yingdi Yu6ac97982014-01-30 14:49:21 -080075
76 /**
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070077 * @brief Validate Interest and call either onValidated or onValidationFailed.
78 *
Yingdi Yu6ac97982014-01-30 14:49:21 -080079 * @param interest The Interest with the signature to check.
80 * @param onValidated If the Interest is validated, this calls onValidated(interest).
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070081 * @param onValidationFailed If validation fails, this calls onValidationFailed(interest).
Yingdi Yu6ac97982014-01-30 14:49:21 -080082 */
83 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070084 validate(const Interest& interest,
85 const OnInterestValidated& onValidated,
86 const OnInterestValidationFailed& onValidationFailed)
87 {
88 validate(interest, onValidated, onValidationFailed, 0);
89 }
Yingdi Yu6ac97982014-01-30 14:49:21 -080090
91 /*****************************************
92 * verifySignature method set *
93 *****************************************/
94
95 /// @brief Verify the data using the publicKey.
96 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070097 verifySignature(const Data& data, const PublicKey& publicKey);
Yingdi Yu6ac97982014-01-30 14:49:21 -080098
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070099 /**
100 * @brief Verify the signed Interest using the publicKey.
101 *
102 * (Note the signature covers the first n-2 name components).
103 */
Yingdi Yu6ac97982014-01-30 14:49:21 -0800104 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 verifySignature(const Interest& interest, const PublicKey& publicKey);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800106
107 /// @brief Verify the blob using the publicKey against the signature.
108 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 verifySignature(const Buffer& blob, const Signature& sig, const PublicKey& publicKey);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800110
111 /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
112 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700113 verifySignature(const Data& data,
114 const SignatureSha256WithRsa& sig,
115 const PublicKey& publicKey)
116 {
117 return verifySignature(data.wireEncode().value(),
118 data.wireEncode().value_size() - data.getSignature().getValue().size(),
119 sig, publicKey);
120 }
121
122 /** @brief Verify the interest using the publicKey against the SHA256-RSA signature.
123 *
124 * (Note the signature covers the first n-2 name components).
125 */
126 static bool
127 verifySignature(const Interest& interest,
128 const SignatureSha256WithRsa& sig,
129 const PublicKey& publicKey)
130 {
131 if (interest.getName().size() < 2)
132 return false;
133
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700134 const Name& name = interest.getName();
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700135
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700136 return verifySignature(name.wireEncode().value(),
137 name.wireEncode().value_size() - name[-1].size(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700138 sig, publicKey);
139 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800140
141 /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
142 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700143 verifySignature(const Buffer& blob,
144 const SignatureSha256WithRsa& sig,
145 const PublicKey& publicKey)
146 {
147 return verifySignature(blob.buf(), blob.size(), sig, publicKey);
148 }
149
Yingdi Yu6ac97982014-01-30 14:49:21 -0800150 /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
151 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700152 verifySignature(const uint8_t* buf,
153 const size_t size,
154 const SignatureSha256WithRsa& sig,
155 const PublicKey& publicKey);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800156
Yingdi Yu21157162014-02-28 13:02:34 -0800157
158 /// @brief Verify the data against the SHA256 signature.
159 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700160 verifySignature(const Data& data, const SignatureSha256& sig)
161 {
162 return verifySignature(data.wireEncode().value(),
163 data.wireEncode().value_size() -
164 data.getSignature().getValue().size(),
165 sig);
166 }
167
168 /** @brief Verify the interest against the SHA256 signature.
169 *
170 * (Note the signature covers the first n-2 name components).
171 */
172 static bool
173 verifySignature(const Interest& interest, const SignatureSha256& sig)
174 {
175 if (interest.getName().size() < 2)
176 return false;
177
178 Name signedName = interest.getName().getPrefix(-2);
179
180 return verifySignature(signedName.wireEncode().value(),
181 signedName.wireEncode().value_size(),
182 sig);
183 }
Yingdi Yu21157162014-02-28 13:02:34 -0800184
185 /// @brief Verify the blob against the SHA256 signature.
186 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700187 verifySignature(const Buffer& blob, const SignatureSha256& sig)
188 {
189 return verifySignature (blob.buf(), blob.size(), sig);
190 }
191
Yingdi Yu21157162014-02-28 13:02:34 -0800192 /// @brief Verify the blob against the SHA256 signature.
193 static bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700194 verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig);
Yingdi Yu21157162014-02-28 13:02:34 -0800195
Yingdi Yu6ac97982014-01-30 14:49:21 -0800196protected:
197 /**
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700198 * @brief Check the Data against policy and return the next validation step if necessary.
Yingdi Yu6ac97982014-01-30 14:49:21 -0800199 *
200 * If there is no next validation step, that validation MUST have been done.
201 * i.e., either onValidated or onValidationFailed callback is invoked.
202 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700203 * @param data The Data to check.
204 * @param nSteps The number of validation steps that have been done.
205 * @param onValidated If the Data is validated, this calls onValidated(data)
206 * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
207 * @param nextSteps On return, contains the next validation step
Yingdi Yu6ac97982014-01-30 14:49:21 -0800208 */
209 virtual void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700210 checkPolicy(const Data& data,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700211 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700212 const OnDataValidated& onValidated,
213 const OnDataValidationFailed& onValidationFailed,
214 std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800215
216 /**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700217 * @brief Check the Interest against validation policy and return the next validation step
218 * if necessary.
Yingdi Yu6ac97982014-01-30 14:49:21 -0800219 *
220 * If there is no next validation step, that validation MUST have been done.
221 * i.e., either onValidated or onValidationFailed callback is invoked.
222 *
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700223 * @param interest The Interest to check.
224 * @param nSteps The number of validation steps that have been done.
225 * @param onValidated If the Interest is validated, this calls onValidated(data)
226 * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
227 * @param nextSteps On return, contains the next validation step
Yingdi Yu6ac97982014-01-30 14:49:21 -0800228 */
229 virtual void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700230 checkPolicy(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700231 int nSteps,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700232 const OnInterestValidated& onValidated,
233 const OnInterestValidationFailed& onValidationFailed,
234 std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800235
236private:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700237 typedef function<void(const std::string&)> OnFailure;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700238
Yingdi Yu6ac97982014-01-30 14:49:21 -0800239 /// @brief Process the received certificate.
240 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700241 onData(const Interest& interest,
242 const Data& data,
243 const shared_ptr<ValidationRequest>& nextStep);
244
Yingdi Yu6ac97982014-01-30 14:49:21 -0800245 /// @brief Re-express the interest if it times out.
246 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700247 onTimeout(const Interest& interest,
248 int retry,
249 const OnFailure& onFailure,
250 const shared_ptr<ValidationRequest>& nextStep);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800251
252 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700253 validate(const Data& data,
254 const OnDataValidated& onValidated,
255 const OnDataValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700256 int nSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800257
258 void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700259 validate(const Interest& interest,
260 const OnInterestValidated& onValidated,
261 const OnInterestValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700262 int nSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800263
264protected:
Yingdi Yu96e64062014-04-15 19:57:33 -0700265 bool m_hasFace;
266 Face& m_face;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800267};
268
Yingdi Yufc40d872014-02-18 12:56:04 -0800269} // namespace ndn
Yingdi Yu6ac97982014-01-30 14:49:21 -0800270
Yingdi Yufc40d872014-02-18 12:56:04 -0800271#endif //NDN_SECURITY_VALIDATOR_HPP