blob: be166e5eb7d950764993b3c3e91d0d6a79c8baa5 [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
15#include <cryptopp/rsa.h>
Yingdi Yu21157162014-02-28 13:02:34 -080016#include <cryptopp/files.h>
17#include <cryptopp/hex.h>
18
Yingdi Yu6ac97982014-01-30 14:49:21 -080019
20using namespace std;
21
Yingdi Yu21157162014-02-28 13:02:34 -080022INIT_LOGGER("ndn.Validator");
Yingdi Yu6ac97982014-01-30 14:49:21 -080023
24namespace ndn {
25
26const shared_ptr<Face> Validator::DefaultFace = shared_ptr<Face>();
27
28Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
29 : m_face(face)
30{}
31
32void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080033Validator::validate(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -080034 const OnInterestValidated &onValidated,
35 const OnInterestValidationFailed &onValidationFailed,
36 int stepCount)
37{
38 vector<shared_ptr<ValidationRequest> > nextSteps;
39 checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
40
41 if (!nextSteps.empty())
42 {
43 if(!static_cast<bool>(m_face))
44 throw Error("Face should be set prior to verify method to call");
45
46 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080047 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu6ac97982014-01-30 14:49:21 -080048 for(; it != nextSteps.end(); it++)
49 m_face->expressInterest((*it)->m_interest,
50 bind(&Validator::onData, this, _1, _2, *it),
51 bind(&Validator::onTimeout,
52 this, _1, (*it)->m_retry,
53 onFailure,
54 *it));
55 }
56 else
57 {
58 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
59 //No more further processes.
60 }
61}
62
63void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080064Validator::validate(const Data& data,
Yingdi Yu6ac97982014-01-30 14:49:21 -080065 const OnDataValidated &onValidated,
66 const OnDataValidationFailed &onValidationFailed,
67 int stepCount)
68{
69 vector<shared_ptr<ValidationRequest> > nextSteps;
70 checkPolicy(data, stepCount, onValidated, onValidationFailed, nextSteps);
71
72 if (!nextSteps.empty())
73 {
74 if(!static_cast<bool>(m_face))
75 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 Yu6ac97982014-01-30 14:49:21 -080079 for(; it != nextSteps.end(); it++)
80 m_face->expressInterest((*it)->m_interest,
81 bind(&Validator::onData, this, _1, _2, *it),
82 bind(&Validator::onTimeout,
83 this, _1, (*it)->m_retry,
84 onFailure,
85 *it));
86 }
87 else
88 {
89 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
90 //No more further processes.
91 }
92}
93
94void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080095Validator::onData(const Interest& interest,
96 Data& data,
97 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080098{
99 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
100}
101
102void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800103Validator::onTimeout(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800104 int retry,
105 const OnFailure &onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800106 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800107{
108 if (retry > 0)
109 // Issue the same expressInterest except decrement retry.
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800110 m_face->expressInterest(interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800111 bind(&Validator::onData, this, _1, _2, nextStep),
112 bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
113 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800114 onFailure("Cannot fetch cert: " + interest.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800115}
116
117bool
118Validator::verifySignature(const Data& data, const PublicKey& key)
119{
Yingdi Yu40587c02014-02-21 16:40:48 -0800120 try
121 {
122 switch(data.getSignature().getType()){
123 case Signature::Sha256WithRsa:
124 {
125 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
126 return verifySignature(data, sigSha256Rsa, key);
127 }
128 default:
129 {
130 _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
131 return false;
132 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800133 }
134 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800135 catch(Signature::Error &e)
136 {
137 _LOG_DEBUG("verifySignature: " << e.what());
138 return false;
139 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800140 return false;
141}
142
143bool
Yingdi Yu21157162014-02-28 13:02:34 -0800144Validator::verifySignature(const Interest& interest, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800145{
146 const Name &interestName = interest.getName();
147
Yingdi Yu17bc3012014-02-10 17:37:12 -0800148 if(interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800149 return false;
150
Yingdi Yu40587c02014-02-21 16:40:48 -0800151 try
152 {
153 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800154
Yingdi Yu40587c02014-02-21 16:40:48 -0800155 Signature sig(interestName[-2].blockFromValue(),
156 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800157
Yingdi Yu40587c02014-02-21 16:40:48 -0800158 switch(sig.getType()){
159 case Signature::Sha256WithRsa:
160 {
161 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800162
Yingdi Yu40587c02014-02-21 16:40:48 -0800163 return verifySignature(nameBlock.value(),
164 nameBlock.value_size() - interestName[-1].size(),
165 sigSha256Rsa, key);
166 }
167 default:
168 {
169 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
170 return false;
171 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800172 }
173 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800174 catch(Signature::Error &e)
175 {
176 _LOG_DEBUG("verifySignature: " << e.what());
177 return false;
178 }
179 catch(Block::Error &e)
180 {
181 _LOG_DEBUG("verifySignature: " << e.what());
182 return false;
183 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800184 return false;
185}
186
187bool
Yingdi Yu21157162014-02-28 13:02:34 -0800188Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800189{
Yingdi Yu40587c02014-02-21 16:40:48 -0800190 try
191 {
192 switch(sig.getType()){
193 case Signature::Sha256WithRsa:
194 {
195 SignatureSha256WithRsa sigSha256Rsa(sig);
196 return verifySignature(data, sigSha256Rsa, key);
197 }
198 default:
199 {
200 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
201 return false;
202 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800203 }
204 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800205 catch(Signature::Error &e)
206 {
207 _LOG_DEBUG("verifySignature: " << e.what());
208 return false;
209 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800210 return false;
211}
212
213bool
Yingdi Yu21157162014-02-28 13:02:34 -0800214Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa& sig, const PublicKey& key)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800215{
Yingdi Yu40587c02014-02-21 16:40:48 -0800216 try
217 {
218 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800219
Yingdi Yu40587c02014-02-21 16:40:48 -0800220 RSA::PublicKey publicKey;
221 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800222
Yingdi Yu40587c02014-02-21 16:40:48 -0800223 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
224 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800225
Yingdi Yu40587c02014-02-21 16:40:48 -0800226 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
227 return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
228 }
229 catch(CryptoPP::Exception& e)
230 {
231 _LOG_DEBUG("verifySignature: " << e.what());
232 return false;
233 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800234}
235
Yingdi Yu21157162014-02-28 13:02:34 -0800236bool
237Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256& sig)
238{
239 try
240 {
241 ConstBufferPtr buffer = crypto::sha256(buf, size);
242 const Block& sigValue = sig.getValue();
243
244 if(static_cast<bool>(buffer)
245 && buffer->size() == sigValue.value_size()
Yingdi Yu110881d2014-03-04 18:27:29 -0800246 && buffer->size() == crypto::SHA256_DIGEST_SIZE)
Yingdi Yu21157162014-02-28 13:02:34 -0800247 {
248
249 const uint8_t* p1 = buffer->buf();
250 const uint8_t* p2 = sigValue.value();
251
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700252 for(size_t i = 0; i < crypto::SHA256_DIGEST_SIZE; i++)
Yingdi Yu21157162014-02-28 13:02:34 -0800253 if(p1[i] != p2[i])
254 return false;
255 return true;
256 }
257 else
258 return false;
259 }
260 catch(CryptoPP::Exception& e)
261 {
262 _LOG_DEBUG("verifySignature: " << e.what());
263 return false;
264 }
265}
266
Yingdi Yufc40d872014-02-18 12:56:04 -0800267} // namespace ndn