blob: f679fb15e76fcbc021e9658bcb8b53b8b107ae80 [file] [log] [blame]
Saurab Dulal427e0122019-11-28 11:58:02 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -04002/*
Junxiao Shib032fcb2022-04-28 01:28:50 +00003 * Copyright (c) 2014-2022, The University of Memphis,
Saurab Dulal427e0122019-11-28 11:58:02 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040020 */
Saurab Dulal427e0122019-11-28 11:58:02 -060021
22#include "certificate-store.hpp"
23#include "conf-parameter.hpp"
24#include "logger.hpp"
25
26#include <ndn-cxx/util/io.hpp>
Davide Pesavento7bc3d432021-10-25 21:08:04 -040027#include <fstream>
Saurab Dulal427e0122019-11-28 11:58:02 -060028
29namespace nlsr {
30namespace security {
31
32INIT_LOGGER(CertificateStore);
33
34CertificateStore::CertificateStore(ndn::Face& face, ConfParameter& confParam, Lsdb& lsdb)
35 : m_face(face)
36 , m_confParam(confParam)
Saurab Dulal427e0122019-11-28 11:58:02 -060037 , m_validator(m_confParam.getValidator())
Saurab Dulal427e0122019-11-28 11:58:02 -060038{
Davide Pesavento7bc3d432021-10-25 21:08:04 -040039 for (const auto& certfile : confParam.getIdCerts()) {
40 std::ifstream ifs(certfile);
41 insert(ndn::io::loadTlv<ndn::security::Certificate>(ifs));
Saurab Dulal427e0122019-11-28 11:58:02 -060042 }
43
44 registerKeyPrefixes();
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -070045
46 m_afterSegmentValidatedConnection = lsdb.afterSegmentValidatedSignal.connect(
47 [this] (const ndn::Data& data) { afterFetcherSignalEmitted(data); });
Saurab Dulal427e0122019-11-28 11:58:02 -060048}
49
50void
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040051CertificateStore::insert(const ndn::security::Certificate& certificate)
Saurab Dulal427e0122019-11-28 11:58:02 -060052{
53 m_certificates[certificate.getKeyName()] = certificate;
54 NLSR_LOG_TRACE("Certificate inserted successfully");
55}
56
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040057const ndn::security::Certificate*
Junxiao Shib032fcb2022-04-28 01:28:50 +000058CertificateStore::find(const ndn::Name& name) const
59{
60 if (ndn::security::Certificate::isValidName(name)) {
61 return findByCertName(name);
62 }
63 return findByKeyName(name);
64}
65
66const ndn::security::Certificate*
67CertificateStore::findByKeyName(const ndn::Name& keyName) const
Saurab Dulal427e0122019-11-28 11:58:02 -060068{
69 auto it = m_certificates.find(keyName);
70 return it != m_certificates.end() ? &it->second : nullptr;
71}
72
Junxiao Shib032fcb2022-04-28 01:28:50 +000073const ndn::security::Certificate*
74CertificateStore::findByCertName(const ndn::Name& certName) const
75{
76 auto found = findByKeyName(ndn::security::extractKeyNameFromCertName(certName));
77 if (found == nullptr || found->getName() != certName) {
78 return nullptr;
79 }
80 return found;
81}
82
Saurab Dulal427e0122019-11-28 11:58:02 -060083void
84CertificateStore::clear()
85{
86 m_certificates.clear();
87}
88
89void
90CertificateStore::setInterestFilter(const ndn::Name& prefix, bool loopback)
91{
92 m_face.setInterestFilter(ndn::InterestFilter(prefix).allowLoopback(loopback),
93 std::bind(&CertificateStore::onKeyInterest, this, _1, _2),
94 std::bind(&CertificateStore::onKeyPrefixRegSuccess, this, _1),
95 std::bind(&CertificateStore::registrationFailed, this, _1),
96 m_confParam.getSigningInfo(), ndn::nfd::ROUTE_FLAG_CAPTURE);
97}
98
99void
100CertificateStore::registerKeyPrefixes()
101{
102 std::vector<ndn::Name> prefixes;
103
104 // Router's NLSR certificate
105 ndn::Name nlsrKeyPrefix = m_confParam.getRouterPrefix();
106 nlsrKeyPrefix.append("nlsr");
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700107 nlsrKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600108 prefixes.push_back(nlsrKeyPrefix);
109
110 // Router's certificate
111 ndn::Name routerKeyPrefix = m_confParam.getRouterPrefix();
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700112 routerKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600113 prefixes.push_back(routerKeyPrefix);
114
115 // Router's operator's certificate
116 ndn::Name operatorKeyPrefix = m_confParam.getNetwork();
117 operatorKeyPrefix.append(m_confParam.getSiteName());
118 operatorKeyPrefix.append(std::string("%C1.Operator"));
119 prefixes.push_back(operatorKeyPrefix);
120
121 // Router's site's certificate
122 ndn::Name siteKeyPrefix = m_confParam.getNetwork();
123 siteKeyPrefix.append(m_confParam.getSiteName());
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700124 siteKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600125 prefixes.push_back(siteKeyPrefix);
126
127 // Start listening for interest of this router's NLSR certificate,
128 // router's certificate and site's certificate
129 for (const auto& i : prefixes) {
130 setInterestFilter(i);
131 }
132}
133
134void
Junxiao Shib032fcb2022-04-28 01:28:50 +0000135CertificateStore::onKeyInterest(const ndn::Name&, const ndn::Interest& interest)
Saurab Dulal427e0122019-11-28 11:58:02 -0600136{
137 NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
138
139 const auto* cert = find(interest.getName());
140
141 if (!cert) {
142 NLSR_LOG_TRACE("Certificate is not found for: " << interest);
143 return;
144 }
145 m_face.put(*cert);
146}
147
148void
149CertificateStore::onKeyPrefixRegSuccess(const ndn::Name& name)
150{
Davide Pesaventod90338d2021-01-07 17:50:05 -0500151 NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful");
Saurab Dulal427e0122019-11-28 11:58:02 -0600152}
153
154void
155CertificateStore::registrationFailed(const ndn::Name& name)
156{
Davide Pesaventod90338d2021-01-07 17:50:05 -0500157 NLSR_LOG_ERROR("Failed to register prefix " << name);
158 NDN_THROW(std::runtime_error("Prefix registration failed"));
Saurab Dulal427e0122019-11-28 11:58:02 -0600159}
160
161void
162CertificateStore::publishCertFromCache(const ndn::Name& keyName)
163{
164 const auto* cert = m_validator.getUnverifiedCertCache().find(keyName);
165
166 if (cert) {
167 insert(*cert);
168 NLSR_LOG_TRACE(*cert);
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -0400169 ndn::Name certName = ndn::security::extractKeyNameFromCertName(cert->getName());
Saurab Dulal427e0122019-11-28 11:58:02 -0600170 NLSR_LOG_TRACE("Setting interest filter for: " << certName);
171
172 setInterestFilter(certName);
173
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700174 const ndn::Name& keyLocatorName = cert->getSignatureInfo().getKeyLocator().getName();
175 if (cert->getKeyName() != keyLocatorName) {
176 publishCertFromCache(keyLocatorName);
Saurab Dulal427e0122019-11-28 11:58:02 -0600177 }
178 }
179 else {
180 // Happens for root cert
181 NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache. ");
182 }
183}
184
185void
186CertificateStore::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
187{
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700188 const auto keyName = lsaSegment.getSignatureInfo().getKeyLocator().getName();
Saurab Dulal427e0122019-11-28 11:58:02 -0600189 if (!find(keyName)) {
190 NLSR_LOG_TRACE("Publishing certificate for: " << keyName);
191 publishCertFromCache(keyName);
192 }
193 else {
194 NLSR_LOG_TRACE("Certificate is already in the store: " << keyName);
195 }
196}
197
198} // namespace security
199} // namespace nlsr