All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
checker.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
8 #ifndef NDN_SECURITY_CONF_CHECKER_HPP
9 #define NDN_SECURITY_CONF_CHECKER_HPP
10 
11 #include "key-locator-checker.hpp"
12 #include "../../util/io.hpp"
13 #include <boost/algorithm/string.hpp>
14 
15 #include "common.hpp"
16 
17 namespace ndn {
18 namespace security {
19 namespace conf {
20 
21 class Checker
22 {
23 public:
24  typedef function<void(const shared_ptr<const Interest>&)> OnInterestChecked;
25  typedef function<void(const shared_ptr<const Interest>&, const std::string&)> OnInterestCheckFailed;
26  typedef function<void(const shared_ptr<const Data>&)> OnDataChecked;
27  typedef function<void(const shared_ptr<const Data>&, const std::string&)> OnDataCheckFailed;
28 
29 
30  virtual
32  {
33  }
34 
45  virtual int8_t
46  check(const Data& data,
47  const OnDataChecked& onValidated,
48  const OnDataCheckFailed& onValidationFailed) = 0;
49 
60  virtual int8_t
61  check(const Interest& interest,
62  const OnInterestChecked& onValidated,
63  const OnInterestCheckFailed& onValidationFailed) = 0;
64 };
65 
66 class CustomizedChecker : public Checker
67 {
68  enum
69  {
70  INTEREST_SIG_VALUE = -1,
71  INTEREST_SIG_INFO = -2
72  };
73 
74 public:
75  CustomizedChecker(uint32_t sigType,
76  shared_ptr<KeyLocatorChecker> keyLocatorChecker)
77  : m_sigType(sigType)
78  , m_keyLocatorChecker(keyLocatorChecker)
79  {
80  if (m_sigType == Signature::Sha256WithRsa && !static_cast<bool>(m_keyLocatorChecker))
81  throw Error("Strong signature requires KeyLocatorChecker");
82  }
83 
84  virtual int8_t
85  check(const Data& data,
86  const OnDataChecked& onValidated,
87  const OnDataCheckFailed& onValidationFailed)
88  {
89  return check(data, data.getSignature(), onValidated, onValidationFailed);
90  }
91 
92  virtual int8_t
93  check(const Interest& interest,
94  const OnInterestChecked& onValidated,
95  const OnInterestCheckFailed& onValidationFailed)
96  {
97  try
98  {
99  const Name& interestName = interest.getName();
100  Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
101  interestName[INTEREST_SIG_VALUE].blockFromValue());
102  return check(interest, signature, onValidated, onValidationFailed);
103  }
104  catch (Signature::Error& e)
105  {
106  onValidationFailed(interest.shared_from_this(), "Invalid signature");
107  return -1;
108  }
109  catch (Tlv::Error& e)
110  {
111  onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
112  return -1;
113  }
114  }
115 
116 private:
117  template<class Packet, class OnValidated, class OnFailed>
118  int8_t
119  check(const Packet& packet, const Signature& signature,
120  const OnValidated& onValidated,
121  const OnFailed& onValidationFailed)
122  {
123  if (m_sigType != signature.getType())
124  {
125  onValidationFailed(packet.shared_from_this(),
126  "Signature type does not match: " +
127  boost::lexical_cast<std::string>(m_sigType) +
128  "!=" +
129  boost::lexical_cast<std::string>(signature.getType()));
130  return -1;
131  }
132 
133  switch (signature.getType())
134  {
136  {
137  try
138  {
139  SignatureSha256WithRsa sig(signature);
140 
141  std::string failInfo;
142  if (m_keyLocatorChecker->check(packet, sig.getKeyLocator(), failInfo))
143  return 0;
144  else
145  {
146  onValidationFailed(packet.shared_from_this(), failInfo);
147  return -1;
148  }
149  }
150  catch (SignatureSha256WithRsa::Error& e)
151  {
152  onValidationFailed(packet.shared_from_this(),
153  "Cannot decode Sha256WithRsa signature!");
154  return -1;
155  }
156  }
157  case Signature::Sha256:
158  return 0;
159  default:
160  {
161  onValidationFailed(packet.shared_from_this(),
162  "Unsupported signature type: " +
163  boost::lexical_cast<std::string>(signature.getType()));
164  return -1;
165  }
166  }
167  }
168 
169 private:
170  uint32_t m_sigType;
171  shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
172 };
173 
175 {
176 public:
177  HierarchicalChecker(uint32_t sigType)
178  : CustomizedChecker(sigType,
179  make_shared<HyperKeyLocatorNameChecker>("^(<>*)$", "\\1",
180  "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
181  "\\1\\2",
182  KeyLocatorChecker::RELATION_IS_PREFIX_OF))
183  {
184  }
185 };
186 
188 {
189  enum
190  {
191  INTEREST_SIG_VALUE = -1,
192  INTEREST_SIG_INFO = -2
193  };
194 public:
195  FixedSignerChecker(uint32_t sigType,
196  const std::vector<shared_ptr<IdentityCertificate> >& signers)
197  : m_sigType(sigType)
198  {
199  for (std::vector<shared_ptr<IdentityCertificate> >::const_iterator it = signers.begin();
200  it != signers.end(); it++)
201  m_signers[(*it)->getName().getPrefix(-1)] = (*it);
202  }
203 
204  virtual int8_t
205  check(const Data& data,
206  const OnDataChecked& onValidated,
207  const OnDataCheckFailed& onValidationFailed)
208  {
209  return check(data, data.getSignature(), onValidated, onValidationFailed);
210  }
211 
212  virtual int8_t
213  check(const Interest& interest,
214  const OnInterestChecked& onValidated,
215  const OnInterestCheckFailed& onValidationFailed)
216  {
217  try
218  {
219  const Name& interestName = interest.getName();
220  Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
221  interestName[INTEREST_SIG_VALUE].blockFromValue());
222  return check(interest, signature, onValidated, onValidationFailed);
223  }
224  catch (Signature::Error& e)
225  {
226  onValidationFailed(interest.shared_from_this(), "Invalid signature");
227  return -1;
228  }
229  catch (Tlv::Error& e)
230  {
231  onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
232  return -1;
233  }
234  }
235 
236 private:
237  template<class Packet, class OnValidated, class OnFailed>
238  int8_t
239  check(const Packet& packet, const Signature& signature,
240  const OnValidated& onValidated,
241  const OnFailed& onValidationFailed)
242  {
243  if (m_sigType != signature.getType())
244  {
245  onValidationFailed(packet.shared_from_this(),
246  "Signature type does not match: "
247  + boost::lexical_cast<std::string>(m_sigType)
248  + "!="
249  + boost::lexical_cast<std::string>(signature.getType()));
250  return -1;
251  }
252 
253  switch (signature.getType())
254  {
256  {
257  try
258  {
259  SignatureSha256WithRsa sig(signature);
260 
261  const Name& keyLocatorName = sig.getKeyLocator().getName();
262  if (m_signers.find(keyLocatorName) == m_signers.end())
263  {
264  onValidationFailed(packet.shared_from_this(),
265  "Signer is not in the fixed signer list: "
266  + keyLocatorName.toUri());
267  return -1;
268  }
269 
270  if (Validator::verifySignature(packet, sig,
271  m_signers[keyLocatorName]->getPublicKeyInfo()))
272  {
273  onValidated(packet.shared_from_this());
274  return 1;
275  }
276  else
277  {
278  onValidationFailed(packet.shared_from_this(),
279  "Signature cannot be validated!");
280  return -1;
281  }
282  }
283  catch (KeyLocator::Error& e)
284  {
285  onValidationFailed(packet.shared_from_this(),
286  "KeyLocator does not have name!");
287  return -1;
288  }
289  catch (SignatureSha256WithRsa::Error& e)
290  {
291  onValidationFailed(packet.shared_from_this(),
292  "Cannot decode signature!");
293  return -1;
294  }
295  }
296  case Signature::Sha256:
297  {
298  onValidationFailed(packet.shared_from_this(),
299  "FixedSigner does not allow Sha256 signature type!");
300  return -1;
301  }
302  default:
303  {
304  onValidationFailed(packet.shared_from_this(),
305  "Unsupported signature type: "
306  + boost::lexical_cast<std::string>(signature.getType()));
307  return -1;
308  }
309  }
310  }
311 
312 private:
313  typedef std::map<Name, shared_ptr<IdentityCertificate> > SignerList;
314 
315  uint32_t m_sigType;
316  SignerList m_signers;
317 };
318 
320 {
321 public:
329  static shared_ptr<Checker>
330  create(const ConfigSection& configSection, const std::string& configFilename)
331  {
332  ConfigSection::const_iterator propertyIt = configSection.begin();
333 
334  // Get checker.type
335  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
336  throw Error("Expect <checker.type>!");
337 
338  std::string type = propertyIt->second.data();
339 
340  if (boost::iequals(type, "customized"))
341  return createCustomizedChecker(configSection, configFilename);
342  else if (boost::iequals(type, "hierarchical"))
343  return createHierarchicalChecker(configSection, configFilename);
344  else if (boost::iequals(type, "fixed-signer"))
345  return createFixedSignerChecker(configSection, configFilename);
346  else
347  throw Error("Unsupported checker type: " + type);
348  }
349 
350 private:
351  static shared_ptr<Checker>
352  createCustomizedChecker(const ConfigSection& configSection,
353  const std::string& configFilename)
354  {
355  ConfigSection::const_iterator propertyIt = configSection.begin();
356  propertyIt++;
357 
358  // Get checker.sig-type
359  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
360  throw Error("Expect <checker.sig-type>!");
361 
362  std::string sigType = propertyIt->second.data();
363  propertyIt++;
364 
365  // Get checker.key-locator
366  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator"))
367  throw Error("Expect <checker.key-locator>!");
368 
369  shared_ptr<KeyLocatorChecker> keyLocatorChecker =
370  KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
371  propertyIt++;
372 
373  if (propertyIt != configSection.end())
374  throw Error("Expect the end of checker!");
375 
376  return make_shared<CustomizedChecker>(boost::cref(getSigType(sigType)),
377  boost::cref(keyLocatorChecker));
378  }
379 
380  static shared_ptr<Checker>
381  createHierarchicalChecker(const ConfigSection& configSection,
382  const std::string& configFilename)
383  {
384  ConfigSection::const_iterator propertyIt = configSection.begin();
385  propertyIt++;
386 
387  // Get checker.sig-type
388  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
389  throw Error("Expect <checker.sig-type>!");
390 
391  std::string sigType = propertyIt->second.data();
392  propertyIt++;
393 
394  if (propertyIt != configSection.end())
395  throw Error("Expect the end of checker!");
396 
397  return make_shared<HierarchicalChecker>(boost::cref(getSigType(sigType)));
398  }
399 
400  static shared_ptr<Checker>
401  createFixedSignerChecker(const ConfigSection& configSection,
402  const std::string& configFilename)
403  {
404  ConfigSection::const_iterator propertyIt = configSection.begin();
405  propertyIt++;
406 
407  // Get checker.sig-type
408  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
409  throw Error("Expect <checker.sig-type>!");
410 
411  std::string sigType = propertyIt->second.data();
412  propertyIt++;
413 
414  std::vector<shared_ptr<IdentityCertificate> > signers;
415  for (; propertyIt != configSection.end(); propertyIt++)
416  {
417  if (!boost::iequals(propertyIt->first, "signer"))
418  throw Error("Expect <checker.signer> but get <checker."
419  + propertyIt->first + ">");
420 
421  signers.push_back(getSigner(propertyIt->second, configFilename));
422  }
423 
424  if (propertyIt != configSection.end())
425  throw Error("Expect the end of checker!");
426 
427  return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
428  signers));
429  }
430 
431  static shared_ptr<IdentityCertificate>
432  getSigner(const ConfigSection& configSection, const std::string& configFilename)
433  {
434  using namespace boost::filesystem;
435 
436  ConfigSection::const_iterator propertyIt = configSection.begin();
437 
438  // Get checker.signer.type
439  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
440  throw Error("Expect <checker.signer.type>!");
441 
442  std::string type = propertyIt->second.data();
443  propertyIt++;
444 
445  if (boost::iequals(type, "file"))
446  {
447  // Get checker.signer.file-name
448  if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
449  throw Error("Expect <checker.signer.file-name>!");
450 
451  path certfilePath = absolute(propertyIt->second.data(),
452  path(configFilename).parent_path());
453  propertyIt++;
454 
455  if (propertyIt != configSection.end())
456  throw Error("Expect the end of checker.signer");
457 
458  shared_ptr<IdentityCertificate> idCert
459  = io::load<IdentityCertificate>(certfilePath.c_str());
460 
461  if (static_cast<bool>(idCert))
462  return idCert;
463  else
464  throw Error("Cannot read certificate from file: "
465  + certfilePath.native());
466  }
467  else if (boost::iequals(type, "base64"))
468  {
469  // Get checker.signer.base64-string
470  if (propertyIt == configSection.end() ||
471  !boost::iequals(propertyIt->first, "base64-string"))
472  throw Error("Expect <checker.signer.base64-string>!");
473 
474  std::stringstream ss(propertyIt->second.data());
475  propertyIt++;
476 
477  if (propertyIt != configSection.end())
478  throw Error("Expect the end of checker.signer");
479 
480  shared_ptr<IdentityCertificate> idCert = io::load<IdentityCertificate>(ss);
481 
482  if (static_cast<bool>(idCert))
483  return idCert;
484  else
485  throw Error("Cannot decode certificate from string");
486  }
487  else
488  throw Error("Unsupported checker.signer type: " + type);
489  }
490 
491  static int32_t
492  getSigType(const std::string& sigType)
493  {
494  if (boost::iequals(sigType, "rsa-sha256"))
496  else if (boost::iequals(sigType, "sha256"))
497  return Signature::Sha256;
498  else
499  return -1;
500  }
501 };
502 
503 } // namespace conf
504 } // namespace security
505 } // namespace ndn
506 
507 #endif // NDN_SECURITY_SEC_CONF_RULE_SIGNER_HPP
Representing of SHA256-with-RSA signature in a data packet.
const Name & getName() const
Definition: interest.hpp:182
function< void(const shared_ptr< const Interest > &, const std::string &)> OnInterestCheckFailed
Definition: checker.hpp:25
FixedSignerChecker(uint32_t sigType, const std::vector< shared_ptr< IdentityCertificate > > &signers)
Definition: checker.hpp:195
virtual int8_t check(const Data &data, const OnDataChecked &onValidated, const OnDataCheckFailed &onValidationFailed)
check if data satisfies condition defined in the specific checker implementation
Definition: checker.hpp:205
An Interest holds a Name and other fields for an interest.
Definition: interest.hpp:24
virtual int8_t check(const Data &data, const OnDataChecked &onValidated, const OnDataCheckFailed &onValidationFailed)=0
check if data satisfies condition defined in the specific checker implementation
virtual int8_t check(const Interest &interest, const OnInterestChecked &onValidated, const OnInterestCheckFailed &onValidationFailed)
check if interest satisfies condition defined in the specific checker implementation ...
Definition: checker.hpp:213
function< void(const shared_ptr< const Interest > &)> OnInterestChecked
Definition: checker.hpp:24
virtual int8_t check(const Interest &interest, const OnInterestChecked &onValidated, const OnInterestCheckFailed &onValidationFailed)
check if interest satisfies condition defined in the specific checker implementation ...
Definition: checker.hpp:93
static shared_ptr< KeyLocatorChecker > create(const ConfigSection &configSection, const std::string &filename)
uint32_t getType() const
Definition: signature.hpp:50
std::string toUri() const
Encode this name as a URI.
Definition: name.hpp:536
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
CustomizedChecker(uint32_t sigType, shared_ptr< KeyLocatorChecker > keyLocatorChecker)
Definition: checker.hpp:75
const Signature & getSignature() const
Definition: data.hpp:450
virtual int8_t check(const Data &data, const OnDataChecked &onValidated, const OnDataCheckFailed &onValidationFailed)
check if data satisfies condition defined in the specific checker implementation
Definition: checker.hpp:85
boost::property_tree::ptree ConfigSection
static bool verifySignature(const Data &data, const PublicKey &publicKey)
Verify the data using the publicKey.
Definition: validator.cpp:128
function< void(const shared_ptr< const Data > &)> OnDataChecked
Definition: checker.hpp:26
static shared_ptr< Checker > create(const ConfigSection &configSection, const std::string &configFilename)
create a checker from configuration file.
Definition: checker.hpp:330
function< void(const shared_ptr< const Data > &, const std::string &)> OnDataCheckFailed
Definition: checker.hpp:27
A Signature is storage for the signature-related information (info and value) in a Data packet...
Definition: signature.hpp:15