blob: 7f9792695b923a646d641c27e96312ab78fdc6e2 [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 Yu96e64062014-04-15 19:57:33 -070020Validator::Validator()
21 : m_hasFace(false)
22 , m_face(*static_cast<Face*>(0))
23{
24}
Yingdi Yu6ac97982014-01-30 14:49:21 -080025
Yingdi Yu96e64062014-04-15 19:57:33 -070026Validator::Validator(Face& face)
27 : m_hasFace(true)
28 , m_face(face)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070029{
30}
Yingdi Yu6ac97982014-01-30 14:49:21 -080031
32void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070033Validator::validate(const Interest& interest,
34 const OnInterestValidated& onValidated,
35 const OnInterestValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070036 int nSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080037{
38 vector<shared_ptr<ValidationRequest> > nextSteps;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070039 checkPolicy(interest, nSteps, onValidated, onValidationFailed, nextSteps);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070040
Yingdi Yu6ac97982014-01-30 14:49:21 -080041 if (!nextSteps.empty())
42 {
Yingdi Yu96e64062014-04-15 19:57:33 -070043 if (!m_hasFace)
44 {
45 onValidationFailed(interest.shared_from_this(),
46 "Require more information to validate the interest!");
47 return;
48 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070049
Yingdi Yu6ac97982014-01-30 14:49:21 -080050 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080051 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070052 for (; it != nextSteps.end(); it++)
Yingdi Yu96e64062014-04-15 19:57:33 -070053 m_face.expressInterest((*it)->m_interest,
54 bind(&Validator::onData, this, _1, _2, *it),
55 bind(&Validator::onTimeout,
56 this, _1, (*it)->m_nRetrials,
57 onFailure,
58 *it));
Yingdi Yu6ac97982014-01-30 14:49:21 -080059 }
60 else
61 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070062 // If there is no nextStep,
63 // that means InterestPolicy has already been able to verify the Interest.
64 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -080065 }
66}
67
68void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069Validator::validate(const Data& data,
70 const OnDataValidated& onValidated,
71 const OnDataValidationFailed& onValidationFailed,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070072 int nSteps)
Yingdi Yu6ac97982014-01-30 14:49:21 -080073{
74 vector<shared_ptr<ValidationRequest> > nextSteps;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070075 checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -080076
77 if (!nextSteps.empty())
78 {
Yingdi Yu96e64062014-04-15 19:57:33 -070079 if (!m_hasFace)
80 {
81 onValidationFailed(data.shared_from_this(),
82 "Require more information to validate the data!");
83 }
Yingdi Yu6ac97982014-01-30 14:49:21 -080084
85 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080086 OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070087 for (; it != nextSteps.end(); it++)
Yingdi Yu96e64062014-04-15 19:57:33 -070088 m_face.expressInterest((*it)->m_interest,
89 bind(&Validator::onData, this, _1, _2, *it),
90 bind(&Validator::onTimeout,
91 this, _1, (*it)->m_nRetrials,
92 onFailure,
93 *it));
Yingdi Yu6ac97982014-01-30 14:49:21 -080094 }
95 else
96 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070097 // If there is no nextStep,
98 // that means Data Policy has already been able to verify the Interest.
99 // No more further processes.
Yingdi Yu6ac97982014-01-30 14:49:21 -0800100 }
101}
102
103void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700104Validator::onData(const Interest& interest,
105 const Data& data,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800106 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800107{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700108 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_nSteps);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800109}
110
111void
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700112Validator::onTimeout(const Interest& interest,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700113 int nRetrials,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700114 const OnFailure& onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800115 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800116{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700117 if (nRetrials > 0)
118 // Issue the same expressInterest except decrement nRetrials.
Yingdi Yu96e64062014-04-15 19:57:33 -0700119 m_face.expressInterest(interest,
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700120 bind(&Validator::onData, this, _1, _2, nextStep),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700121 bind(&Validator::onTimeout, this, _1,
122 nRetrials - 1, onFailure, nextStep));
Yingdi Yu6ac97982014-01-30 14:49:21 -0800123 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800124 onFailure("Cannot fetch cert: " + interest.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800125}
126
127bool
128Validator::verifySignature(const Data& data, const PublicKey& key)
129{
Yingdi Yu40587c02014-02-21 16:40:48 -0800130 try
131 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700132 switch (data.getSignature().getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800133 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700134 case Signature::Sha256WithRsa:
135 {
136 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
137 return verifySignature(data, sigSha256Rsa, key);
138 }
139 default:
140 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700141 return false;
142 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800143 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800144 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700145 catch (Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800146 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800147 return false;
148 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800149 return false;
150}
151
152bool
Yingdi Yu21157162014-02-28 13:02:34 -0800153Validator::verifySignature(const Interest& interest, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800154{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700155 const Name& interestName = interest.getName();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800156
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700157 if (interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800158 return false;
159
Yingdi Yu40587c02014-02-21 16:40:48 -0800160 try
161 {
162 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800163
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700164 Signature sig(interestName[-2].blockFromValue(),
Yingdi Yu40587c02014-02-21 16:40:48 -0800165 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800166
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700167 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800168 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700169 case Signature::Sha256WithRsa:
170 {
171 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800172
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700173 return verifySignature(nameBlock.value(),
174 nameBlock.value_size() - interestName[-1].size(),
175 sigSha256Rsa, key);
176 }
177 default:
178 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700179 return false;
180 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800181 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800182 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700183 catch (Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800184 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800185 return false;
186 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700187 catch (Block::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800188 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800189 return false;
190 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800191 return false;
192}
193
194bool
Yingdi Yu21157162014-02-28 13:02:34 -0800195Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800196{
Yingdi Yu40587c02014-02-21 16:40:48 -0800197 try
198 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700199 switch (sig.getType())
Yingdi Yu40587c02014-02-21 16:40:48 -0800200 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700201 case Signature::Sha256WithRsa:
202 {
203 SignatureSha256WithRsa sigSha256Rsa(sig);
204 return verifySignature(data, sigSha256Rsa, key);
205 }
206 default:
207 {
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700208 return false;
209 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800210 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800211 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700212 catch (Signature::Error& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800213 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800214 return false;
215 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800216 return false;
217}
218
219bool
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700220Validator::verifySignature(const uint8_t* buf,
221 const size_t size,
222 const SignatureSha256WithRsa& sig,
223 const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800224{
Yingdi Yu40587c02014-02-21 16:40:48 -0800225 try
226 {
227 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800228
Yingdi Yu40587c02014-02-21 16:40:48 -0800229 RSA::PublicKey publicKey;
230 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800231
Yingdi Yu40587c02014-02-21 16:40:48 -0800232 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
233 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800234
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700235 RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
236 return verifier.VerifyMessage(buf, size,
237 sig.getValue().value(),
238 sig.getValue().value_size());
Yingdi Yu40587c02014-02-21 16:40:48 -0800239 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700240 catch (CryptoPP::Exception& e)
Yingdi Yu40587c02014-02-21 16:40:48 -0800241 {
Yingdi Yu40587c02014-02-21 16:40:48 -0800242 return false;
243 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800244}
245
Yingdi Yu21157162014-02-28 13:02:34 -0800246bool
247Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig)
248{
249 try
250 {
251 ConstBufferPtr buffer = crypto::sha256(buf, size);
252 const Block& sigValue = sig.getValue();
253
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700254 if (static_cast<bool>(buffer) &&
255 buffer->size() == sigValue.value_size() &&
256 buffer->size() == crypto::SHA256_DIGEST_SIZE)
Yingdi Yu21157162014-02-28 13:02:34 -0800257 {
258
259 const uint8_t* p1 = buffer->buf();
260 const uint8_t* p2 = sigValue.value();
261
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700262 return 0 == memcmp(p1, p2, crypto::SHA256_DIGEST_SIZE);
Yingdi Yu21157162014-02-28 13:02:34 -0800263 }
264 else
265 return false;
266 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700267 catch (CryptoPP::Exception& e)
Yingdi Yu21157162014-02-28 13:02:34 -0800268 {
Yingdi Yu21157162014-02-28 13:02:34 -0800269 return false;
270 }
271}
272
Yingdi Yufc40d872014-02-18 12:56:04 -0800273} // namespace ndn