conf+security: accommodate certificate name in KeyLocator
refs #5195
Change-Id: I88709f891fe78fc9f2699bc021d35ca72ebc6850
diff --git a/nlsr.conf b/nlsr.conf
index fd2ad23..bfed00b 100644
--- a/nlsr.conf
+++ b/nlsr.conf
@@ -4,7 +4,7 @@
{
; mandatory configuration command section network, site and router
- network /ndn/ ; name of the network the router belongs to in ndn URI format
+ network /ndn ; name of the network the router belongs to in ndn URI format
site /edu/memphis ; name of the site the router belongs to in ndn URI format
router /%C1.Router/cs/pollux ; name of the router in ndn URI format
@@ -150,7 +150,7 @@
type name
hyper-relation
{
- k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>$
+ k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
k-expand \\1
h-relation equal
p-regex ^([^<nlsr><INFO>]*)<nlsr><INFO><><>$
@@ -178,7 +178,7 @@
type name
hyper-relation
{
- k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>$
+ k-regex ^([^<KEY><nlsr>]*)<nlsr><KEY><>{1,3}$
k-expand \\1
h-relation equal
; the last four components in the prefix should be <lsaType><seqNo><version><segmentNo>
@@ -235,7 +235,7 @@
type name
hyper-relation
{
- k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
+ k-regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
k-expand \\1
h-relation equal
p-regex ^([^<KEY><%C1.Router>]*)<%C1.Router>[^<KEY>]*<KEY><><><>$
@@ -288,7 +288,7 @@
key-locator
{
type name
- regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>$
+ regex ^([^<KEY><%C1.Operator>]*)<%C1.Operator>[^<KEY>]*<KEY><>{1,3}$
}
}
}
diff --git a/src/conf-parameter.cpp b/src/conf-parameter.cpp
index e313b1f..205c67c 100644
--- a/src/conf-parameter.cpp
+++ b/src/conf-parameter.cpp
@@ -20,6 +20,7 @@
#include "conf-parameter.hpp"
#include "logger.hpp"
+#include <ndn-cxx/security/signing-helpers.hpp>
namespace nlsr {
@@ -118,69 +119,38 @@
m_prefixUpdateValidator.loadAnchor("Authoritative-Certificate", ndn::security::Certificate(cert));
}
-std::shared_ptr<ndn::security::Certificate>
+ndn::optional<ndn::security::Certificate>
ConfParameter::initializeKey()
{
+ using namespace ndn::security;
NLSR_LOG_DEBUG("Initializing Key ...");
- ndn::Name nlsrInstanceName(m_routerPrefix);
- nlsrInstanceName.append("nlsr");
-
+ Identity routerIdentity;
try {
- m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
+ routerIdentity = m_keyChain.getPib().getIdentity(m_routerPrefix);
}
- catch (const std::exception& e) {
- NLSR_LOG_WARN(e.what());
- }
-
- ndn::security::Identity nlsrInstanceIdentity;
- try {
- nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
- }
- catch (const std::exception& e) {
- NLSR_LOG_ERROR(e.what());
- NLSR_LOG_ERROR("Unable to create identity, NLSR will run without security!");
- NLSR_LOG_ERROR("Can be ignored if running in non-production environments.");
- return nullptr;
- }
- auto certificate = std::make_shared<ndn::security::Certificate>();
- auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
- ndn::Name certificateName = nlsrInstanceKey.getName();
- certificateName.append("NA");
- certificateName.appendVersion();
-
- certificate->setName(certificateName);
-
- // set metainfo
- certificate->setContentType(ndn::tlv::ContentType_Key);
- certificate->setFreshnessPeriod(365_days);
-
- // set content
- certificate->setContent(nlsrInstanceKey.getPublicKey());
-
- // set signature-info
- ndn::SignatureInfo signatureInfo;
- signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
- ndn::time::system_clock::now()
- + 365_days));
-
- try {
- m_keyChain.sign(*certificate,
- ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_routerPrefix))
- .setSignatureInfo(signatureInfo));
- }
- catch (const std::exception& e) {
- NLSR_LOG_ERROR("Router's " << e.what() << ", NLSR is running without security. " <<
+ catch (const Pib::Error&) {
+ NLSR_LOG_ERROR("Router identity " << m_routerPrefix << " not found. "
+ "NLSR is running without security. "
"If security is enabled in the configuration, NLSR will not converge.");
-
+ return ndn::nullopt;
}
- m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
- nlsrInstanceName);
+ auto instanceName = ndn::Name(m_routerPrefix).append("nlsr");
+ try {
+ m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(instanceName));
+ }
+ catch (const Pib::Error&) {
+ // old instance identity does not exist
+ }
- loadCertToValidator(*certificate);
+ auto key = m_keyChain.createIdentity(instanceName).getDefaultKey();
+ auto cert = m_keyChain.makeCertificate(key, signingByIdentity(routerIdentity));
+ m_keyChain.setDefaultCertificate(key, cert);
- return certificate;
+ m_signingInfo = signingByCertificate(cert);
+ loadCertToValidator(cert);
+ return cert;
}
} // namespace nlsr
diff --git a/src/conf-parameter.hpp b/src/conf-parameter.hpp
index 57dd2c2..9989803 100644
--- a/src/conf-parameter.hpp
+++ b/src/conf-parameter.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2021, The University of Memphis,
+ * Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -475,7 +475,7 @@
return m_keyChain;
}
- std::shared_ptr<ndn::security::Certificate>
+ ndn::optional<ndn::security::Certificate>
initializeKey();
void
diff --git a/src/security/certificate-store.cpp b/src/security/certificate-store.cpp
index 9fcaf84..f679fb1 100644
--- a/src/security/certificate-store.cpp
+++ b/src/security/certificate-store.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2021, The University of Memphis,
+ * Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -55,12 +55,31 @@
}
const ndn::security::Certificate*
-CertificateStore::find(const ndn::Name& keyName) const
+CertificateStore::find(const ndn::Name& name) const
+{
+ if (ndn::security::Certificate::isValidName(name)) {
+ return findByCertName(name);
+ }
+ return findByKeyName(name);
+}
+
+const ndn::security::Certificate*
+CertificateStore::findByKeyName(const ndn::Name& keyName) const
{
auto it = m_certificates.find(keyName);
return it != m_certificates.end() ? &it->second : nullptr;
}
+const ndn::security::Certificate*
+CertificateStore::findByCertName(const ndn::Name& certName) const
+{
+ auto found = findByKeyName(ndn::security::extractKeyNameFromCertName(certName));
+ if (found == nullptr || found->getName() != certName) {
+ return nullptr;
+ }
+ return found;
+}
+
void
CertificateStore::clear()
{
@@ -113,7 +132,7 @@
}
void
-CertificateStore::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
+CertificateStore::onKeyInterest(const ndn::Name&, const ndn::Interest& interest)
{
NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
diff --git a/src/security/certificate-store.hpp b/src/security/certificate-store.hpp
index 79a0cf7..2a47caa 100644
--- a/src/security/certificate-store.hpp
+++ b/src/security/certificate-store.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2021, The University of Memphis,
+ * Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -44,23 +44,24 @@
*/
class CertificateStore
{
-
public:
CertificateStore(ndn::Face& face, ConfParameter& confParam, Lsdb& lsdb);
void
insert(const ndn::security::Certificate& certificate);
- /*! \brief Find a certificate
+ /*!
+ * \brief Find a certificate
+ * \param name Either key name or certificate name.
*
* Find a certificate that NLSR has. First it checks against the
* certificates this NLSR claims to be authoritative for, usually
* something like this specific router's certificate, and then
* checks the cache of certificates it has already fetched. If none
* can be found, it will return an null pointer.
- */
+ */
const ndn::security::Certificate*
- find(const ndn::Name& keyName) const;
+ find(const ndn::Name& name) const;
/*! \brief Retrieves the chain of certificates from Validator's cache and
* store them in Nlsr's own CertificateStore.
@@ -73,6 +74,12 @@
afterFetcherSignalEmitted(const ndn::Data& lsaSegment);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ const ndn::security::Certificate*
+ findByKeyName(const ndn::Name& keyName) const;
+
+ const ndn::security::Certificate*
+ findByCertName(const ndn::Name& certName) const;
+
void
clear();
diff --git a/tests/security/test-certificate-store.cpp b/tests/security/test-certificate-store.cpp
index ffb94d1..216aba5 100644
--- a/tests/security/test-certificate-store.cpp
+++ b/tests/security/test-certificate-store.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2021, The University of Memphis,
+ * Copyright (c) 2014-2022, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -59,26 +59,21 @@
opIdentity = addSubCertificate(opIdentityName, siteIdentity);
routerId = addSubCertificate(routerIdName, opIdentity);
- auto certificate = conf.initializeKey();
- if (certificate) {
- certStore.insert(*certificate);
- };
+ auto instanceCert = conf.initializeKey();
+ BOOST_REQUIRE(!!instanceCert);
+ certStore.insert(*instanceCert);
+ instanceCertName = instanceCert->getName();
// Create certificate and load it to the validator
// previously this was done by in nlsr ctor
- conf.loadCertToValidator(rootId.getDefaultKey().getDefaultCertificate());
- conf.loadCertToValidator(siteIdentity.getDefaultKey().getDefaultCertificate());
- conf.loadCertToValidator(opIdentity.getDefaultKey().getDefaultCertificate());
- conf.loadCertToValidator(routerId.getDefaultKey().getDefaultCertificate());
-
- std::ifstream inputFile;
- inputFile.open(std::string("nlsr.conf"));
-
- BOOST_REQUIRE(inputFile.is_open());
+ for (const auto& id : {rootId, siteIdentity, opIdentity, routerId}) {
+ const auto& cert = id.getDefaultKey().getDefaultCertificate();
+ conf.loadCertToValidator(cert);
+ certStore.insert(cert);
+ }
boost::property_tree::ptree pt;
-
- boost::property_tree::read_info(inputFile, pt);
+ boost::property_tree::read_info("nlsr.conf", pt);
// Load security section and file name
for (const auto& tn : pt) {
@@ -88,9 +83,8 @@
break;
}
}
- inputFile.close();
- this->advanceClocks(ndn::time::milliseconds(20));
+ advanceClocks(20_ms);
}
public:
@@ -114,6 +108,7 @@
ndn::Name rootIdName, siteIdentityName, opIdentityName, routerIdName;
ndn::security::pib::Identity rootId, siteIdentity, opIdentity, routerId;
+ ndn::Name instanceCertName;
Nlsr nlsr;
Lsdb& lsdb;
@@ -136,12 +131,14 @@
ndn::Name certKey = certificate.getKeyName();
BOOST_CHECK(certStore.find(certKey) == nullptr);
+ BOOST_CHECK(certStore.find(certificate.getName()) == nullptr);
// Certificate should be retrievable from the CertificateStore
certStore.insert(certificate);
conf.loadCertToValidator(certificate);
BOOST_CHECK(certStore.find(certKey) != nullptr);
+ BOOST_CHECK(certStore.find(certificate.getName()) != nullptr);
lsdb.expressInterest(certKey, 0);
@@ -149,6 +146,41 @@
checkForInterest(certKey);
}
+BOOST_AUTO_TEST_CASE(RetrieveCert)
+{
+ ndn::util::DummyClientFace consumer(m_ioService);
+ consumer.linkTo(face);
+
+ auto checkRetrieve = [&] (const ndn::Name& interestName, bool canBePrefix, const ndn::Name& dataName) {
+ ndn::Interest interest(interestName);
+ interest.setCanBePrefix(canBePrefix);
+ BOOST_TEST_CONTEXT(interest) {
+ bool hasData = false;
+ consumer.expressInterest(interest,
+ [&] (const auto&, const auto& data) {
+ BOOST_CHECK(!hasData);
+ hasData = true;
+ BOOST_CHECK_EQUAL(data.getName(), dataName);
+ },
+ [&] (const auto&, const auto&) { BOOST_ERROR("unexpected Nack"); },
+ [&] (const auto&) { BOOST_ERROR("unexpected timeout"); }
+ );
+ advanceClocks(10_ms, 2);
+ BOOST_CHECK(hasData);
+ }
+ };
+
+ for (const auto& id : {siteIdentity, opIdentity, routerId}) {
+ auto key = id.getDefaultKey();
+ auto cert = key.getDefaultCertificate();
+ checkRetrieve(key.getName(), true, cert.getName());
+ checkRetrieve(cert.getName(), false, cert.getName());
+ }
+
+ checkRetrieve(ndn::security::extractKeyNameFromCertName(instanceCertName), true, instanceCertName);
+ checkRetrieve(instanceCertName, false, instanceCertName);
+}
+
BOOST_AUTO_TEST_CASE(TestKeyPrefixRegistration)
{
// check if nlsrKeyPrefix is registered
@@ -202,12 +234,13 @@
// Make NLSR validate data signed by its own key
conf.getValidator().validate(data,
[] (const ndn::Data&) { BOOST_CHECK(true); },
- [] (const ndn::Data&, const ndn::security::ValidationError&) {
- BOOST_CHECK(false);
+ [] (const ndn::Data&, const ndn::security::ValidationError& e) {
+ BOOST_ERROR(e);
});
lsdb.emitSegmentValidatedSignal(data);
- const auto keyName = data.getSignatureInfo().getKeyLocator().getName();
+ auto certName = data.getSignatureInfo().getKeyLocator().getName();
+ auto keyName = ndn::security::extractKeyNameFromCertName(certName);
BOOST_CHECK(certStore.find(keyName) != nullptr);
// testing a callback after segment validation signal from lsdb
diff --git a/tests/test-lsa-rule.cpp b/tests/test-lsa-rule.cpp
index 2b6faf4..557b540 100644
--- a/tests/test-lsa-rule.cpp
+++ b/tests/test-lsa-rule.cpp
@@ -65,21 +65,15 @@
saveCertificate(rootId, ROOT_CERT_PATH.string());
- confParam.loadCertToValidator(rootId.getDefaultKey().getDefaultCertificate());
- confParam.loadCertToValidator(siteIdentity.getDefaultKey().getDefaultCertificate());
- confParam.loadCertToValidator(opIdentity.getDefaultKey().getDefaultCertificate());
- confParam.loadCertToValidator(routerId.getDefaultKey().getDefaultCertificate());
+ for (const auto& id : {rootId, siteIdentity, opIdentity, routerId}) {
+ const auto& cert = id.getDefaultKey().getDefaultCertificate();
+ confParam.loadCertToValidator(cert);
+ }
// Loading the security section's validator part into the validator
// See conf file processor for more details
- std::ifstream inputFile;
- inputFile.open(std::string("nlsr.conf"));
-
- BOOST_REQUIRE(inputFile.is_open());
-
boost::property_tree::ptree pt;
-
- boost::property_tree::read_info(inputFile, pt);
+ boost::property_tree::read_info("nlsr.conf", pt);
// Loads section and file name
for (const auto& tn : pt) {
@@ -89,10 +83,8 @@
break;
}
}
- inputFile.close();
- this->advanceClocks(ndn::time::milliseconds(10));
-
+ this->advanceClocks(10_ms);
face.sentInterests.clear();
}
@@ -126,7 +118,7 @@
lsaDataName.appendNumber(1).appendNumber(1);
ndn::Data data(lsaDataName);
- data.setFreshnessPeriod(ndn::time::seconds(10));
+ data.setFreshnessPeriod(10_s);
// Sign data with NLSR's key
m_keyChain.sign(data, confParam.getSigningInfo());
@@ -134,8 +126,8 @@
// Make NLSR validate data signed by its own key
confParam.getValidator().validate(data,
[] (const Data&) { BOOST_CHECK(true); },
- [] (const Data&, const ndn::security::ValidationError&) {
- BOOST_CHECK(false);
+ [] (const Data&, const ndn::security::ValidationError& e) {
+ BOOST_ERROR(e);
});
}