blob: cb5be23d913685396e19242fa32b5d30be79d3c5 [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
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070024const shared_ptr<Face> Validator::DEFAULT_FACE;
Yingdi Yu6ac97982014-01-30 14:49:21 -080025
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070026Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
Yingdi Yu6ac97982014-01-30 14:49:21 -080027 : m_face(face)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070028{
29}
Yingdi Yu6ac97982014-01-30 14:49:21 -080030
31void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070032Validator::validate(const Interest& interest,
33 const OnInterestValidated& onValidated,
34 const OnInterestValidationFailed& onValidationFailed,
Yingdi Yu6ac97982014-01-30 14:49:21 -080035 int stepCount)
36{
37 vector<shared_ptr<ValidationRequest> > nextSteps;
38 checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070039
Yingdi Yu6ac97982014-01-30 14:49:21 -080040 if (!nextSteps.empty())
41 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070042 if (!static_cast<bool>(m_face))
43 throw Error("Face should be set before calling validate method");
44
Yingdi Yu6ac97982014-01-30 14:49:21 -080045 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080046 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070047 for (; it != nextSteps.end(); it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -080048 m_face->expressInterest((*it)->m_interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070049 bind(&Validator::onData, this, _1, _2, *it),
50 bind(&Validator::onTimeout,
51 this, _1, (*it)->m_retry,
52 onFailure,
Yingdi Yu6ac97982014-01-30 14:49:21 -080053 *it));
54 }
55 else
56 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070057 // If there is no nextStep,
58 // that means InterestPolicy has already been able to verify the Interest.
59 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -080060 }
61}
62
63void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070064Validator::validate(const Data& data,
65 const OnDataValidated& onValidated,
66 const OnDataValidationFailed& onValidationFailed,
Yingdi Yu6ac97982014-01-30 14:49:21 -080067 int stepCount)
68{
69 vector<shared_ptr<ValidationRequest> > nextSteps;
70 checkPolicy(data, stepCount, onValidated, onValidationFailed, nextSteps);
71
72 if (!nextSteps.empty())
73 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070074 if (!static_cast<bool>(m_face))
Yingdi Yu6ac97982014-01-30 14:49:21 -080075 throw Error("Face should be set prior to verify method to call");
76
77 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080078 OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070079 for (; it != nextSteps.end(); it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -080080 m_face->expressInterest((*it)->m_interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070081 bind(&Validator::onData, this, _1, _2, *it),
82 bind(&Validator::onTimeout,
83 this, _1, (*it)->m_retry,
Yingdi Yu6ac97982014-01-30 14:49:21 -080084 onFailure,
85 *it));
86 }
87 else
88 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070089 // If there is no nextStep,
90 // that means Data Policy has already been able to verify the Interest.
91 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -080092 }
93}
94
95void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070096Validator::onData(const Interest& interest,
97 const Data& data,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080098 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080099{
100 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
101}
102
103void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700104Validator::onTimeout(const Interest& interest,
105 int retry,
106 const OnFailure& onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800107 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800108{
109 if (retry > 0)
110 // Issue the same expressInterest except decrement retry.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700111 m_face->expressInterest(interest,
112 bind(&Validator::onData, this, _1, _2, nextStep),
Yingdi Yu6ac97982014-01-30 14:49:21 -0800113 bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
114 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800115 onFailure("Cannot fetch cert: " + interest.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800116}
117
118bool
119Validator::verifySignature(const Data& data, const PublicKey& key)
120{
Yingdi Yu40587c02014-02-21 16:40:48 -0800121 try
122 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700123 switch (data.getSignature().getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800124 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700125 case Signature::Sha256WithRsa:
126 {
127 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
128 return verifySignature(data, sigSha256Rsa, key);
129 }
130 default:
131 {
132 _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
133 return false;
134 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800135 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800136 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700137 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800138 {
139 _LOG_DEBUG("verifySignature: " << e.what());
140 return false;
141 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800142 return false;
143}
144
145bool
Yingdi Yu21157162014-02-28 13:02:34 -0800146Validator::verifySignature(const Interest& interest, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800147{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700148 const Name& interestName = interest.getName();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800149
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700150 if (interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800151 return false;
152
Yingdi Yu40587c02014-02-21 16:40:48 -0800153 try
154 {
155 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800156
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700157 Signature sig(interestName[-2].blockFromValue(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800158 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800159
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700160 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800161 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700162 case Signature::Sha256WithRsa:
163 {
164 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800165
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700166 return verifySignature(nameBlock.value(),
167 nameBlock.value_size() - interestName[-1].size(),
168 sigSha256Rsa, key);
169 }
170 default:
171 {
172 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
173 return false;
174 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800175 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800176 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700177 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800178 {
179 _LOG_DEBUG("verifySignature: " << e.what());
180 return false;
181 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700182 catch (const Block::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800183 {
184 _LOG_DEBUG("verifySignature: " << e.what());
185 return false;
186 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800187 return false;
188}
189
190bool
Yingdi Yu21157162014-02-28 13:02:34 -0800191Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800192{
Yingdi Yu40587c02014-02-21 16:40:48 -0800193 try
194 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700195 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800196 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700197 case Signature::Sha256WithRsa:
198 {
199 SignatureSha256WithRsa sigSha256Rsa(sig);
200 return verifySignature(data, sigSha256Rsa, key);
201 }
202 default:
203 {
204 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
205 return false;
206 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800207 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800208 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700209 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800210 {
211 _LOG_DEBUG("verifySignature: " << e.what());
212 return false;
213 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800214 return false;
215}
216
217bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700218Validator::verifySignature(const uint8_t* buf,
219 const size_t size,
220 const SignatureSha256WithRsa& sig,
221 const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800222{
Yingdi Yu40587c02014-02-21 16:40:48 -0800223 try
224 {
225 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800226
Yingdi Yu40587c02014-02-21 16:40:48 -0800227 RSA::PublicKey publicKey;
228 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800229
Yingdi Yu40587c02014-02-21 16:40:48 -0800230 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
231 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800232
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700233 RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
234 return verifier.VerifyMessage(buf, size,
235 sig.getValue().value(),
236 sig.getValue().value_size());
Yingdi Yu40587c02014-02-21 16:40:48 -0800237 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700238 catch (const CryptoPP::Exception& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800239 {
240 _LOG_DEBUG("verifySignature: " << e.what());
241 return false;
242 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800243}
244
Yingdi Yu21157162014-02-28 13:02:34 -0800245bool
246Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig)
247{
248 try
249 {
250 ConstBufferPtr buffer = crypto::sha256(buf, size);
251 const Block& sigValue = sig.getValue();
252
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700253 if (static_cast<bool>(buffer) &&
254 buffer->size() == sigValue.value_size() &&
255 buffer->size() == crypto::SHA256_DIGEST_SIZE)
Yingdi Yu21157162014-02-28 13:02:34 -0800256 {
257
258 const uint8_t* p1 = buffer->buf();
259 const uint8_t* p2 = sigValue.value();
260
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700261 return 0 == memcmp(p1, p2, crypto::SHA256_DIGEST_SIZE);
Yingdi Yu21157162014-02-28 13:02:34 -0800262 }
263 else
264 return false;
265 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700266 catch (const CryptoPP::Exception& e)
Yingdi Yu21157162014-02-28 13:02:34 -0800267 {
268 _LOG_DEBUG("verifySignature: " << e.what());
269 return false;
270 }
271}
272
Yingdi Yufc40d872014-02-18 12:56:04 -0800273} // namespace ndn