blob: f1d80357ec546fd073aee433857d0c86c21f306b [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"
Yingdi Yu21157162014-02-28 13:02:34 -080013#include "../util/crypto.hpp"
Yingdi Yu6ac97982014-01-30 14:49:21 -080014
Junxiao Shi482ccc52014-03-31 13:05:24 -070015#include "cryptopp.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080016
Yingdi Yu6ac97982014-01-30 14:49:21 -080017
18using namespace std;
19
Yingdi Yu21157162014-02-28 13:02:34 -080020INIT_LOGGER("ndn.Validator");
Yingdi Yu6ac97982014-01-30 14:49:21 -080021
22namespace ndn {
23
24const shared_ptr<Face> Validator::DefaultFace = shared_ptr<Face>();
25
26Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
27 : m_face(face)
28{}
29
30void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080031Validator::validate(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -080032 const OnInterestValidated &onValidated,
33 const OnInterestValidationFailed &onValidationFailed,
34 int stepCount)
35{
36 vector<shared_ptr<ValidationRequest> > nextSteps;
37 checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
38
39 if (!nextSteps.empty())
40 {
41 if(!static_cast<bool>(m_face))
42 throw Error("Face should be set prior to verify method to call");
43
44 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080045 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu6ac97982014-01-30 14:49:21 -080046 for(; it != nextSteps.end(); it++)
47 m_face->expressInterest((*it)->m_interest,
48 bind(&Validator::onData, this, _1, _2, *it),
49 bind(&Validator::onTimeout,
50 this, _1, (*it)->m_retry,
51 onFailure,
52 *it));
53 }
54 else
55 {
56 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
57 //No more further processes.
58 }
59}
60
61void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080062Validator::validate(const Data& data,
Yingdi Yu6ac97982014-01-30 14:49:21 -080063 const OnDataValidated &onValidated,
64 const OnDataValidationFailed &onValidationFailed,
65 int stepCount)
66{
67 vector<shared_ptr<ValidationRequest> > nextSteps;
68 checkPolicy(data, stepCount, onValidated, onValidationFailed, nextSteps);
69
70 if (!nextSteps.empty())
71 {
72 if(!static_cast<bool>(m_face))
73 throw Error("Face should be set prior to verify method to call");
74
75 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080076 OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
Yingdi Yu6ac97982014-01-30 14:49:21 -080077 for(; it != nextSteps.end(); it++)
78 m_face->expressInterest((*it)->m_interest,
79 bind(&Validator::onData, this, _1, _2, *it),
80 bind(&Validator::onTimeout,
81 this, _1, (*it)->m_retry,
82 onFailure,
83 *it));
84 }
85 else
86 {
87 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
88 //No more further processes.
89 }
90}
91
92void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080093Validator::onData(const Interest& interest,
94 Data& data,
95 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080096{
97 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
98}
99
100void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800101Validator::onTimeout(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800102 int retry,
103 const OnFailure &onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800104 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800105{
106 if (retry > 0)
107 // Issue the same expressInterest except decrement retry.
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800108 m_face->expressInterest(interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800109 bind(&Validator::onData, this, _1, _2, nextStep),
110 bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
111 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800112 onFailure("Cannot fetch cert: " + interest.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800113}
114
115bool
116Validator::verifySignature(const Data& data, const PublicKey& key)
117{
Yingdi Yu40587c02014-02-21 16:40:48 -0800118 try
119 {
120 switch(data.getSignature().getType()){
121 case Signature::Sha256WithRsa:
122 {
123 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
124 return verifySignature(data, sigSha256Rsa, key);
125 }
126 default:
127 {
128 _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
129 return false;
130 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800131 }
132 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800133 catch(Signature::Error &e)
134 {
135 _LOG_DEBUG("verifySignature: " << e.what());
136 return false;
137 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800138 return false;
139}
140
141bool
Yingdi Yu21157162014-02-28 13:02:34 -0800142Validator::verifySignature(const Interest& interest, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800143{
144 const Name &interestName = interest.getName();
145
Yingdi Yu17bc3012014-02-10 17:37:12 -0800146 if(interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800147 return false;
148
Yingdi Yu40587c02014-02-21 16:40:48 -0800149 try
150 {
151 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800152
Yingdi Yu40587c02014-02-21 16:40:48 -0800153 Signature sig(interestName[-2].blockFromValue(),
154 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800155
Yingdi Yu40587c02014-02-21 16:40:48 -0800156 switch(sig.getType()){
157 case Signature::Sha256WithRsa:
158 {
159 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800160
Yingdi Yu40587c02014-02-21 16:40:48 -0800161 return verifySignature(nameBlock.value(),
162 nameBlock.value_size() - interestName[-1].size(),
163 sigSha256Rsa, key);
164 }
165 default:
166 {
167 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
168 return false;
169 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800170 }
171 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800172 catch(Signature::Error &e)
173 {
174 _LOG_DEBUG("verifySignature: " << e.what());
175 return false;
176 }
177 catch(Block::Error &e)
178 {
179 _LOG_DEBUG("verifySignature: " << e.what());
180 return false;
181 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800182 return false;
183}
184
185bool
Yingdi Yu21157162014-02-28 13:02:34 -0800186Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800187{
Yingdi Yu40587c02014-02-21 16:40:48 -0800188 try
189 {
190 switch(sig.getType()){
191 case Signature::Sha256WithRsa:
192 {
193 SignatureSha256WithRsa sigSha256Rsa(sig);
194 return verifySignature(data, sigSha256Rsa, key);
195 }
196 default:
197 {
198 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
199 return false;
200 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800201 }
202 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800203 catch(Signature::Error &e)
204 {
205 _LOG_DEBUG("verifySignature: " << e.what());
206 return false;
207 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800208 return false;
209}
210
211bool
Yingdi Yu21157162014-02-28 13:02:34 -0800212Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800213{
Yingdi Yu40587c02014-02-21 16:40:48 -0800214 try
215 {
216 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800217
Yingdi Yu40587c02014-02-21 16:40:48 -0800218 RSA::PublicKey publicKey;
219 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800220
Yingdi Yu40587c02014-02-21 16:40:48 -0800221 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
222 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800223
Yingdi Yu40587c02014-02-21 16:40:48 -0800224 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
225 return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
226 }
227 catch(CryptoPP::Exception& e)
228 {
229 _LOG_DEBUG("verifySignature: " << e.what());
230 return false;
231 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800232}
233
Yingdi Yu21157162014-02-28 13:02:34 -0800234bool
235Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig)
236{
237 try
238 {
239 ConstBufferPtr buffer = crypto::sha256(buf, size);
240 const Block& sigValue = sig.getValue();
241
242 if(static_cast<bool>(buffer)
243 && buffer->size() == sigValue.value_size()
Yingdi Yu110881d2014-03-04 18:27:29 -0800244 && buffer->size() == crypto::SHA256_DIGEST_SIZE)
Yingdi Yu21157162014-02-28 13:02:34 -0800245 {
246
247 const uint8_t* p1 = buffer->buf();
248 const uint8_t* p2 = sigValue.value();
249
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700250 for(size_t i = 0; i < crypto::SHA256_DIGEST_SIZE; i++)
Yingdi Yu21157162014-02-28 13:02:34 -0800251 if(p1[i] != p2[i])
252 return false;
253 return true;
254 }
255 else
256 return false;
257 }
258 catch(CryptoPP::Exception& e)
259 {
260 _LOG_DEBUG("verifySignature: " << e.what());
261 return false;
262 }
263}
264
Yingdi Yufc40d872014-02-18 12:56:04 -0800265} // namespace ndn