certificate-store.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2024, The University of Memphis,
4  * 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/>.
20  */
21 
22 #include "certificate-store.hpp"
23 #include "conf-parameter.hpp"
24 #include "logger.hpp"
25 #include "lsdb.hpp"
26 
27 #include <ndn-cxx/util/io.hpp>
28 #include <fstream>
29 
30 namespace nlsr {
31 namespace security {
32 
34 
35 CertificateStore::CertificateStore(ndn::Face& face, ConfParameter& confParam, Lsdb& lsdb)
36  : m_face(face)
37  , m_confParam(confParam)
38  , m_validator(m_confParam.getValidator())
39 {
40  for (const auto& certfile : confParam.getIdCerts()) {
41  std::ifstream ifs(certfile);
42  insert(ndn::io::loadTlv<ndn::security::Certificate>(ifs));
43  }
44 
45  registerKeyPrefixes();
46 
47  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  });
60 }
61 
62 void
63 CertificateStore::insert(const ndn::security::Certificate& certificate)
64 {
65  m_certificates[certificate.getKeyName()] = certificate;
66  NLSR_LOG_TRACE("Certificate inserted successfully\n" << certificate);
67 }
68 
69 const ndn::security::Certificate*
70 CertificateStore::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 
78 const ndn::security::Certificate*
79 CertificateStore::findByKeyName(const ndn::Name& keyName) const
80 {
81  auto it = m_certificates.find(keyName);
82  return it != m_certificates.end() ? &it->second : nullptr;
83 }
84 
85 const ndn::security::Certificate*
86 CertificateStore::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 
95 void
96 CertificateStore::setInterestFilter(const ndn::Name& prefix)
97 {
98  m_face.setInterestFilter(ndn::InterestFilter(prefix).allowLoopback(false),
99  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 
105 void
106 CertificateStore::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");
113  nlsrKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
114  prefixes.push_back(nlsrKeyPrefix);
115 
116  // Router's certificate
117  ndn::Name routerKeyPrefix = m_confParam.getRouterPrefix();
118  routerKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
119  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());
130  siteKeyPrefix.append(ndn::security::Certificate::KEY_COMPONENT);
131  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 
140 void
141 CertificateStore::onKeyInterest(const ndn::Name&, const ndn::Interest& interest)
142 {
143  NLSR_LOG_TRACE("Got certificate Interest: " << interest.getName());
144 
145  const auto* cert = find(interest.getName());
146  if (!cert) {
147  NLSR_LOG_DEBUG("Certificate not found for: " << interest.getName());
148  return;
149  }
150 
151  m_face.put(*cert);
152 }
153 
154 void
155 CertificateStore::onKeyPrefixRegSuccess(const ndn::Name& name)
156 {
157  NLSR_LOG_DEBUG("Prefix registered successfully: " << name);
158 }
159 
160 void
161 CertificateStore::registrationFailed(const ndn::Name& name)
162 {
163  NLSR_LOG_ERROR("Failed to register prefix: " << name);
164  NDN_THROW(std::runtime_error("Prefix registration failed: " + name.toUri()));
165 }
166 
167 void
168 CertificateStore::publishCertFromCache(const ndn::Name& keyName)
169 {
170  const auto* cert = m_validator.getUnverifiedCertCache().find(keyName);
171 
172  if (cert) {
173  insert(*cert);
174  ndn::Name certName = ndn::security::extractKeyNameFromCertName(cert->getName());
175  NLSR_LOG_TRACE("Setting interest filter for: " << certName);
176 
177  setInterestFilter(certName);
178 
179  const ndn::Name& keyLocatorName = cert->getSignatureInfo().getKeyLocator().getName();
180  if (cert->getKeyName() != keyLocatorName) {
181  publishCertFromCache(keyLocatorName);
182  }
183  }
184  else {
185  // Happens for root cert
186  NLSR_LOG_TRACE("Cert for " << keyName << " was not found in the Validator's cache");
187  }
188 }
189 
190 } // namespace security
191 } // namespace nlsr
A class to house all the configuration parameters for NLSR.
const ndn::security::SigningInfo & getSigningInfo() const
const ndn::Name & getSiteName() const
const std::unordered_set< std::string > & getIdCerts() const
const ndn::Name & getNetwork() const
const ndn::Name & getRouterPrefix() const
ndn::signal::Signal< Lsdb, ndn::Data > afterSegmentValidatedSignal
Definition: lsdb.hpp:336
Store certificates for names.
const ndn::security::Certificate * find(const ndn::Name &name) const
Find a certificate.
void insert(const ndn::security::Certificate &certificate)
CertificateStore(ndn::Face &face, ConfParameter &confParam, Lsdb &lsdb)
void publishCertFromCache(const ndn::Name &keyName)
Retrieves the chain of certificates from Validator's cache and store them in Nlsr's own CertificateSt...
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
#define INIT_LOGGER(name)
Definition: logger.hpp:35
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.