blob: d0c808b186c22c5698928154a89d152f2a72b5e5 [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
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080029Validator::validate(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -080030 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();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080043 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this());
Yingdi Yu6ac97982014-01-30 14:49:21 -080044 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
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080060Validator::validate(const Data& data,
Yingdi Yu6ac97982014-01-30 14:49:21 -080061 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();
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080074 OnFailure onFailure = bind(onValidationFailed, data.shared_from_this());
Yingdi Yu6ac97982014-01-30 14:49:21 -080075 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
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080091Validator::onData(const Interest& interest,
92 Data& data,
93 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080094{
95 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
96}
97
98void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080099Validator::onTimeout(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800100 int retry,
101 const OnFailure &onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800102 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800103{
104 if (retry > 0)
105 // Issue the same expressInterest except decrement retry.
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800106 m_face->expressInterest(interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800107 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 {
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800125 _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800126 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
Yingdi Yu17bc3012014-02-10 17:37:12 -0800141 if(interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800142 return false;
143
144 try{
Yingdi Yu17bc3012014-02-10 17:37:12 -0800145 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800146
Yingdi Yu17bc3012014-02-10 17:37:12 -0800147 Signature sig(interestName[-2].blockFromValue(),
148 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800149
150 switch(sig.getType()){
151 case Signature::Sha256WithRsa:
152 {
153 SignatureSha256WithRsa sigSha256Rsa(sig);
154
155 return verifySignature(nameBlock.value(),
Yingdi Yu17bc3012014-02-10 17:37:12 -0800156 nameBlock.value_size() - interestName[-1].size(),
Yingdi Yu6ac97982014-01-30 14:49:21 -0800157 sigSha256Rsa, key);
158 }
159 default:
160 {
161 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
162 return false;
163 }
164 }
165 }catch(Signature::Error &e){
166 _LOG_DEBUG("verifySignature: " << e.what());
167 return false;
168 }catch(Block::Error &e){
169 _LOG_DEBUG("verifySignature: " << e.what());
170 return false;
171 }
172 return false;
173}
174
175bool
176Validator::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
177{
178 try{
179 switch(sig.getType()){
180 case Signature::Sha256WithRsa:
181 {
182 SignatureSha256WithRsa sigSha256Rsa(sig);
183 return verifySignature(data, sigSha256Rsa, key);
184 }
185 default:
186 {
187 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
188 return false;
189 }
190 }
191 }catch(Signature::Error &e){
192 _LOG_DEBUG("verifySignature: " << e.what());
193 return false;
194 }
195 return false;
196}
197
198bool
199Validator::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
200{
201 using namespace CryptoPP;
202
203 bool result = false;
204
205 RSA::PublicKey publicKey;
206 ByteQueue queue;
207
208 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
209 publicKey.Load(queue);
210
211 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
212 result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
213 sig.getValue().value(), sig.getValue().value_size());
214
215 _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
216
217 return result;
218}
219
220bool
221Validator::verifySignature(const Buffer& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
222{
223 using namespace CryptoPP;
224
225 bool result = false;
226
227 RSA::PublicKey publicKey;
228 ByteQueue queue;
229
230 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
231 publicKey.Load(queue);
232
233 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
234 result = verifier.VerifyMessage(data.buf(), data.size(),
235 sig.getValue().value(), sig.getValue().value_size());
236
237 return result;
238}
239
240bool
241Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa &sig, const PublicKey &key)
242{
243 using namespace CryptoPP;
244
245 bool result = false;
246
247 RSA::PublicKey publicKey;
248 ByteQueue queue;
249
250 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
251 publicKey.Load(queue);
252
253 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
254 result = verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
255
256 return result;
257}
258
Yingdi Yufc40d872014-02-18 12:56:04 -0800259} // namespace ndn