blob: 6d702ab786248673855619abeadc5c9e808c6509 [file] [log] [blame]
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08002/*
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -07003 * Copyright (c) 2013-2017 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * 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.
20 */
21
22#include "trust-anchor-group.hpp"
23
24#include "util/io.hpp"
25#include "util/logger.hpp"
26
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -070027#include <boost/filesystem.hpp>
28#include <boost/range/adaptor/map.hpp>
29#include <boost/range/algorithm/copy.hpp>
30#include <boost/range/iterator_range.hpp>
31
32namespace ndn {
33namespace security {
34namespace v2 {
35
36NDN_LOG_INIT(ndn.security.v2.TrustAnchorGroup);
37
38namespace fs = boost::filesystem;
39
40TrustAnchorGroup::TrustAnchorGroup(CertContainerInterface& certContainer, const std::string& id)
41 : m_certs(certContainer)
42 , m_id(id)
43{
44}
45
Davide Pesavento7f20d6e2017-01-16 14:43:58 -050046TrustAnchorGroup::~TrustAnchorGroup() = default;
47
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -070048size_t
49TrustAnchorGroup::size() const
50{
51 return m_anchorNames.size();
52}
53
54void
55TrustAnchorGroup::refresh()
56{
57 // base method does nothing
58}
59
60//////////////
61
62StaticTrustAnchorGroup::StaticTrustAnchorGroup(CertContainerInterface& certContainer, const std::string& id)
63 : TrustAnchorGroup(certContainer, id)
64{
65}
66
67void
68StaticTrustAnchorGroup::add(Certificate&& cert)
69{
70 if (m_anchorNames.count(cert.getName()) != 0) {
71 return;
72 }
73
74 m_anchorNames.insert(cert.getName());
75 m_certs.add(std::move(cert));
76}
77
78void
79StaticTrustAnchorGroup::remove(const Name& certName)
80{
81 m_anchorNames.erase(certName);
82 m_certs.remove(certName);
83}
84
85/////////////
86
87DynamicTrustAnchorGroup::DynamicTrustAnchorGroup(CertContainerInterface& certContainer, const std::string& id,
88 const boost::filesystem::path& path,
89 time::nanoseconds refreshPeriod, bool isDir)
90 : TrustAnchorGroup(certContainer, id)
91 , m_isDir(isDir)
92 , m_path(path)
93 , m_refreshPeriod(refreshPeriod)
94{
95 if (refreshPeriod <= time::nanoseconds::zero()) {
96 BOOST_THROW_EXCEPTION(std::runtime_error("Refresh period for the dynamic group must be positive"));
97 }
98
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080099 NDN_LOG_TRACE("Create dynamic trust anchor group " << id << " for file/dir " << path
100 << " with refresh time " << refreshPeriod);
Qiuhan Ding4caa0cc2015-10-23 20:31:27 -0700101 refresh();
102}
103
104void
105DynamicTrustAnchorGroup::refresh()
106{
107 if (m_expireTime > time::steady_clock::now()) {
108 return;
109 }
110 m_expireTime = time::steady_clock::now() + m_refreshPeriod;
111 NDN_LOG_TRACE("Reloading dynamic trust anchor group");
112
113 std::set<Name> oldAnchorNames = m_anchorNames;
114
115 auto loadCert = [this, &oldAnchorNames] (const fs::path& file) {
116 auto cert = io::load<Certificate>(file.string());
117 if (cert != nullptr) {
118 if (m_anchorNames.count(cert->getName()) == 0) {
119 m_anchorNames.insert(cert->getName());
120 m_certs.add(std::move(*cert));
121 }
122 else {
123 oldAnchorNames.erase(cert->getName());
124 }
125 }
126 };
127
128 if (!m_isDir) {
129 loadCert(m_path);
130 }
131 else {
132 if (fs::exists(m_path)) {
133 std::for_each(fs::directory_iterator(m_path), fs::directory_iterator(), loadCert);
134 }
135 }
136
137 // remove old certs
138 for (const auto& oldAnchorName : oldAnchorNames) {
139 m_anchorNames.erase(oldAnchorName);
140 m_certs.remove(oldAnchorName);
141 }
142}
143
144} // namespace v2
145} // namespace security
146} // namespace ndn