blob: cabd082a7da785a78527bbe343a7561ef5cdf8f8 [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"
13
14#include <cryptopp/rsa.h>
15
16using namespace std;
17
18INIT_LOGGER("ndn::Validator");
19
20namespace ndn {
21
22const shared_ptr<Face> Validator::DefaultFace = shared_ptr<Face>();
23
24Validator::Validator(shared_ptr<Face> face /* = DefaultFace */)
25 : m_face(face)
26{}
27
28void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080029Validator::validate(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -080030 const OnInterestValidated &onValidated,
31 const OnInterestValidationFailed &onValidationFailed,
32 int stepCount)
33{
34 vector<shared_ptr<ValidationRequest> > nextSteps;
35 checkPolicy(interest, stepCount, onValidated, onValidationFailed, nextSteps);
36
37 if (!nextSteps.empty())
38 {
39 if(!static_cast<bool>(m_face))
40 throw Error("Face should be set prior to verify method to call");
41
42 vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
Yingdi Yu40587c02014-02-21 16:40:48 -080043 OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
Yingdi Yu6ac97982014-01-30 14:49:21 -080044 for(; it != nextSteps.end(); it++)
45 m_face->expressInterest((*it)->m_interest,
46 bind(&Validator::onData, this, _1, _2, *it),
47 bind(&Validator::onTimeout,
48 this, _1, (*it)->m_retry,
49 onFailure,
50 *it));
51 }
52 else
53 {
54 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
55 //No more further processes.
56 }
57}
58
59void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080060Validator::validate(const Data& data,
Yingdi Yu6ac97982014-01-30 14:49:21 -080061 const OnDataValidated &onValidated,
62 const OnDataValidationFailed &onValidationFailed,
63 int stepCount)
64{
65 vector<shared_ptr<ValidationRequest> > nextSteps;
66 checkPolicy(data, stepCount, onValidated, onValidationFailed, nextSteps);
67
68 if (!nextSteps.empty())
69 {
70 if(!static_cast<bool>(m_face))
71 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 Yu6ac97982014-01-30 14:49:21 -080075 for(; it != nextSteps.end(); it++)
76 m_face->expressInterest((*it)->m_interest,
77 bind(&Validator::onData, this, _1, _2, *it),
78 bind(&Validator::onTimeout,
79 this, _1, (*it)->m_retry,
80 onFailure,
81 *it));
82 }
83 else
84 {
85 //If there is no nextStep, that means InterestPolicy has already been able to verify the Interest.
86 //No more further processes.
87 }
88}
89
90void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080091Validator::onData(const Interest& interest,
92 Data& data,
93 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -080094{
95 validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_stepCount);
96}
97
98void
Alexander Afanasyev0222fba2014-02-09 23:16:02 -080099Validator::onTimeout(const Interest& interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800100 int retry,
101 const OnFailure &onFailure,
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800102 const shared_ptr<ValidationRequest>& nextStep)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800103{
104 if (retry > 0)
105 // Issue the same expressInterest except decrement retry.
Alexander Afanasyev0222fba2014-02-09 23:16:02 -0800106 m_face->expressInterest(interest,
Yingdi Yu6ac97982014-01-30 14:49:21 -0800107 bind(&Validator::onData, this, _1, _2, nextStep),
108 bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
109 else
Yingdi Yu40587c02014-02-21 16:40:48 -0800110 onFailure("Cannot fetch cert: " + interest.getName().toUri());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800111}
112
113bool
114Validator::verifySignature(const Data& data, const PublicKey& key)
115{
Yingdi Yu40587c02014-02-21 16:40:48 -0800116 try
117 {
118 switch(data.getSignature().getType()){
119 case Signature::Sha256WithRsa:
120 {
121 SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
122 return verifySignature(data, sigSha256Rsa, key);
123 }
124 default:
125 {
126 _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
127 return false;
128 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800129 }
130 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800131 catch(Signature::Error &e)
132 {
133 _LOG_DEBUG("verifySignature: " << e.what());
134 return false;
135 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800136 return false;
137}
138
139bool
140Validator::verifySignature(const Interest &interest, const PublicKey &key)
141{
142 const Name &interestName = interest.getName();
143
Yingdi Yu17bc3012014-02-10 17:37:12 -0800144 if(interestName.size() < 2)
Yingdi Yu6ac97982014-01-30 14:49:21 -0800145 return false;
146
Yingdi Yu40587c02014-02-21 16:40:48 -0800147 try
148 {
149 const Block& nameBlock = interestName.wireEncode();
Yingdi Yu6ac97982014-01-30 14:49:21 -0800150
Yingdi Yu40587c02014-02-21 16:40:48 -0800151 Signature sig(interestName[-2].blockFromValue(),
152 interestName[-1].blockFromValue());
Yingdi Yu6ac97982014-01-30 14:49:21 -0800153
Yingdi Yu40587c02014-02-21 16:40:48 -0800154 switch(sig.getType()){
155 case Signature::Sha256WithRsa:
156 {
157 SignatureSha256WithRsa sigSha256Rsa(sig);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800158
Yingdi Yu40587c02014-02-21 16:40:48 -0800159 return verifySignature(nameBlock.value(),
160 nameBlock.value_size() - interestName[-1].size(),
161 sigSha256Rsa, key);
162 }
163 default:
164 {
165 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
166 return false;
167 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800168 }
169 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800170 catch(Signature::Error &e)
171 {
172 _LOG_DEBUG("verifySignature: " << e.what());
173 return false;
174 }
175 catch(Block::Error &e)
176 {
177 _LOG_DEBUG("verifySignature: " << e.what());
178 return false;
179 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800180 return false;
181}
182
183bool
184Validator::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
185{
Yingdi Yu40587c02014-02-21 16:40:48 -0800186 try
187 {
188 switch(sig.getType()){
189 case Signature::Sha256WithRsa:
190 {
191 SignatureSha256WithRsa sigSha256Rsa(sig);
192 return verifySignature(data, sigSha256Rsa, key);
193 }
194 default:
195 {
196 _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
197 return false;
198 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800199 }
200 }
Yingdi Yu40587c02014-02-21 16:40:48 -0800201 catch(Signature::Error &e)
202 {
203 _LOG_DEBUG("verifySignature: " << e.what());
204 return false;
205 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800206 return false;
207}
208
209bool
Yingdi Yu6ac97982014-01-30 14:49:21 -0800210Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa &sig, const PublicKey &key)
211{
Yingdi Yu40587c02014-02-21 16:40:48 -0800212 try
213 {
214 using namespace CryptoPP;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800215
Yingdi Yu40587c02014-02-21 16:40:48 -0800216 RSA::PublicKey publicKey;
217 ByteQueue queue;
Yingdi Yu6ac97982014-01-30 14:49:21 -0800218
Yingdi Yu40587c02014-02-21 16:40:48 -0800219 queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
220 publicKey.Load(queue);
Yingdi Yu6ac97982014-01-30 14:49:21 -0800221
Yingdi Yu40587c02014-02-21 16:40:48 -0800222 RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
223 return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
224 }
225 catch(CryptoPP::Exception& e)
226 {
227 _LOG_DEBUG("verifySignature: " << e.what());
228 return false;
229 }
Yingdi Yu6ac97982014-01-30 14:49:21 -0800230}
231
Yingdi Yufc40d872014-02-18 12:56:04 -0800232} // namespace ndn