blob: 648be4b548c5d9994fadc846530f348953d61f35 [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/*
Davide Pesaventob6adfe12024-07-05 13:03:15 -04003 * Copyright (c) 2014-2024, 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"
Davide Pesaventob6adfe12024-07-05 13:03:15 -040025#include "lsdb.hpp"
Saurab Dulal427e0122019-11-28 11:58:02 -060026
27#include <ndn-cxx/util/io.hpp>
Davide Pesavento7bc3d432021-10-25 21:08:04 -040028#include <fstream>
Saurab Dulal427e0122019-11-28 11:58:02 -060029
30namespace nlsr {
31namespace security {
32
33INIT_LOGGER(CertificateStore);
34
35CertificateStore::CertificateStore(ndn::Face& face, ConfParameter& confParam, Lsdb& lsdb)
36 : m_face(face)
37 , m_confParam(confParam)
Saurab Dulal427e0122019-11-28 11:58:02 -060038 , m_validator(m_confParam.getValidator())
Saurab Dulal427e0122019-11-28 11:58:02 -060039{
Davide Pesavento7bc3d432021-10-25 21:08:04 -040040 for (const auto& certfile : confParam.getIdCerts()) {
41 std::ifstream ifs(certfile);
42 insert(ndn::io::loadTlv<ndn::security::Certificate>(ifs));
Saurab Dulal427e0122019-11-28 11:58:02 -060043 }
44
45 registerKeyPrefixes();
Ashlesh Gawande5d93aa52020-06-13 18:57:45 -070046
Davide Pesaventob6adfe12024-07-05 13:03:15 -040047 m_afterSegmentValidatedConn = lsdb.afterSegmentValidatedSignal.connect([this] (const auto& data) {
48 const auto kl = data.getKeyLocator();
49 if (!kl || kl->getType() != ndn::tlv::Name) {
50 NLSR_LOG_TRACE("Cannot determine KeyLocator Name for: " << data.getName());
51 }
52 else if (const auto klName = kl->getName(); !find(klName)) {
53 NLSR_LOG_TRACE("Publishing certificate for: " << klName);
54 publishCertFromCache(klName);
55 }
56 else {
57 NLSR_LOG_TRACE("Certificate is already in the store: " << klName);
58 }
59 });
Saurab Dulal427e0122019-11-28 11:58:02 -060060}
61
62void
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040063CertificateStore::insert(const ndn::security::Certificate& certificate)
Saurab Dulal427e0122019-11-28 11:58:02 -060064{
65 m_certificates[certificate.getKeyName()] = certificate;
Davide Pesaventob6adfe12024-07-05 13:03:15 -040066 NLSR_LOG_TRACE("Certificate inserted successfully\n" << certificate);
Saurab Dulal427e0122019-11-28 11:58:02 -060067}
68
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -040069const ndn::security::Certificate*
Junxiao Shib032fcb2022-04-28 01:28:50 +000070CertificateStore::find(const ndn::Name& name) const
71{
72 if (ndn::security::Certificate::isValidName(name)) {
73 return findByCertName(name);
74 }
75 return findByKeyName(name);
76}
77
78const ndn::security::Certificate*
79CertificateStore::findByKeyName(const ndn::Name& keyName) const
Saurab Dulal427e0122019-11-28 11:58:02 -060080{
81 auto it = m_certificates.find(keyName);
82 return it != m_certificates.end() ? &it->second : nullptr;
83}
84
Junxiao Shib032fcb2022-04-28 01:28:50 +000085const ndn::security::Certificate*
86CertificateStore::findByCertName(const ndn::Name& certName) const
87{
88 auto found = findByKeyName(ndn::security::extractKeyNameFromCertName(certName));
89 if (found == nullptr || found->getName() != certName) {
90 return nullptr;
91 }
92 return found;
93}
94
Saurab Dulal427e0122019-11-28 11:58:02 -060095void
Davide Pesaventob6adfe12024-07-05 13:03:15 -040096CertificateStore::setInterestFilter(const ndn::Name& prefix)
Saurab Dulal427e0122019-11-28 11:58:02 -060097{
Davide Pesaventob6adfe12024-07-05 13:03:15 -040098 m_face.setInterestFilter(ndn::InterestFilter(prefix).allowLoopback(false),
Saurab Dulal427e0122019-11-28 11:58:02 -060099 std::bind(&CertificateStore::onKeyInterest, this, _1, _2),
100 std::bind(&CertificateStore::onKeyPrefixRegSuccess, this, _1),
101 std::bind(&CertificateStore::registrationFailed, this, _1),
102 m_confParam.getSigningInfo(), ndn::nfd::ROUTE_FLAG_CAPTURE);
103}
104
105void
106CertificateStore::registerKeyPrefixes()
107{
108 std::vector<ndn::Name> prefixes;
109
110 // Router's NLSR certificate
111 ndn::Name nlsrKeyPrefix = m_confParam.getRouterPrefix();
112 nlsrKeyPrefix.append("nlsr");
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700113 nlsrKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600114 prefixes.push_back(nlsrKeyPrefix);
115
116 // Router's certificate
117 ndn::Name routerKeyPrefix = m_confParam.getRouterPrefix();
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700118 routerKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600119 prefixes.push_back(routerKeyPrefix);
120
121 // Router's operator's certificate
122 ndn::Name operatorKeyPrefix = m_confParam.getNetwork();
123 operatorKeyPrefix.append(m_confParam.getSiteName());
124 operatorKeyPrefix.append(std::string("%C1.Operator"));
125 prefixes.push_back(operatorKeyPrefix);
126
127 // Router's site's certificate
128 ndn::Name siteKeyPrefix = m_confParam.getNetwork();
129 siteKeyPrefix.append(m_confParam.getSiteName());
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700130 siteKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
Saurab Dulal427e0122019-11-28 11:58:02 -0600131 prefixes.push_back(siteKeyPrefix);
132
133 // Start listening for interest of this router's NLSR certificate,
134 // router's certificate and site's certificate
135 for (const auto& i : prefixes) {
136 setInterestFilter(i);
137 }
138}
139
140void
Junxiao Shib032fcb2022-04-28 01:28:50 +0000141CertificateStore::onKeyInterest(const ndn::Name&, const ndn::Interest& interest)
Saurab Dulal427e0122019-11-28 11:58:02 -0600142{
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400143 NLSR_LOG_TRACE("Got certificate Interest: " << interest.getName());
Saurab Dulal427e0122019-11-28 11:58:02 -0600144
145 const auto* cert = find(interest.getName());
Saurab Dulal427e0122019-11-28 11:58:02 -0600146 if (!cert) {
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400147 NLSR_LOG_DEBUG("Certificate not found for: " << interest.getName());
Saurab Dulal427e0122019-11-28 11:58:02 -0600148 return;
149 }
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400150
Saurab Dulal427e0122019-11-28 11:58:02 -0600151 m_face.put(*cert);
152}
153
154void
155CertificateStore::onKeyPrefixRegSuccess(const ndn::Name& name)
156{
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400157 NLSR_LOG_DEBUG("Prefix registered successfully: " << name);
Saurab Dulal427e0122019-11-28 11:58:02 -0600158}
159
160void
161CertificateStore::registrationFailed(const ndn::Name& name)
162{
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400163 NLSR_LOG_ERROR("Failed to register prefix: " << name);
164 NDN_THROW(std::runtime_error("Prefix registration failed: " + name.toUri()));
Saurab Dulal427e0122019-11-28 11:58:02 -0600165}
166
167void
168CertificateStore::publishCertFromCache(const ndn::Name& keyName)
169{
170 const auto* cert = m_validator.getUnverifiedCertCache().find(keyName);
171
172 if (cert) {
173 insert(*cert);
Alexander Afanasyev0ad01f32020-06-03 14:12:58 -0400174 ndn::Name certName = ndn::security::extractKeyNameFromCertName(cert->getName());
Saurab Dulal427e0122019-11-28 11:58:02 -0600175 NLSR_LOG_TRACE("Setting interest filter for: " << certName);
176
177 setInterestFilter(certName);
178
Ashlesh Gawande7a231c02020-06-12 20:06:44 -0700179 const ndn::Name& keyLocatorName = cert->getSignatureInfo().getKeyLocator().getName();
180 if (cert->getKeyName() != keyLocatorName) {
181 publishCertFromCache(keyLocatorName);
Saurab Dulal427e0122019-11-28 11:58:02 -0600182 }
183 }
184 else {
185 // Happens for root cert
Davide Pesaventob6adfe12024-07-05 13:03:15 -0400186 NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache");
Saurab Dulal427e0122019-11-28 11:58:02 -0600187 }
188}
189
190} // namespace security
191} // namespace nlsr