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