blob: c4ec3cafb209085041bd2199763d95b5d906efac [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/**
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -07003 * Copyright (c) 2013-2016 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"
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070032#include "../v1/identity-certificate.hpp"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070033
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070034#include <boost/algorithm/string.hpp>
35#include <boost/filesystem.hpp>
36#include <boost/lexical_cast.hpp>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070037
38namespace ndn {
39namespace security {
40namespace conf {
41
42class Checker
43{
44public:
45 typedef function<void(const shared_ptr<const Interest>&)> OnInterestChecked;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070046 typedef function<void(const shared_ptr<const Interest>&,
47 const std::string&)> OnInterestCheckFailed;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070048 typedef function<void(const shared_ptr<const Data>&)> OnDataChecked;
49 typedef function<void(const shared_ptr<const Data>&, const std::string&)> OnDataCheckFailed;
50
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070051 enum {
52 INTEREST_SIG_VALUE = -1,
53 INTEREST_SIG_INFO = -2
54 };
55
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070056
57 virtual
58 ~Checker()
59 {
60 }
61
62 /**
63 * @brief check if data satisfies condition defined in the specific checker implementation
64 *
65 * @param data Data packet
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070066 * @retval -1 if data is immediately invalid
67 * @retval 1 if data is immediately valid
68 * @retval 0 if further signature verification is needed.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070069 */
70 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070071 check(const Data& data) = 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070072
73 /**
74 * @brief check if interest satisfies condition defined in the specific checker implementation
75 *
76 * @param interest Interest packet
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070077 * @retval -1 if interest is immediately invalid
78 * @retval 1 if interest is immediately valid
79 * @retval 0 if further signature verification is needed.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070080 */
81 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070082 check(const Interest& interest) = 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070083};
84
85class CustomizedChecker : public Checker
86{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070087public:
88 CustomizedChecker(uint32_t sigType,
89 shared_ptr<KeyLocatorChecker> keyLocatorChecker)
90 : m_sigType(sigType)
91 , m_keyLocatorChecker(keyLocatorChecker)
92 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070093 switch (sigType) {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060094 case tlv::SignatureSha256WithRsa:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070095 case tlv::SignatureSha256WithEcdsa: {
96 if (!static_cast<bool>(m_keyLocatorChecker))
97 BOOST_THROW_EXCEPTION(Error("Strong signature requires KeyLocatorChecker"));
98 return;
99 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600100 case tlv::DigestSha256:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700101 return;
102 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700103 BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700104 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 }
106
107 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700108 check(const Data& data) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700110 return check(data, data.getSignature());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700111 }
112
113 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700114 check(const Interest& interest) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700115 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700116 try {
117 const Name& interestName = interest.getName();
118 Signature signature(interestName[Checker::INTEREST_SIG_INFO].blockFromValue(),
119 interestName[Checker::INTEREST_SIG_VALUE].blockFromValue());
120 return check(interest, signature);
121 }
122 catch (const Signature::Error& e) {
123 // Invalid signature
124 return -1;
125 }
126 catch (const tlv::Error& e) {
127 // Cannot decode signature related TLVs
128 return -1;
129 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700130 }
131
132private:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700133 template<class Packet>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700134 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700135 check(const Packet& packet, const Signature& signature)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700136 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700137 if (m_sigType != signature.getType()) {
138 // Signature type does not match
139 return -1;
140 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700141
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600142 if (signature.getType() == tlv::DigestSha256)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700143 return 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700144
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700145 try {
146 switch (signature.getType()) {
147 case tlv::SignatureSha256WithRsa:
148 case tlv::SignatureSha256WithEcdsa: {
149 if (!signature.hasKeyLocator()) {
150 // Missing KeyLocator in SignatureInfo
151 return -1;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700152 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700153 break;
154 }
155 default: {
156 // Unsupported signature type
157 return -1;
158 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700159 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700160 }
161 catch (const KeyLocator::Error& e) {
162 // Cannot decode KeyLocator
163 return -1;
164 }
165 catch (const tlv::Error& e) {
166 // Cannot decode signature
167 return -1;
168 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700169
170 std::string failInfo;
Yingdi Yu4a557052014-07-09 16:40:37 -0700171 if (m_keyLocatorChecker->check(packet, signature.getKeyLocator(), failInfo))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700172 return 0;
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700173 else {
174 return -1;
175 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700176 }
177
178private:
179 uint32_t m_sigType;
180 shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
181};
182
183class HierarchicalChecker : public CustomizedChecker
184{
185public:
Alexander Afanasyeva4297a62014-06-19 13:29:34 -0700186 explicit
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700187 HierarchicalChecker(uint32_t sigType)
188 : CustomizedChecker(sigType,
189 make_shared<HyperKeyLocatorNameChecker>("^(<>*)$", "\\1",
190 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
191 "\\1\\2",
192 KeyLocatorChecker::RELATION_IS_PREFIX_OF))
193 {
194 }
195};
196
197class FixedSignerChecker : public Checker
198{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700199public:
200 FixedSignerChecker(uint32_t sigType,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700201 const std::vector<shared_ptr<v1::IdentityCertificate>>& signers)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700202 : m_sigType(sigType)
203 {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700204 for (std::vector<shared_ptr<v1::IdentityCertificate>>::const_iterator it = signers.begin();
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700205 it != signers.end(); it++)
206 m_signers[(*it)->getName().getPrefix(-1)] = (*it);
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700207
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600208 if (sigType != tlv::SignatureSha256WithRsa &&
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700209 sigType != tlv::SignatureSha256WithEcdsa) {
210 BOOST_THROW_EXCEPTION(Error("FixedSigner is only meaningful for strong signature type"));
211 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700212 }
213
214 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700215 check(const Data& data) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700216 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700217 return check(data, data.getSignature());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700218 }
219
220 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700221 check(const Interest& interest) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700222 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700223 try {
224 const Name& interestName = interest.getName();
225 Signature signature(interestName[Checker::INTEREST_SIG_INFO].blockFromValue(),
226 interestName[Checker::INTEREST_SIG_VALUE].blockFromValue());
227 return check(interest, signature);
228 }
229 catch (const Signature::Error& e) {
230 // Invalid signature
231 return -1;
232 }
233 catch (const tlv::Error& e) {
234 // Cannot decode signature related TLVs
235 return -1;
236 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700237 }
238
239private:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700240 template<class Packet>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700241 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700242 check(const Packet& packet, const Signature& signature)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700243 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700244 if (m_sigType != signature.getType()) {
245 // Signature type does not match
246 return -1;
247 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700248
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700249 if (signature.getType() == tlv::DigestSha256) {
250 // FixedSigner does not allow Sha256 signature type
251 return -1;
252 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700253
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700254 try {
255 switch (signature.getType()) {
256 case tlv::SignatureSha256WithRsa:
257 case tlv::SignatureSha256WithEcdsa: {
258 if (!signature.hasKeyLocator()) {
259 // Missing KeyLocator in SignatureInfo
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700260 return -1;
261 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700262 break;
263 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700264
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700265 default: {
266 // Unsupported signature type
267 return -1;
268 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700269 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700270
271 const Name& keyLocatorName = signature.getKeyLocator().getName();
272
273 if (m_signers.find(keyLocatorName) == m_signers.end()) {
274 // Signer is not in the fixed signer list
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700275 return -1;
276 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700277
278 if (Validator::verifySignature(packet, signature,
279 m_signers[keyLocatorName]->getPublicKeyInfo())) {
280 return 1;
281 }
282 else {
283 // Signature cannot be validated
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700284 return -1;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700285 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700286 }
287 catch (const KeyLocator::Error& e) {
288 // KeyLocator does not have name
289 return -1;
290 }
291 catch (const tlv::Error& e) {
292 // Cannot decode signature
293 return -1;
294 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700295 }
296
297private:
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700298 typedef std::map<Name, shared_ptr<v1::IdentityCertificate>> SignerList;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700299 uint32_t m_sigType;
300 SignerList m_signers;
301};
302
303class CheckerFactory
304{
305public:
306 /**
307 * @brief create a checker from configuration file.
308 *
309 * @param configSection The section containing the definition of checker.
310 * @param configFilename The configuration file name.
311 * @return a shared pointer to the created checker.
312 */
313 static shared_ptr<Checker>
314 create(const ConfigSection& configSection, const std::string& configFilename)
315 {
316 ConfigSection::const_iterator propertyIt = configSection.begin();
317
318 // Get checker.type
319 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700320 BOOST_THROW_EXCEPTION(Error("Expect <checker.type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700321
322 std::string type = propertyIt->second.data();
323
324 if (boost::iequals(type, "customized"))
325 return createCustomizedChecker(configSection, configFilename);
326 else if (boost::iequals(type, "hierarchical"))
327 return createHierarchicalChecker(configSection, configFilename);
328 else if (boost::iequals(type, "fixed-signer"))
329 return createFixedSignerChecker(configSection, configFilename);
330 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700331 BOOST_THROW_EXCEPTION(Error("Unsupported checker type: " + type));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700332 }
333
334private:
335 static shared_ptr<Checker>
336 createCustomizedChecker(const ConfigSection& configSection,
337 const std::string& configFilename)
338 {
339 ConfigSection::const_iterator propertyIt = configSection.begin();
340 propertyIt++;
341
342 // Get checker.sig-type
343 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700344 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700345
346 std::string sigType = propertyIt->second.data();
347 propertyIt++;
348
349 // Get checker.key-locator
350 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700351 BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700352
353 shared_ptr<KeyLocatorChecker> keyLocatorChecker =
354 KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
355 propertyIt++;
356
357 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700358 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700359
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700360 return make_shared<CustomizedChecker>(getSigType(sigType), keyLocatorChecker);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700361 }
362
363 static shared_ptr<Checker>
364 createHierarchicalChecker(const ConfigSection& configSection,
365 const std::string& configFilename)
366 {
367 ConfigSection::const_iterator propertyIt = configSection.begin();
368 propertyIt++;
369
370 // Get checker.sig-type
371 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700372 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700373
374 std::string sigType = propertyIt->second.data();
375 propertyIt++;
376
377 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700378 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700379
Alexander Afanasyevb67090a2014-04-29 22:31:01 -0700380 return make_shared<HierarchicalChecker>(getSigType(sigType));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700381 }
382
383 static shared_ptr<Checker>
384 createFixedSignerChecker(const ConfigSection& configSection,
385 const std::string& configFilename)
386 {
387 ConfigSection::const_iterator propertyIt = configSection.begin();
388 propertyIt++;
389
390 // Get checker.sig-type
391 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700392 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700393
394 std::string sigType = propertyIt->second.data();
395 propertyIt++;
396
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700397 std::vector<shared_ptr<v1::IdentityCertificate>> signers;
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700398 for (; propertyIt != configSection.end(); propertyIt++) {
399 if (!boost::iequals(propertyIt->first, "signer"))
400 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer> but get <checker." +
401 propertyIt->first + ">"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700402
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700403 signers.push_back(getSigner(propertyIt->second, configFilename));
404 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700405
406 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700407 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700408
409 return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
410 signers));
411 }
412
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700413 static shared_ptr<v1::IdentityCertificate>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700414 getSigner(const ConfigSection& configSection, const std::string& configFilename)
415 {
416 using namespace boost::filesystem;
417
418 ConfigSection::const_iterator propertyIt = configSection.begin();
419
420 // Get checker.signer.type
421 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700422 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700423
424 std::string type = propertyIt->second.data();
425 propertyIt++;
426
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700427 if (boost::iequals(type, "file")) {
428 // Get checker.signer.file-name
429 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
430 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.file-name>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700431
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700432 path certfilePath = absolute(propertyIt->second.data(),
433 path(configFilename).parent_path());
434 propertyIt++;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700435
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700436 if (propertyIt != configSection.end())
437 BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700438
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700439 shared_ptr<v1::IdentityCertificate> idCert
440 = io::load<v1::IdentityCertificate>(certfilePath.c_str());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700441
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700442 if (static_cast<bool>(idCert))
443 return idCert;
444 else
445 BOOST_THROW_EXCEPTION(Error("Cannot read certificate from file: " +
446 certfilePath.native()));
447 }
448 else if (boost::iequals(type, "base64")) {
449 // Get checker.signer.base64-string
450 if (propertyIt == configSection.end() ||
451 !boost::iequals(propertyIt->first, "base64-string"))
452 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.base64-string>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700453
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700454 std::stringstream ss(propertyIt->second.data());
455 propertyIt++;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700456
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700457 if (propertyIt != configSection.end())
458 BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700459
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700460 shared_ptr<v1::IdentityCertificate> idCert = io::load<v1::IdentityCertificate>(ss);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700461
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700462 if (static_cast<bool>(idCert))
463 return idCert;
464 else
465 BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from string"));
466 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700467 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700468 BOOST_THROW_EXCEPTION(Error("Unsupported checker.signer type: " + type));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700469 }
470
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700471 static uint32_t
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700472 getSigType(const std::string& sigType)
473 {
474 if (boost::iequals(sigType, "rsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600475 return tlv::SignatureSha256WithRsa;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700476 else if (boost::iequals(sigType, "ecdsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600477 return tlv::SignatureSha256WithEcdsa;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700478 else if (boost::iequals(sigType, "sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600479 return tlv::DigestSha256;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700480 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700481 BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700482 }
483};
484
485} // namespace conf
486} // namespace security
487} // namespace ndn
488
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700489#endif // NDN_SECURITY_CONF_CHECKER_HPP