All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
validator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
9 #include "common.hpp"
10 
11 #include "validator.hpp"
12 #include "../util/crypto.hpp"
13 
14 #include "cryptopp.hpp"
15 
16 using namespace std;
17 
18 namespace ndn {
19 
20 Validator::Validator()
21  : m_hasFace(false)
22  , m_face(*static_cast<Face*>(0))
23 {
24 }
25 
27  : m_hasFace(true)
28  , m_face(face)
29 {
30 }
31 
32 void
33 Validator::validate(const Interest& interest,
34  const OnInterestValidated& onValidated,
35  const OnInterestValidationFailed& onValidationFailed,
36  int nSteps)
37 {
38  vector<shared_ptr<ValidationRequest> > nextSteps;
39  checkPolicy(interest, nSteps, onValidated, onValidationFailed, nextSteps);
40 
41  if (!nextSteps.empty())
42  {
43  if (!m_hasFace)
44  {
45  onValidationFailed(interest.shared_from_this(),
46  "Require more information to validate the interest!");
47  return;
48  }
49 
50  vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
51  OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
52  for (; it != nextSteps.end(); it++)
53  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));
59  }
60  else
61  {
62  // If there is no nextStep,
63  // that means InterestPolicy has already been able to verify the Interest.
64  // No more further processes.
65  }
66 }
67 
68 void
69 Validator::validate(const Data& data,
70  const OnDataValidated& onValidated,
71  const OnDataValidationFailed& onValidationFailed,
72  int nSteps)
73 {
74  vector<shared_ptr<ValidationRequest> > nextSteps;
75  checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
76 
77  if (!nextSteps.empty())
78  {
79  if (!m_hasFace)
80  {
81  onValidationFailed(data.shared_from_this(),
82  "Require more information to validate the data!");
83  }
84 
85  vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
86  OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
87  for (; it != nextSteps.end(); it++)
88  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));
94  }
95  else
96  {
97  // If there is no nextStep,
98  // that means Data Policy has already been able to verify the Interest.
99  // No more further processes.
100  }
101 }
102 
103 void
104 Validator::onData(const Interest& interest,
105  const Data& data,
106  const shared_ptr<ValidationRequest>& nextStep)
107 {
108  validate(data, nextStep->m_onValidated, nextStep->m_onDataValidated, nextStep->m_nSteps);
109 }
110 
111 void
112 Validator::onTimeout(const Interest& interest,
113  int nRetrials,
114  const OnFailure& onFailure,
115  const shared_ptr<ValidationRequest>& nextStep)
116 {
117  if (nRetrials > 0)
118  // Issue the same expressInterest except decrement nRetrials.
119  m_face.expressInterest(interest,
120  bind(&Validator::onData, this, _1, _2, nextStep),
121  bind(&Validator::onTimeout, this, _1,
122  nRetrials - 1, onFailure, nextStep));
123  else
124  onFailure("Cannot fetch cert: " + interest.getName().toUri());
125 }
126 
127 bool
128 Validator::verifySignature(const Data& data, const PublicKey& key)
129 {
130  try
131  {
132  switch (data.getSignature().getType())
133  {
135  {
136  SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
137  return verifySignature(data, sigSha256Rsa, key);
138  }
139  default:
140  {
141  return false;
142  }
143  }
144  }
145  catch (Signature::Error& e)
146  {
147  return false;
148  }
149  return false;
150 }
151 
152 bool
153 Validator::verifySignature(const Interest& interest, const PublicKey& key)
154 {
155  const Name& interestName = interest.getName();
156 
157  if (interestName.size() < 2)
158  return false;
159 
160  try
161  {
162  const Block& nameBlock = interestName.wireEncode();
163 
164  Signature sig(interestName[-2].blockFromValue(),
165  interestName[-1].blockFromValue());
166 
167  switch (sig.getType())
168  {
170  {
171  SignatureSha256WithRsa sigSha256Rsa(sig);
172 
173  return verifySignature(nameBlock.value(),
174  nameBlock.value_size() - interestName[-1].size(),
175  sigSha256Rsa, key);
176  }
177  default:
178  {
179  return false;
180  }
181  }
182  }
183  catch (Signature::Error& e)
184  {
185  return false;
186  }
187  catch (Block::Error& e)
188  {
189  return false;
190  }
191  return false;
192 }
193 
194 bool
195 Validator::verifySignature(const Buffer& data, const Signature& sig, const PublicKey& key)
196 {
197  try
198  {
199  switch (sig.getType())
200  {
202  {
203  SignatureSha256WithRsa sigSha256Rsa(sig);
204  return verifySignature(data, sigSha256Rsa, key);
205  }
206  default:
207  {
208  return false;
209  }
210  }
211  }
212  catch (Signature::Error& e)
213  {
214  return false;
215  }
216  return false;
217 }
218 
219 bool
220 Validator::verifySignature(const uint8_t* buf,
221  const size_t size,
222  const SignatureSha256WithRsa& sig,
223  const PublicKey& key)
224 {
225  try
226  {
227  using namespace CryptoPP;
228 
229  RSA::PublicKey publicKey;
230  ByteQueue queue;
231 
232  queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
233  publicKey.Load(queue);
234 
235  RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
236  return verifier.VerifyMessage(buf, size,
237  sig.getValue().value(),
238  sig.getValue().value_size());
239  }
240  catch (CryptoPP::Exception& e)
241  {
242  return false;
243  }
244 }
245 
246 bool
247 Validator::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 
254  if (static_cast<bool>(buffer) &&
255  buffer->size() == sigValue.value_size() &&
256  buffer->size() == crypto::SHA256_DIGEST_SIZE)
257  {
258 
259  const uint8_t* p1 = buffer->buf();
260  const uint8_t* p2 = sigValue.value();
261 
262  return 0 == memcmp(p1, p2, crypto::SHA256_DIGEST_SIZE);
263  }
264  else
265  return false;
266  }
267  catch (CryptoPP::Exception& e)
268  {
269  return false;
270  }
271 }
272 
273 } // namespace ndn
Representing of SHA256-with-RSA signature in a data packet.
const Name & getName() const
Definition: interest.hpp:182
Representing of SHA256 signature in a data packet.
static const size_t SHA256_DIGEST_SIZE
number of octets in a SHA256 digest
Definition: crypto.hpp:26
Class representing wire element of the NDN packet.
Definition: block.hpp:26
An Interest holds a Name and other fields for an interest.
Definition: interest.hpp:24
const Block & getValue() const
Definition: signature.hpp:79
uint32_t getType() const
Definition: signature.hpp:50
ptr_lib::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:17
function< void(const shared_ptr< const Data > &)> OnDataValidated
Callback to report a successful Data validation.
void validate(const Data &data, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed)
Validate Data and call either onValidated or onValidationFailed.
Definition: validator.hpp:53
virtual void checkPolicy(const Data &data, int nSteps, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed, std::vector< shared_ptr< ValidationRequest > > &nextSteps)=0
Check the Data against policy and return the next validation step if necessary.
uint8_t * buf()
Get pointer to the first byte of the buffer (alternative version)
Definition: buffer.hpp:86
function< void(const shared_ptr< const Data > &, const std::string &)> OnDataValidationFailed
Callback to report a failed Data validation.
Abstraction to communicate with local or remote NDN forwarder.
Definition: face.hpp:54
size_t size() const
Get the number of components.
Definition: name.hpp:329
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
const PendingInterestId * expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout=OnTimeout())
Express Interest.
Definition: face.cpp:125
size_t value_size() const
Definition: block.hpp:455
size_t wireEncode(EncodingImpl< T > &block) const
Fast encoding or block size estimation.
Definition: name.hpp:711
const Signature & getSignature() const
Definition: data.hpp:450
function< void(const shared_ptr< const Interest > &, const std::string &)> OnInterestValidationFailed
Callback to report a failed Interest validation.
const Buffer & get() const
Definition: public-key.hpp:47
static bool verifySignature(const Data &data, const PublicKey &publicKey)
Verify the data using the publicKey.
Definition: validator.cpp:128
const uint8_t * value() const
Definition: block.hpp:446
ConstBufferPtr sha256(const uint8_t *data, size_t dataLength)
Compute the sha-256 digest of data.
Definition: crypto.cpp:33
Class representing a general-use automatically managed/resized buffer.
Definition: buffer.hpp:28
function< void(const shared_ptr< const Interest > &)> OnInterestValidated
Callback to report a successful Interest validation.
Error that can be thrown from Block.
Definition: block.hpp:34
A Signature is storage for the signature-related information (info and value) in a Data packet...
Definition: signature.hpp:15