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