blob: 029f76646d8a43a54d388a45022d0ede3a2a01c8 [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"
Yingdi Yu21157162014-02-28 13:02:34 -080012#include "../util/crypto.hpp"
Yingdi Yu6ac97982014-01-30 14:49:21 -080013
Junxiao Shi482ccc52014-03-31 13:05:24 -070014#include "cryptopp.hpp"
Yingdi Yu21157162014-02-28 13:02:34 -080015
Yingdi Yu6ac97982014-01-30 14:49:21 -080016using namespace std;
17
Yingdi Yu6ac97982014-01-30 14:49:21 -080018namespace ndn {
19
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070020const shared_ptr<Face> Validator::DEFAULT_FACE;
Yingdi Yu6ac97982014-01-30 14:49:21 -080021
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
Yingdi Yu6ac97982014-01-30 14:49:21 -080023 : m_face(face)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070024{
25}
Yingdi Yu6ac97982014-01-30 14:49:21 -080026
27void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070028Validator::validate(const Interest& interest,
29 const OnInterestValidated& onValidated,
30 const OnInterestValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070031 int nSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080032{
33 vector<shared_ptr<ValidationRequest> > nextSteps;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070034 checkPolicy(interest, nSteps, onValidated, onValidationFailed, nextSteps);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070035
Yingdi Yu6ac97982014-01-30 14:49:21 -080036 if (!nextSteps.empty())
37 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070038 if (!static_cast<bool>(m_face))
39 throw Error("Face should be set before calling validate method");
40
Yingdi Yu6ac97982014-01-30 14:49:21 -080041 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080042 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070043 for (; it != nextSteps.end(); it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -080044 m_face->expressInterest((*it)->m_interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070045 bind(&Validator::onData, this, _1, _2, *it),
46 bind(&Validator::onTimeout,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070047 this, _1, (*it)->m_nRetrials,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070048 onFailure,
Yingdi Yu6ac97982014-01-30 14:49:21 -080049 *it));
50 }
51 else
52 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070053 // If there is no nextStep,
54 // that means InterestPolicy has already been able to verify the Interest.
55 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -080056 }
57}
58
59void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070060Validator::validate(const Data& data,
61 const OnDataValidated& onValidated,
62 const OnDataValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070063 int nSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080064{
65 vector<shared_ptr<ValidationRequest> > nextSteps;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070066 checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -080067
68 if (!nextSteps.empty())
69 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070070 if (!static_cast<bool>(m_face))
Yingdi Yu6ac97982014-01-30 14:49:21 -080071 throw Error("Face should be set prior to verify method to call");
72
73 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080074 OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070075 for (; it != nextSteps.end(); it++)
Yingdi Yu6ac97982014-01-30 14:49:21 -080076 m_face->expressInterest((*it)->m_interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070077 bind(&Validator::onData, this, _1, _2, *it),
78 bind(&Validator::onTimeout,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070079 this, _1, (*it)->m_nRetrials,
Yingdi Yu6ac97982014-01-30 14:49:21 -080080 onFailure,
81 *it));
82 }
83 else
84 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070085 // If there is no nextStep,
86 // that means Data Policy has already been able to verify the Interest.
87 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -080088 }
89}
90
91void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070092Validator::onData(const Interest& interest,
93 const Data& data,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080094 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080095{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070096 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_nSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -080097}
98
99void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700100Validator::onTimeout(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700101 int nRetrials,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700102 const OnFailure& onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800103 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800104{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700105 if (nRetrials > 0)
106 // Issue the same expressInterest except decrement nRetrials.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700107 m_face->expressInterest(interest,
108 bind(&Validator::onData, this, _1, _2, nextStep),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700109 bind(&Validator::onTimeout, this, _1,
110 nRetrials - 1, onFailure, nextStep));
Yingdi Yu6ac97982014-01-30 14:49:21 -0800111 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 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700120 switch (data.getSignature().getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800121 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700122 case Signature::Sha256WithRsa:
123 {
124 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
125 return verifySignature(data, sigSha256Rsa, key);
126 }
127 default:
128 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700129 return false;
130 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800131 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800132 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700133 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800134 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800135 return false;
136 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800137 return false;
138}
139
140bool
Yingdi Yu21157162014-02-28 13:02:34 -0800141Validator::verifySignature(const Interest& interest, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800142{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700143 const Name& interestName = interest.getName();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800144
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700145 if (interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800146 return false;
147
Yingdi Yu40587c02014-02-21 16:40:48 -0800148 try
149 {
150 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800151
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700152 Signature sig(interestName[-2].blockFromValue(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800153 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800154
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700155 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800156 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700157 case Signature::Sha256WithRsa:
158 {
159 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800160
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700161 return verifySignature(nameBlock.value(),
162 nameBlock.value_size() - interestName[-1].size(),
163 sigSha256Rsa, key);
164 }
165 default:
166 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700167 return false;
168 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800169 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800170 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700171 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800172 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800173 return false;
174 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700175 catch (const Block::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800176 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800177 return false;
178 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800179 return false;
180}
181
182bool
Yingdi Yu21157162014-02-28 13:02:34 -0800183Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800184{
Yingdi Yu40587c02014-02-21 16:40:48 -0800185 try
186 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700187 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800188 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700189 case Signature::Sha256WithRsa:
190 {
191 SignatureSha256WithRsa sigSha256Rsa(sig);
192 return verifySignature(data, sigSha256Rsa, key);
193 }
194 default:
195 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700196 return false;
197 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800198 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800199 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700200 catch (const Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800201 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800202 return false;
203 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800204 return false;
205}
206
207bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700208Validator::verifySignature(const uint8_t* buf,
209 const size_t size,
210 const SignatureSha256WithRsa& sig,
211 const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800212{
Yingdi Yu40587c02014-02-21 16:40:48 -0800213 try
214 {
215 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800216
Yingdi Yu40587c02014-02-21 16:40:48 -0800217 RSA::PublicKey publicKey;
218 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800219
Yingdi Yu40587c02014-02-21 16:40:48 -0800220 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
221 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800222
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700223 RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
224 return verifier.VerifyMessage(buf, size,
225 sig.getValue().value(),
226 sig.getValue().value_size());
Yingdi Yu40587c02014-02-21 16:40:48 -0800227 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700228 catch (const CryptoPP::Exception& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800229 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800230 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
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700242 if (static_cast<bool>(buffer) &&
243 buffer->size() == sigValue.value_size() &&
244 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
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700250 return 0 == memcmp(p1, p2, crypto::SHA256_DIGEST_SIZE);
Yingdi Yu21157162014-02-28 13:02:34 -0800251 }
252 else
253 return false;
254 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700255 catch (const CryptoPP::Exception& e)
Yingdi Yu21157162014-02-28 13:02:34 -0800256 {
Yingdi Yu21157162014-02-28 13:02:34 -0800257 return false;
258 }
259}
260
Yingdi Yufc40d872014-02-18 12:56:04 -0800261} // namespace ndn