blob: 9440d84e59d9ad49c9c3257682fa0248b3dc9437 [file] [log] [blame]
Yingdi Yu6ac97982014-01-30 14:49:21 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
9#if __clang__
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wreorder"
12#pragma clang diagnostic ignored "-Wtautological-compare"
13#pragma clang diagnostic ignored "-Wunused-variable"
14#pragma clang diagnostic ignored "-Wunused-function"
15#elif __GNUC__
16#pragma GCC diagnostic ignored "-Wreorder"
17#pragma GCC diagnostic ignored "-Wunused-variable"
18#pragma GCC diagnostic ignored "-Wunused-function"
19#endif
20
21#include "validator.hpp"
22#include "../util/logging.hpp"
23
24#include <cryptopp/rsa.h>
25
26using namespace std;
27
28INIT_LOGGER("ndn::Validator");
29
30namespace ndn {
31
32const shared_ptr<Face> Validator::DefaultFace = shared_ptr<Face>();
33
34Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
35 : m_face(face)
36{}
37
38void
39Validator::validate(const shared_ptr<const Interest> &interest,
40 const OnInterestValidated &onValidated,
41 const OnInterestValidationFailed &onValidationFailed,
42 int stepCount)
43{
44 vector<shared_ptr<ValidationRequest> > nextSteps;
45 checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
46
47 if (!nextSteps.empty())
48 {
49 if(!static_cast<bool>(m_face))
50 throw Error("Face should be set prior to verify method to call");
51
52 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
53 OnFailure onFailure = bind(onValidationFailed, interest);
54 for(; it != nextSteps.end(); it++)
55 m_face->expressInterest((*it)->m_interest,
56 bind(&Validator::onData, this, _1, _2, *it),
57 bind(&Validator::onTimeout,
58 this, _1, (*it)->m_retry,
59 onFailure,
60 *it));
61 }
62 else
63 {
64 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
65 //No more further processes.
66 }
67}
68
69void
70Validator::validate(const shared_ptr<const Data> &data,
71 const OnDataValidated &onValidated,
72 const OnDataValidationFailed &onValidationFailed,
73 int stepCount)
74{
75 vector<shared_ptr<ValidationRequest> > nextSteps;
76 checkPolicy(data, stepCount, onValidated, onValidationFailed, nextSteps);
77
78 if (!nextSteps.empty())
79 {
80 if(!static_cast<bool>(m_face))
81 throw Error("Face should be set prior to verify method to call");
82
83 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
84 OnFailure onFailure = bind(onValidationFailed, data);
85 for(; it != nextSteps.end(); it++)
86 m_face->expressInterest((*it)->m_interest,
87 bind(&Validator::onData, this, _1, _2, *it),
88 bind(&Validator::onTimeout,
89 this, _1, (*it)->m_retry,
90 onFailure,
91 *it));
92 }
93 else
94 {
95 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
96 //No more further processes.
97 }
98}
99
100void
101Validator::onData(const shared_ptr<const Interest> &interest,
102 const shared_ptr<const Data> &data,
103 shared_ptr<ValidationRequest> nextStep)
104{
105 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
106}
107
108void
109Validator::onTimeout(const shared_ptr<const Interest> &interest,
110 int retry,
111 const OnFailure &onFailure,
112 shared_ptr<ValidationRequest> nextStep)
113{
114 if (retry > 0)
115 // Issue the same expressInterest except decrement retry.
116 m_face->expressInterest(*interest,
117 bind(&Validator::onData, this, _1, _2, nextStep),
118 bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
119 else
120 onFailure();
121}
122
123bool
124Validator::verifySignature(const Data& data, const PublicKey& key)
125{
126 try{
127 switch(data.getSignature().getType()){
128 case Signature::Sha256WithRsa:
129 {
130 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
131 return verifySignature(data, sigSha256Rsa, key);
132 }
133 default:
134 {
135 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
136 return false;
137 }
138 }
139 }catch(Signature::Error &e){
140 _LOG_DEBUG("verifySignature: " << e.what());
141 return false;
142 }
143 return false;
144}
145
146bool
147Validator::verifySignature(const Interest &interest, const PublicKey &key)
148{
149 const Name &interestName = interest.getName();
150
151 if(interestName.size() < 3)
152 return false;
153
154 try{
155 const Block &nameBlock = interestName.wireEncode();
156
157 if(nameBlock.getAll().size() != interestName.size()) //HACK!! we should change it when Name::Component is changed to derive from Block.
158 const_cast<Block&>(nameBlock).parse();
159
160 Signature sig((++nameBlock.getAll().rbegin())->blockFromValue(),
161 (nameBlock.getAll().rbegin())->blockFromValue());
162
163 switch(sig.getType()){
164 case Signature::Sha256WithRsa:
165 {
166 SignatureSha256WithRsa sigSha256Rsa(sig);
167
168 return verifySignature(nameBlock.value(),
169 nameBlock.value_size() - (nameBlock.getAll().rbegin())->size(),
170 sigSha256Rsa, key);
171 }
172 default:
173 {
174 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
175 return false;
176 }
177 }
178 }catch(Signature::Error &e){
179 _LOG_DEBUG("verifySignature: " << e.what());
180 return false;
181 }catch(Block::Error &e){
182 _LOG_DEBUG("verifySignature: " << e.what());
183 return false;
184 }
185 return false;
186}
187
188bool
189Validator::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
190{
191 try{
192 switch(sig.getType()){
193 case Signature::Sha256WithRsa:
194 {
195 SignatureSha256WithRsa sigSha256Rsa(sig);
196 return verifySignature(data, sigSha256Rsa, key);
197 }
198 default:
199 {
200 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
201 return false;
202 }
203 }
204 }catch(Signature::Error &e){
205 _LOG_DEBUG("verifySignature: " << e.what());
206 return false;
207 }
208 return false;
209}
210
211bool
212Validator::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
213{
214 using namespace CryptoPP;
215
216 bool result = false;
217
218 RSA::PublicKey publicKey;
219 ByteQueue queue;
220
221 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
222 publicKey.Load(queue);
223
224 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
225 result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
226 sig.getValue().value(), sig.getValue().value_size());
227
228 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
229
230 return result;
231}
232
233bool
234Validator::verifySignature(const Buffer& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
235{
236 using namespace CryptoPP;
237
238 bool result = false;
239
240 RSA::PublicKey publicKey;
241 ByteQueue queue;
242
243 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
244 publicKey.Load(queue);
245
246 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
247 result = verifier.VerifyMessage(data.buf(), data.size(),
248 sig.getValue().value(), sig.getValue().value_size());
249
250 return result;
251}
252
253bool
254Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa &sig, const PublicKey &key)
255{
256 using namespace CryptoPP;
257
258 bool result = false;
259
260 RSA::PublicKey publicKey;
261 ByteQueue queue;
262
263 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
264 publicKey.Load(queue);
265
266 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
267 result = verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
268
269 return result;
270}
271
272}