blob: b928906af6890349066ef2718871ffda44fafd17 [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 Afanasyev70244f42017-01-04 12:47:12 -08003 * Copyright (c) 2013-2017 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 Yu48e8c0c2014-03-19 12:01:55 -070051 virtual
52 ~Checker()
53 {
54 }
55
56 /**
57 * @brief check if data satisfies condition defined in the specific checker implementation
58 *
59 * @param data Data packet
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070060 * @retval -1 if data is immediately invalid
61 * @retval 1 if data is immediately valid
62 * @retval 0 if further signature verification is needed.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070063 */
64 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070065 check(const Data& data) = 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070066
67 /**
68 * @brief check if interest satisfies condition defined in the specific checker implementation
69 *
70 * @param interest Interest packet
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070071 * @retval -1 if interest is immediately invalid
72 * @retval 1 if interest is immediately valid
73 * @retval 0 if further signature verification is needed.
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070074 */
75 virtual int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070076 check(const Interest& interest) = 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070077};
78
79class CustomizedChecker : public Checker
80{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070081public:
82 CustomizedChecker(uint32_t sigType,
83 shared_ptr<KeyLocatorChecker> keyLocatorChecker)
84 : m_sigType(sigType)
85 , m_keyLocatorChecker(keyLocatorChecker)
86 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070087 switch (sigType) {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060088 case tlv::SignatureSha256WithRsa:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070089 case tlv::SignatureSha256WithEcdsa: {
90 if (!static_cast<bool>(m_keyLocatorChecker))
91 BOOST_THROW_EXCEPTION(Error("Strong signature requires KeyLocatorChecker"));
92 return;
93 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060094 case tlv::DigestSha256:
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070095 return;
96 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070097 BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -070098 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070099 }
100
Davide Pesavento57c07df2016-12-11 18:41:45 -0500101 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700102 check(const Data& data) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700103 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700104 return check(data, data.getSignature());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700105 }
106
Davide Pesavento57c07df2016-12-11 18:41:45 -0500107 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700108 check(const Interest& interest) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700109 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700110 try {
111 const Name& interestName = interest.getName();
Alexander Afanasyev70244f42017-01-04 12:47:12 -0800112 Signature signature(interestName[command_interest::POS_SIG_INFO].blockFromValue(),
113 interestName[command_interest::POS_SIG_VALUE].blockFromValue());
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700114 return check(interest, signature);
115 }
116 catch (const Signature::Error& e) {
117 // Invalid signature
118 return -1;
119 }
120 catch (const tlv::Error& e) {
121 // Cannot decode signature related TLVs
122 return -1;
123 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700124 }
125
126private:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700127 template<class Packet>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700128 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700129 check(const Packet& packet, const Signature& signature)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700130 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700131 if (m_sigType != signature.getType()) {
132 // Signature type does not match
133 return -1;
134 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700135
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600136 if (signature.getType() == tlv::DigestSha256)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700137 return 0;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700138
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700139 try {
140 switch (signature.getType()) {
141 case tlv::SignatureSha256WithRsa:
142 case tlv::SignatureSha256WithEcdsa: {
143 if (!signature.hasKeyLocator()) {
144 // Missing KeyLocator in SignatureInfo
145 return -1;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700146 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700147 break;
148 }
149 default: {
150 // Unsupported signature type
151 return -1;
152 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700153 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700154 }
155 catch (const KeyLocator::Error& e) {
156 // Cannot decode KeyLocator
157 return -1;
158 }
159 catch (const tlv::Error& e) {
160 // Cannot decode signature
161 return -1;
162 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700163
164 std::string failInfo;
Yingdi Yu4a557052014-07-09 16:40:37 -0700165 if (m_keyLocatorChecker->check(packet, signature.getKeyLocator(), failInfo))
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700166 return 0;
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700167 else {
168 return -1;
169 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700170 }
171
172private:
173 uint32_t m_sigType;
174 shared_ptr<KeyLocatorChecker> m_keyLocatorChecker;
175};
176
177class HierarchicalChecker : public CustomizedChecker
178{
179public:
Alexander Afanasyeva4297a62014-06-19 13:29:34 -0700180 explicit
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700181 HierarchicalChecker(uint32_t sigType)
182 : CustomizedChecker(sigType,
183 make_shared<HyperKeyLocatorNameChecker>("^(<>*)$", "\\1",
184 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
185 "\\1\\2",
186 KeyLocatorChecker::RELATION_IS_PREFIX_OF))
187 {
188 }
189};
190
191class FixedSignerChecker : public Checker
192{
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700193public:
194 FixedSignerChecker(uint32_t sigType,
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700195 const std::vector<shared_ptr<v1::IdentityCertificate>>& signers)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700196 : m_sigType(sigType)
197 {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700198 for (std::vector<shared_ptr<v1::IdentityCertificate>>::const_iterator it = signers.begin();
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700199 it != signers.end(); it++)
200 m_signers[(*it)->getName().getPrefix(-1)] = (*it);
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700201
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600202 if (sigType != tlv::SignatureSha256WithRsa &&
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700203 sigType != tlv::SignatureSha256WithEcdsa) {
204 BOOST_THROW_EXCEPTION(Error("FixedSigner is only meaningful for strong signature type"));
205 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700206 }
207
Davide Pesavento57c07df2016-12-11 18:41:45 -0500208 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700209 check(const Data& data) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700210 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700211 return check(data, data.getSignature());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700212 }
213
Davide Pesavento57c07df2016-12-11 18:41:45 -0500214 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700215 check(const Interest& interest) override
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700216 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700217 try {
218 const Name& interestName = interest.getName();
Alexander Afanasyev70244f42017-01-04 12:47:12 -0800219 Signature signature(interestName[command_interest::POS_SIG_INFO].blockFromValue(),
220 interestName[command_interest::POS_SIG_VALUE].blockFromValue());
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700221 return check(interest, signature);
222 }
223 catch (const Signature::Error& e) {
224 // Invalid signature
225 return -1;
226 }
227 catch (const tlv::Error& e) {
228 // Cannot decode signature related TLVs
229 return -1;
230 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700231 }
232
233private:
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700234 template<class Packet>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700235 int8_t
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700236 check(const Packet& packet, const Signature& signature)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700237 {
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700238 if (m_sigType != signature.getType()) {
239 // Signature type does not match
240 return -1;
241 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700242
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700243 if (signature.getType() == tlv::DigestSha256) {
244 // FixedSigner does not allow Sha256 signature type
245 return -1;
246 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700247
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700248 try {
249 switch (signature.getType()) {
250 case tlv::SignatureSha256WithRsa:
251 case tlv::SignatureSha256WithEcdsa: {
252 if (!signature.hasKeyLocator()) {
253 // Missing KeyLocator in SignatureInfo
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700254 return -1;
255 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700256 break;
257 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700258
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700259 default: {
260 // Unsupported signature type
261 return -1;
262 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700263 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700264
265 const Name& keyLocatorName = signature.getKeyLocator().getName();
266
267 if (m_signers.find(keyLocatorName) == m_signers.end()) {
268 // Signer is not in the fixed signer list
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700269 return -1;
270 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700271
272 if (Validator::verifySignature(packet, signature,
273 m_signers[keyLocatorName]->getPublicKeyInfo())) {
274 return 1;
275 }
276 else {
277 // Signature cannot be validated
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700278 return -1;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700279 }
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700280 }
281 catch (const KeyLocator::Error& e) {
282 // KeyLocator does not have name
283 return -1;
284 }
285 catch (const tlv::Error& e) {
286 // Cannot decode signature
287 return -1;
288 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700289 }
290
291private:
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700292 typedef std::map<Name, shared_ptr<v1::IdentityCertificate>> SignerList;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700293 uint32_t m_sigType;
294 SignerList m_signers;
295};
296
297class CheckerFactory
298{
299public:
300 /**
301 * @brief create a checker from configuration file.
302 *
303 * @param configSection The section containing the definition of checker.
304 * @param configFilename The configuration file name.
305 * @return a shared pointer to the created checker.
306 */
307 static shared_ptr<Checker>
308 create(const ConfigSection& configSection, const std::string& configFilename)
309 {
310 ConfigSection::const_iterator propertyIt = configSection.begin();
311
312 // Get checker.type
313 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700314 BOOST_THROW_EXCEPTION(Error("Expect <checker.type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700315
316 std::string type = propertyIt->second.data();
317
318 if (boost::iequals(type, "customized"))
319 return createCustomizedChecker(configSection, configFilename);
320 else if (boost::iequals(type, "hierarchical"))
321 return createHierarchicalChecker(configSection, configFilename);
322 else if (boost::iequals(type, "fixed-signer"))
323 return createFixedSignerChecker(configSection, configFilename);
324 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700325 BOOST_THROW_EXCEPTION(Error("Unsupported checker type: " + type));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700326 }
327
328private:
329 static shared_ptr<Checker>
330 createCustomizedChecker(const ConfigSection& configSection,
331 const std::string& configFilename)
332 {
333 ConfigSection::const_iterator propertyIt = configSection.begin();
334 propertyIt++;
335
336 // Get checker.sig-type
337 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700338 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700339
340 std::string sigType = propertyIt->second.data();
341 propertyIt++;
342
343 // Get checker.key-locator
344 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700345 BOOST_THROW_EXCEPTION(Error("Expect <checker.key-locator>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700346
347 shared_ptr<KeyLocatorChecker> keyLocatorChecker =
348 KeyLocatorCheckerFactory::create(propertyIt->second, configFilename);
349 propertyIt++;
350
351 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700352 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700353
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700354 return make_shared<CustomizedChecker>(getSigType(sigType), keyLocatorChecker);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700355 }
356
357 static shared_ptr<Checker>
358 createHierarchicalChecker(const ConfigSection& configSection,
359 const std::string& configFilename)
360 {
361 ConfigSection::const_iterator propertyIt = configSection.begin();
362 propertyIt++;
363
364 // Get checker.sig-type
365 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700366 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700367
368 std::string sigType = propertyIt->second.data();
369 propertyIt++;
370
371 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700372 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700373
Alexander Afanasyevb67090a2014-04-29 22:31:01 -0700374 return make_shared<HierarchicalChecker>(getSigType(sigType));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700375 }
376
377 static shared_ptr<Checker>
378 createFixedSignerChecker(const ConfigSection& configSection,
379 const std::string& configFilename)
380 {
381 ConfigSection::const_iterator propertyIt = configSection.begin();
382 propertyIt++;
383
384 // Get checker.sig-type
385 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "sig-type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700386 BOOST_THROW_EXCEPTION(Error("Expect <checker.sig-type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700387
388 std::string sigType = propertyIt->second.data();
389 propertyIt++;
390
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700391 std::vector<shared_ptr<v1::IdentityCertificate>> signers;
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700392 for (; propertyIt != configSection.end(); propertyIt++) {
393 if (!boost::iequals(propertyIt->first, "signer"))
394 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer> but get <checker." +
395 propertyIt->first + ">"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700396
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700397 signers.push_back(getSigner(propertyIt->second, configFilename));
398 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700399
400 if (propertyIt != configSection.end())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700401 BOOST_THROW_EXCEPTION(Error("Expect the end of checker"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700402
403 return shared_ptr<FixedSignerChecker>(new FixedSignerChecker(getSigType(sigType),
404 signers));
405 }
406
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700407 static shared_ptr<v1::IdentityCertificate>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700408 getSigner(const ConfigSection& configSection, const std::string& configFilename)
409 {
410 using namespace boost::filesystem;
411
412 ConfigSection::const_iterator propertyIt = configSection.begin();
413
414 // Get checker.signer.type
415 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700416 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.type>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700417
418 std::string type = propertyIt->second.data();
419 propertyIt++;
420
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700421 if (boost::iequals(type, "file")) {
422 // Get checker.signer.file-name
423 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "file-name"))
424 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.file-name>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700425
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700426 path certfilePath = absolute(propertyIt->second.data(),
427 path(configFilename).parent_path());
428 propertyIt++;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700429
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700430 if (propertyIt != configSection.end())
431 BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700432
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700433 shared_ptr<v1::IdentityCertificate> idCert
434 = io::load<v1::IdentityCertificate>(certfilePath.c_str());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700435
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700436 if (static_cast<bool>(idCert))
437 return idCert;
438 else
439 BOOST_THROW_EXCEPTION(Error("Cannot read certificate from file: " +
440 certfilePath.native()));
441 }
442 else if (boost::iequals(type, "base64")) {
443 // Get checker.signer.base64-string
444 if (propertyIt == configSection.end() ||
445 !boost::iequals(propertyIt->first, "base64-string"))
446 BOOST_THROW_EXCEPTION(Error("Expect <checker.signer.base64-string>"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700447
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700448 std::stringstream ss(propertyIt->second.data());
449 propertyIt++;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700450
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700451 if (propertyIt != configSection.end())
452 BOOST_THROW_EXCEPTION(Error("Expect the end of checker.signer"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700453
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700454 shared_ptr<v1::IdentityCertificate> idCert = io::load<v1::IdentityCertificate>(ss);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700455
Zhiyi Zhang044bb7e2016-06-10 00:02:37 -0700456 if (static_cast<bool>(idCert))
457 return idCert;
458 else
459 BOOST_THROW_EXCEPTION(Error("Cannot decode certificate from string"));
460 }
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700461 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700462 BOOST_THROW_EXCEPTION(Error("Unsupported checker.signer type: " + type));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700463 }
464
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700465 static uint32_t
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700466 getSigType(const std::string& sigType)
467 {
468 if (boost::iequals(sigType, "rsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600469 return tlv::SignatureSha256WithRsa;
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700470 else if (boost::iequals(sigType, "ecdsa-sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600471 return tlv::SignatureSha256WithEcdsa;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700472 else if (boost::iequals(sigType, "sha256"))
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600473 return tlv::DigestSha256;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700474 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700475 BOOST_THROW_EXCEPTION(Error("Unsupported signature type"));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700476 }
477};
478
479} // namespace conf
480} // namespace security
481} // namespace ndn
482
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700483#endif // NDN_SECURITY_CONF_CHECKER_HPP