blob: 3c4ceb29410df2cde68dc965eb156eaa175f4180 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022 */
23
24#ifndef NDN_SECURITY_CONF_CHECKER_HPP
25#define NDN_SECURITY_CONF_CHECKER_HPP
26
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070027#include "common.hpp"
28
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070029#include "key-locator-checker.hpp"
30#include "../../util/io.hpp"
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070031#include "../validator.hpp"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070032
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070033#include <boost/algorithm/string.hpp>
34#include <boost/filesystem.hpp>
35#include <boost/lexical_cast.hpp>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070036
37namespace ndn {
38namespace security {
39namespace conf {
40
41class Checker
42{
43public:
44 typedef function<void(const shared_ptr<const Interest>&)> OnInterestChecked;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070045 typedef function<void(const shared_ptr<const Interest>&,
46 const std::string&)> OnInterestCheckFailed;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070047 typedef function<void(const shared_ptr<const Data>&)> OnDataChecked;
48 typedef function<void(const shared_ptr<const Data>&, const std::string&)> OnDataCheckFailed;
49
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070050 enum {
51 INTEREST_SIG_VALUE = -1,
52 INTEREST_SIG_INFO = -2
53 };
54
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070055
56 virtual
57 ~Checker()
58 {
59 }
60
61 /**
62 * @brief check if data satisfies condition defined in the specific checker implementation
63 *
64 * @param data Data packet
65 * @param onValidated Callback function which is called when data is immediately valid
66 * @param onValidationFailed Call function which is called when data is immediately invalid
67 * @return -1 if data is immediately invalid (onValidationFailed has been called)
68 * 1 if data is immediately valid (onValidated has been called)
69 * 0 if further signature verification is needed.
70 */
71 virtual int8_t
72 check(const Data& data,
73 const OnDataChecked& onValidated,
74 const OnDataCheckFailed& onValidationFailed) = 0;
75
76 /**
77 * @brief check if interest satisfies condition defined in the specific checker implementation
78 *
79 * @param interest Interest packet
80 * @param onValidated Callback function which is called when interest is immediately valid
81 * @param onValidationFailed Call function which is called when interest is immediately invalid
82 * @return -1 if interest is immediately invalid (onValidationFailed has been called)
83 * 1 if interest is immediately valid (onValidated has been called)
84 * 0 if further signature verification is needed.
85 */
86 virtual int8_t
87 check(const Interest& interest,
88 const OnInterestChecked& onValidated,
89 const OnInterestCheckFailed& onValidationFailed) = 0;
90};
91
92class CustomizedChecker : public Checker
93{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070094public:
95 CustomizedChecker(uint32_t sigType,
96 shared_ptr<KeyLocatorChecker> keyLocatorChecker)
97 : m_sigType(sigType)
98 , m_keyLocatorChecker(keyLocatorChecker)
99 {
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700100 switch (sigType)
101 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600102 case tlv::SignatureSha256WithRsa:
103 case tlv::SignatureSha256WithEcdsa:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700104 {
105 if (!static_cast<bool>(m_keyLocatorChecker))
106 throw Error("Strong signature requires KeyLocatorChecker");
107
108 return;
109 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600110 case tlv::DigestSha256:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700111 return;
112 default:
113 throw Error("Unsupported signature type");
114 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700115 }
116
117 virtual int8_t
118 check(const Data& data,
119 const OnDataChecked& onValidated,
120 const OnDataCheckFailed& onValidationFailed)
121 {
122 return check(data, data.getSignature(), onValidated, onValidationFailed);
123 }
124
125 virtual int8_t
126 check(const Interest& interest,
127 const OnInterestChecked& onValidated,
128 const OnInterestCheckFailed& onValidationFailed)
129 {
Yingdi Yu20a06962014-04-17 12:56:04 -0700130 try
131 {
132 const Name& interestName = interest.getName();
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700133 Signature signature(interestName[Checker::INTEREST_SIG_INFO].blockFromValue(),
134 interestName[Checker::INTEREST_SIG_VALUE].blockFromValue());
Yingdi Yu20a06962014-04-17 12:56:04 -0700135 return check(interest, signature, onValidated, onValidationFailed);
136 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700137 catch (Signature::Error& e)
Yingdi Yu20a06962014-04-17 12:56:04 -0700138 {
Yingdi Yu96e64062014-04-15 19:57:33 -0700139 onValidationFailed(interest.shared_from_this(), "Invalid signature");
Yingdi Yu20a06962014-04-17 12:56:04 -0700140 return -1;
141 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600142 catch (tlv::Error& e)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700143 {
144 onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
145 return -1;
146 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700147 }
148
149private:
150 template<class Packet, class OnValidated, class OnFailed>
151 int8_t
152 check(const Packet& packet, const Signature& signature,
153 const OnValidated& onValidated,
154 const OnFailed& onValidationFailed)
155 {
156 if (m_sigType != signature.getType())
157 {
158 onValidationFailed(packet.shared_from_this(),
159 "Signature type does not match: " +
160 boost::lexical_cast<std::string>(m_sigType) +
161 "!=" +
162 boost::lexical_cast<std::string>(signature.getType()));
163 return -1;
164 }
165
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600166 if (signature.getType() == tlv::DigestSha256)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700167 return 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700168
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700169 try
170 {
171 switch (signature.getType())
172 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600173 case tlv::SignatureSha256WithRsa:
174 case tlv::SignatureSha256WithEcdsa:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700175 {
Yingdi Yu4a557052014-07-09 16:40:37 -0700176 if (!signature.hasKeyLocator()) {
177 onValidationFailed(packet.shared_from_this(),
178 "Missing KeyLocator in SignatureInfo");
179 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700180 break;
181 }
182 default:
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700183 {
184 onValidationFailed(packet.shared_from_this(),
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700185 "Unsupported signature type: " +
186 boost::lexical_cast<std::string>(signature.getType()));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700187 return -1;
188 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700189 }
190 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700191 catch (KeyLocator::Error& e)
192 {
193 onValidationFailed(packet.shared_from_this(),
194 "Cannot decode KeyLocator");
195 return -1;
196 }
Junxiao Shic2b8d242014-11-04 08:35:29 -0700197 catch (tlv::Error& e)
198 {
199 onValidationFailed(packet.shared_from_this(),
200 "Cannot decode signature");
201 return -1;
202 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700203
204 std::string failInfo;
Yingdi Yu4a557052014-07-09 16:40:37 -0700205 if (m_keyLocatorChecker->check(packet, signature.getKeyLocator(), failInfo))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700206 return 0;
207 else
208 {
209 onValidationFailed(packet.shared_from_this(), failInfo);
210 return -1;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700211 }
212 }
213
214private:
215 uint32_t m_sigType;
216 shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
217};
218
219class HierarchicalChecker : public CustomizedChecker
220{
221public:
Alexander Afanasyeva4297a62014-06-19 13:29:34 -0700222 explicit
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700223 HierarchicalChecker(uint32_t sigType)
224 : CustomizedChecker(sigType,
225 make_shared<HyperKeyLocatorNameChecker>("^(<>*)$", "\\1",
226 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
227 "\\1\\2",
228 KeyLocatorChecker::RELATION_IS_PREFIX_OF))
229 {
230 }
231};
232
233class FixedSignerChecker : public Checker
234{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700235public:
236 FixedSignerChecker(uint32_t sigType,
237 const std::vector<shared_ptr<IdentityCertificate> >& signers)
238 : m_sigType(sigType)
239 {
240 for (std::vector<shared_ptr<IdentityCertificate> >::const_iterator it = signers.begin();
241 it != signers.end(); it++)
242 m_signers[(*it)->getName().getPrefix(-1)] = (*it);
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700243
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600244 if (sigType != tlv::SignatureSha256WithRsa &&
245 sigType != tlv::SignatureSha256WithEcdsa)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700246 {
247 throw Error("FixedSigner is only meaningful for strong signature type");
248 }
249
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700250 }
251
252 virtual int8_t
253 check(const Data& data,
254 const OnDataChecked& onValidated,
255 const OnDataCheckFailed& onValidationFailed)
256 {
257 return check(data, data.getSignature(), onValidated, onValidationFailed);
258 }
259
260 virtual int8_t
261 check(const Interest& interest,
262 const OnInterestChecked& onValidated,
263 const OnInterestCheckFailed& onValidationFailed)
264 {
Yingdi Yu20a06962014-04-17 12:56:04 -0700265 try
266 {
267 const Name& interestName = interest.getName();
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700268 Signature signature(interestName[Checker::INTEREST_SIG_INFO].blockFromValue(),
269 interestName[Checker::INTEREST_SIG_VALUE].blockFromValue());
Yingdi Yu20a06962014-04-17 12:56:04 -0700270 return check(interest, signature, onValidated, onValidationFailed);
271 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700272 catch (Signature::Error& e)
Yingdi Yu20a06962014-04-17 12:56:04 -0700273 {
Yingdi Yu96e64062014-04-15 19:57:33 -0700274 onValidationFailed(interest.shared_from_this(), "Invalid signature");
Yingdi Yu20a06962014-04-17 12:56:04 -0700275 return -1;
276 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600277 catch (tlv::Error& e)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700278 {
279 onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
280 return -1;
281 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700282 }
283
284private:
285 template<class Packet, class OnValidated, class OnFailed>
286 int8_t
287 check(const Packet& packet, const Signature& signature,
288 const OnValidated& onValidated,
289 const OnFailed& onValidationFailed)
290 {
291 if (m_sigType != signature.getType())
292 {
293 onValidationFailed(packet.shared_from_this(),
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700294 "Signature type does not match: " +
295 boost::lexical_cast<std::string>(m_sigType) +
296 "!=" +
297 boost::lexical_cast<std::string>(signature.getType()));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700298 return -1;
299 }
300
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600301 if (signature.getType() == tlv::DigestSha256)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700302 {
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700303 onValidationFailed(packet.shared_from_this(),
304 "FixedSigner does not allow Sha256 signature type");
305 return -1;
306 }
307
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700308 try
309 {
310 switch (signature.getType())
311 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600312 case tlv::SignatureSha256WithRsa:
313 case tlv::SignatureSha256WithEcdsa:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700314 {
Yingdi Yu4a557052014-07-09 16:40:37 -0700315 if (!signature.hasKeyLocator()) {
316 onValidationFailed(packet.shared_from_this(),
317 "Missing KeyLocator in SignatureInfo");
318 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700319 break;
320 }
321 default:
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700322 {
323 onValidationFailed(packet.shared_from_this(),
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700324 "Unsupported signature type: " +
325 boost::lexical_cast<std::string>(signature.getType()));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700326 return -1;
327 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700328 }
329
Yingdi Yu4a557052014-07-09 16:40:37 -0700330 const Name& keyLocatorName = signature.getKeyLocator().getName();
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700331
332 if (m_signers.find(keyLocatorName) == m_signers.end())
333 {
334 onValidationFailed(packet.shared_from_this(),
335 "Signer is not in the fixed signer list: " +
336 keyLocatorName.toUri());
337 return -1;
338 }
339
Yingdi Yu4a557052014-07-09 16:40:37 -0700340 if (Validator::verifySignature(packet, signature,
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700341 m_signers[keyLocatorName]->getPublicKeyInfo()))
342 {
343 onValidated(packet.shared_from_this());
344 return 1;
345 }
346 else
347 {
348 onValidationFailed(packet.shared_from_this(),
349 "Signature cannot be validated");
350 return -1;
351 }
352 }
353 catch (KeyLocator::Error& e)
354 {
355 onValidationFailed(packet.shared_from_this(),
356 "KeyLocator does not have name");
357 return -1;
358 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600359 catch (tlv::Error& e)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700360 {
361 onValidationFailed(packet.shared_from_this(),
362 "Cannot decode signature");
363 return -1;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700364 }
365 }
366
367private:
368 typedef std::map<Name, shared_ptr<IdentityCertificate> > SignerList;
369
370 uint32_t m_sigType;
371 SignerList m_signers;
372};
373
374class CheckerFactory
375{
376public:
377 /**
378 * @brief create a checker from configuration file.
379 *
380 * @param configSection The section containing the definition of checker.
381 * @param configFilename The configuration file name.
382 * @return a shared pointer to the created checker.
383 */
384 static shared_ptr<Checker>
385 create(const ConfigSection& configSection, const std::string& configFilename)
386 {
387 ConfigSection::const_iterator propertyIt = configSection.begin();
388
389 // Get checker.type
390 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700391 throw Error("Expect <checker.type>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700392
393 std::string type = propertyIt->second.data();
394
395 if (boost::iequals(type, "customized"))
396 return createCustomizedChecker(configSection, configFilename);
397 else if (boost::iequals(type, "hierarchical"))
398 return createHierarchicalChecker(configSection, configFilename);
399 else if (boost::iequals(type, "fixed-signer"))
400 return createFixedSignerChecker(configSection, configFilename);
401 else
402 throw Error("Unsupported checker type: " + type);
403 }
404
405private:
406 static shared_ptr<Checker>
407 createCustomizedChecker(const ConfigSection& configSection,
408 const std::string& configFilename)
409 {
410 ConfigSection::const_iterator propertyIt = configSection.begin();
411 propertyIt++;
412
413 // Get checker.sig-type
414 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700415 throw Error("Expect <checker.sig-type>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700416
417 std::string sigType = propertyIt->second.data();
418 propertyIt++;
419
420 // Get checker.key-locator
421 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700422 throw Error("Expect <checker.key-locator>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700423
424 shared_ptr<KeyLocatorChecker> keyLocatorChecker =
425 KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
426 propertyIt++;
427
428 if (propertyIt != configSection.end())
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700429 throw Error("Expect the end of checker");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700430
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700431 return make_shared<CustomizedChecker>(getSigType(sigType), keyLocatorChecker);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700432 }
433
434 static shared_ptr<Checker>
435 createHierarchicalChecker(const ConfigSection& configSection,
436 const std::string& configFilename)
437 {
438 ConfigSection::const_iterator propertyIt = configSection.begin();
439 propertyIt++;
440
441 // Get checker.sig-type
442 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700443 throw Error("Expect <checker.sig-type>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700444
445 std::string sigType = propertyIt->second.data();
446 propertyIt++;
447
448 if (propertyIt != configSection.end())
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700449 throw Error("Expect the end of checker");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700450
Alexander Afanasyevb67090a2014-04-29 22:31:01 -0700451 return make_shared<HierarchicalChecker>(getSigType(sigType));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700452 }
453
454 static shared_ptr<Checker>
455 createFixedSignerChecker(const ConfigSection& configSection,
456 const std::string& configFilename)
457 {
458 ConfigSection::const_iterator propertyIt = configSection.begin();
459 propertyIt++;
460
461 // Get checker.sig-type
462 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700463 throw Error("Expect <checker.sig-type>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700464
465 std::string sigType = propertyIt->second.data();
466 propertyIt++;
467
468 std::vector<shared_ptr<IdentityCertificate> > signers;
469 for (; propertyIt != configSection.end(); propertyIt++)
470 {
471 if (!boost::iequals(propertyIt->first, "signer"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700472 throw Error("Expect <checker.signer> but get <checker." +
473 propertyIt->first + ">");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700474
475 signers.push_back(getSigner(propertyIt->second, configFilename));
476 }
477
478 if (propertyIt != configSection.end())
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700479 throw Error("Expect the end of checker");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700480
481 return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
482 signers));
483 }
484
485 static shared_ptr<IdentityCertificate>
486 getSigner(const ConfigSection& configSection, const std::string& configFilename)
487 {
488 using namespace boost::filesystem;
489
490 ConfigSection::const_iterator propertyIt = configSection.begin();
491
492 // Get checker.signer.type
493 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700494 throw Error("Expect <checker.signer.type>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700495
496 std::string type = propertyIt->second.data();
497 propertyIt++;
498
499 if (boost::iequals(type, "file"))
500 {
501 // Get checker.signer.file-name
502 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700503 throw Error("Expect <checker.signer.file-name>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700504
505 path certfilePath = absolute(propertyIt->second.data(),
506 path(configFilename).parent_path());
507 propertyIt++;
508
509 if (propertyIt != configSection.end())
510 throw Error("Expect the end of checker.signer");
511
512 shared_ptr<IdentityCertificate> idCert
513 = io::load<IdentityCertificate>(certfilePath.c_str());
514
515 if (static_cast<bool>(idCert))
516 return idCert;
517 else
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700518 throw Error("Cannot read certificate from file: " +
519 certfilePath.native());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700520 }
521 else if (boost::iequals(type, "base64"))
522 {
523 // Get checker.signer.base64-string
524 if (propertyIt == configSection.end() ||
525 !boost::iequals(propertyIt->first, "base64-string"))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700526 throw Error("Expect <checker.signer.base64-string>");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700527
528 std::stringstream ss(propertyIt->second.data());
529 propertyIt++;
530
531 if (propertyIt != configSection.end())
532 throw Error("Expect the end of checker.signer");
533
534 shared_ptr<IdentityCertificate> idCert = io::load<IdentityCertificate>(ss);
535
536 if (static_cast<bool>(idCert))
537 return idCert;
538 else
539 throw Error("Cannot decode certificate from string");
540 }
541 else
542 throw Error("Unsupported checker.signer type: " + type);
543 }
544
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700545 static uint32_t
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700546 getSigType(const std::string& sigType)
547 {
548 if (boost::iequals(sigType, "rsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600549 return tlv::SignatureSha256WithRsa;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700550 else if (boost::iequals(sigType, "ecdsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600551 return tlv::SignatureSha256WithEcdsa;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700552 else if (boost::iequals(sigType, "sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600553 return tlv::DigestSha256;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700554 else
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700555 throw Error("Unsupported signature type");
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700556 }
557};
558
559} // namespace conf
560} // namespace security
561} // namespace ndn
562
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700563#endif // NDN_SECURITY_CONF_CHECKER_HPP