merge ca config and client config, remove old format of probe
Change-Id: I73500f532f166851d82c1bf1cc008c7ffc241ef3
diff --git a/src/ca-config.cpp b/src/ca-config.cpp
deleted file mode 100644
index a7b3f9a..0000000
--- a/src/ca-config.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2020, Regents of the University of California.
- *
- * This file is part of ndncert, a certificate management system based on NDN.
- *
- * ndncert is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndncert authors and contributors.
- */
-
-#include "ca-config.hpp"
-#include "challenge-module.hpp"
-#include <ndn-cxx/util/io.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/property_tree/json_parser.hpp>
-#include <boost/property_tree/ptree.hpp>
-
-namespace ndn {
-namespace ndncert {
-
-void
-CaConfig::load(const std::string& fileName)
-{
- JsonSection configJson;
- try {
- boost::property_tree::read_json(fileName, configJson);
- }
- catch (const std::exception& error) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse configuration file " + fileName + ", " + error.what()));
- }
- if (configJson.begin() == configJson.end()) {
- BOOST_THROW_EXCEPTION(std::runtime_error("std::runtime_error processing configuration file: " + fileName + " no data"));
- }
- parse(configJson);
-}
-
-void
-CaConfig::parse(const JsonSection& configJson)
-{
- // CA prefix
- m_caPrefix = Name(configJson.get(CONFIG_CA_PREFIX, ""));
- if (m_caPrefix.empty()) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Cannot parse ca-prefix from the config file"));
- }
- // CA info
- m_caInfo = configJson.get(CONFIG_CA_INFO, "");
- // CA max validity period
- m_maxValidityPeriod = time::seconds(configJson.get(CONFIG_MAX_VALIDITY_PERIOD, 3600));
- // CA max suffix length
- m_maxSuffixLength = configJson.get<size_t>(CONFIG_MAX_SUFFIX_LENGTH, 1);
- if (m_maxSuffixLength == 0) {
- m_maxSuffixLength = 1;
- }
- // probe
- m_probeParameterKeys.clear();
- auto probeParameters = configJson.get_child_optional(CONFIG_PROBE_PARAMETERS);
- if (probeParameters) {
- parseProbeParameters(*probeParameters);
- }
- // optional supported challenges
- m_supportedChallenges.clear();
- auto challengeList = configJson.get_child_optional(CONFIG_SUPPORTED_CHALLENGES);
- if (!challengeList) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Cannot parse challenge list"));
- }
- parseChallengeList(*challengeList);
-}
-
-void
-CaConfig::parseProbeParameters(const JsonSection& section)
-{
- for (const auto item : section) {
- auto probeParameter = item.second.get(CONFIG_PROBE_PARAMETER, "");
- probeParameter = boost::algorithm::to_lower_copy(probeParameter);
- if (probeParameter == "") {
- BOOST_THROW_EXCEPTION(std::runtime_error("Cannot read probe-parameter-key in probe-parameters from the config file"));
- }
- m_probeParameterKeys.push_back(probeParameter);
- }
-}
-
-void
-CaConfig::parseChallengeList(const JsonSection& section)
-{
- for (const auto item : section) {
- auto challengeType = item.second.get(CONFIG_CHALLENGE, "");
- challengeType = boost::algorithm::to_lower_copy(challengeType);
- if (challengeType == "") {
- BOOST_THROW_EXCEPTION(std::runtime_error("Cannot read type in supported-challenges from the config file"));
- }
- if (!ChallengeModule::isChallengeSupported(challengeType)) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Does not support challenge read from the config file"));
- }
- m_supportedChallenges.push_back(challengeType);
- }
- if (m_supportedChallenges.size() == 0) {
- BOOST_THROW_EXCEPTION(std::runtime_error("At least one challenge should be identified under supported-challenges"));
- }
-}
-
-} // namespace ndncert
-} // namespace ndn
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 00d2208..d829f63 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -75,7 +75,7 @@
_LOG_TRACE("Prefix " << localhopInfoPrefix << " got registered");
// register prefixes
- Name prefix = m_config.m_caPrefix;
+ Name prefix = m_config.m_caItem.m_caPrefix;
prefix.append("CA");
prefixId = m_face.registerPrefix(
@@ -137,7 +137,7 @@
Name discoveryInterestName(infoPacket->getName().getPrefix(-2));
name::Component metadataComponent(32, reinterpret_cast<const uint8_t*>("metadata"), std::strlen("metadata"));
discoveryInterestName.append(metadataComponent);
- auto metadataData = metadata.makeData(discoveryInterestName, m_keyChain, signingByIdentity(m_config.m_caPrefix));
+ auto metadataData = metadata.makeData(discoveryInterestName, m_keyChain, signingByIdentity(m_config.m_caItem.m_caPrefix));
return make_shared<Data>(metadataData);
}
@@ -150,16 +150,16 @@
// otherwise, directly reply m_infoData
const auto& pib = m_keyChain.getPib();
- const auto& identity = pib.getIdentity(m_config.m_caPrefix);
+ const auto& identity = pib.getIdentity(m_config.m_caItem.m_caPrefix);
const auto& cert = identity.getDefaultKey().getDefaultCertificate();
- Block contentTLV = INFO::encodeDataContent(m_config, cert);
+ Block contentTLV = INFO::encodeDataContent(m_config.m_caItem, cert);
- Name infoPacketName(m_config.m_caPrefix);
+ Name infoPacketName(m_config.m_caItem.m_caPrefix);
infoPacketName.append("CA").append("INFO").appendVersion().appendSegment(0);
Data infoData(infoPacketName);
infoData.setContent(contentTLV);
infoData.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- m_keyChain.sign(infoData, signingByIdentity(m_config.m_caPrefix));
+ m_keyChain.sign(infoData, signingByIdentity(m_config.m_caItem.m_caPrefix));
return make_shared<Data>(infoData);
}
@@ -193,9 +193,9 @@
return;
}
- // if (m_config.m_nameAssignmentFunc) {
+ // if (m_config.m_caItem.m_nameAssignmentFunc) {
// try {
- // availableId = m_config.m_nameAssignmentFunc(parameterTLV);
+ // availableId = m_config.m_caItem.m_nameAssignmentFunc(parameterTLV);
// }
// catch (const std::exception& e) {
// _LOG_TRACE("Cannot find PROBE input from PROBE parameters: " << e.what());
@@ -206,17 +206,17 @@
// // if there is no app-specified name lookup, use a random name id
// availableId = std::to_string(random::generateSecureWord64());
// }
- // Name newIdentityName = m_config.m_caPrefix;
+ // Name newIdentityName = m_config.m_caItem.m_caPrefix;
// newIdentityName.append(availableId);
// _LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
- // Block contentTLV = PROBE::encodeDataContent(newIdentityName.toUri(), m_config.m_probe, parameterTLV);
+ // Block contentTLV = PROBE::encodeDataContent(newIdentityName.toUri(), m_config.m_caItem.m_probe, parameterTLV);
// Data result;
// result.setName(request.getName());
// result.setContent(contentTLV);
// result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- // m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
+ // m_keyChain.sign(result, signingByIdentity(m_config.m_caItem.m_caPrefix));
// m_face.put(result);
// _LOG_TRACE("Handle PROBE: send out the PROBE response");
}
@@ -284,23 +284,31 @@
auto expectedPeriod = clientCert->getValidityPeriod().getPeriod();
auto currentTime = time::system_clock::now();
if (expectedPeriod.first < currentTime - REQUEST_VALIDITY_PERIOD_NOT_BEFORE_GRACE_PERIOD ||
- expectedPeriod.second > currentTime + m_config.m_maxValidityPeriod ||
+ expectedPeriod.second > currentTime + m_config.m_caItem.m_maxValidityPeriod ||
expectedPeriod.second <= expectedPeriod.first) {
_LOG_ERROR("An invalid validity period is being requested.");
m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::BAD_VALIDITY_PERIOD,
"An invalid validity period is being requested."));
return;
}
- // verify the self-signed certificate, the request, and the token
- if (!m_config.m_caPrefix.isPrefixOf(clientCert->getIdentity())
+ // verify identity name
+ if (!m_config.m_caItem.m_caPrefix.isPrefixOf(clientCert->getIdentity())
|| !security::v2::Certificate::isValidName(clientCert->getName())
- || clientCert->getIdentity().size() <= m_config.m_caPrefix.size()
- || clientCert->getIdentity().size() > m_config.m_caPrefix.size() + m_config.m_maxSuffixLength) {
+ || clientCert->getIdentity().size() <= m_config.m_caItem.m_caPrefix.size()) {
_LOG_ERROR("An invalid certificate name is being requested " << clientCert->getName());
m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::NAME_NOT_ALLOWED,
"An invalid certificate name is being requested."));
return;
}
+ if (m_config.m_caItem.m_maxSuffixLength) {
+ if (clientCert->getIdentity().size() > m_config.m_caItem.m_caPrefix.size() + *m_config.m_caItem.m_maxSuffixLength) {
+ _LOG_ERROR("An invalid certificate name is being requested " << clientCert->getName());
+ m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::NAME_NOT_ALLOWED,
+ "An invalid certificate name is being requested."));
+ return;
+ }
+ }
+ // verify signature
if (!security::verifySignature(*clientCert, *clientCert)) {
_LOG_ERROR("Invalid signature in the self-signed certificate.");
m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::BAD_SIGNATURE,
@@ -315,17 +323,24 @@
}
}
else if (requestType == RequestType::REVOKE) {
- // verify the certificate
- if (!m_config.m_caPrefix.isPrefixOf(clientCert->getIdentity())
+ // verify identity name
+ if (!m_config.m_caItem.m_caPrefix.isPrefixOf(clientCert->getIdentity())
|| !security::v2::Certificate::isValidName(clientCert->getName())
- || clientCert->getIdentity().size() <= m_config.m_caPrefix.size()
- || clientCert->getIdentity().size() > m_config.m_caPrefix.size() + m_config.m_maxSuffixLength) {
+ || clientCert->getIdentity().size() <= m_config.m_caItem.m_caPrefix.size()) {
_LOG_ERROR("An invalid certificate name is being requested " << clientCert->getName());
m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::NAME_NOT_ALLOWED,
"An invalid certificate name is being requested."));
return;
}
- const auto& cert = m_keyChain.getPib().getIdentity(m_config.m_caPrefix).getDefaultKey().getDefaultCertificate();
+ if (m_config.m_caItem.m_maxSuffixLength) {
+ if (clientCert->getIdentity().size() > m_config.m_caItem.m_caPrefix.size() + *m_config.m_caItem.m_maxSuffixLength) {
+ _LOG_ERROR("An invalid certificate name is being requested " << clientCert->getName());
+ m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::NAME_NOT_ALLOWED,
+ "An invalid certificate name is being requested."));
+ return;
+ }
+ }
+ const auto& cert = m_keyChain.getPib().getIdentity(m_config.m_caItem.m_caPrefix).getDefaultKey().getDefaultCertificate();
if (!security::verifySignature(*clientCert, cert)) {
_LOG_ERROR("Invalid signature in the certificate to revoke.");
m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::BAD_SIGNATURE,
@@ -336,7 +351,7 @@
// create new request instance
std::string requestId = std::to_string(random::generateWord64());
- RequestState requestState(m_config.m_caPrefix, requestId, requestType, Status::BEFORE_CHALLENGE, *clientCert,
+ RequestState requestState(m_config.m_caItem.m_caPrefix, requestId, requestType, Status::BEFORE_CHALLENGE, *clientCert,
makeBinaryBlock(tlv::ContentType_Key, aesKey, sizeof(aesKey)));
m_storage->addRequest(requestState);
Data result;
@@ -346,15 +361,15 @@
result.setContent(NEW::encodeDataContent(myEcdhPubKeyBase64,
std::to_string(saltInt),
requestState,
- m_config.m_supportedChallenges));
+ m_config.m_caItem.m_supportedChallenges));
}
else if (requestType == RequestType::REVOKE) {
result.setContent(REVOKE::encodeDataContent(myEcdhPubKeyBase64,
std::to_string(saltInt),
requestState,
- m_config.m_supportedChallenges));
+ m_config.m_caItem.m_supportedChallenges));
}
- m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
+ m_keyChain.sign(result, signingByIdentity(m_config.m_caItem.m_caPrefix));
m_face.put(result);
if (m_config.m_statusUpdateCallback) {
m_config.m_statusUpdateCallback(requestState);
@@ -456,7 +471,7 @@
auto contentBlock = encodeBlockWithAesGcm128(tlv::Content, requestState.m_encryptionKey.value(), payload.value(),
payload.value_size(), (uint8_t*)"test", strlen("test"));
result.setContent(contentBlock);
- m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
+ m_keyChain.sign(result, signingByIdentity(m_config.m_caItem.m_caPrefix));
m_face.put(result);
if (m_config.m_statusUpdateCallback) {
m_config.m_statusUpdateCallback(requestState);
@@ -479,7 +494,7 @@
SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(period);
security::SigningInfo signingInfo(security::SigningInfo::SIGNER_TYPE_ID,
- m_config.m_caPrefix, signatureInfo);
+ m_config.m_caItem.m_caPrefix, signatureInfo);
m_keyChain.sign(newCert, signingInfo);
_LOG_TRACE("new cert got signed" << newCert);
@@ -492,7 +507,7 @@
std::string requestId;
RequestState requestState;
try {
- requestId = readString(request.getName().at(m_config.m_caPrefix.size() + 2));
+ requestId = readString(request.getName().at(m_config.m_caItem.m_caPrefix.size() + 2));
}
catch (const std::exception& e) {
_LOG_ERROR("Cannot read the request ID out from the request: " << e.what());
@@ -545,7 +560,7 @@
result.setName(name);
result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
result.setContent(ErrorTLV::encodeDataContent(error, errorInfo));
- m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
+ m_keyChain.sign(result, signingByIdentity(m_config.m_caItem.m_caPrefix));
return result;
}
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index c97e4f3..acc2a50 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -21,7 +21,7 @@
#ifndef NDNCERT_CA_MODULE_HPP
#define NDNCERT_CA_MODULE_HPP
-#include "ca-config.hpp"
+#include "configuration.hpp"
#include "crypto-support/crypto-helper.hpp"
#include "ca-storage.hpp"
diff --git a/src/client-config.cpp b/src/client-config.cpp
deleted file mode 100644
index 2396cab..0000000
--- a/src/client-config.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2019, Regents of the University of California.
- *
- * This file is part of ndncert, a certificate management system based on NDN.
- *
- * ndncert is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndncert authors and contributors.
- */
-
-#include "client-config.hpp"
-
-#include <ndn-cxx/util/io.hpp>
-#include <fstream>
-
-namespace ndn {
-namespace ndncert {
-
-void
-ClientConfig::load(const std::string& fileName)
-{
- JsonSection config;
- try {
- boost::property_tree::read_json(fileName, config);
- }
- catch (const std::exception& error) {
- BOOST_THROW_EXCEPTION(Error("Failed to parse configuration file " + fileName + ", " + error.what()));
- }
-
- if (config.begin() == config.end()) {
- BOOST_THROW_EXCEPTION(Error("Error processing configuration file: " + fileName + ", no data"));
- }
-
- load(config);
-}
-
-void
-ClientConfig::load(const JsonSection& configSection)
-{
- m_caItems.clear();
- auto caList = configSection.get_child("ca-list");
- auto it = caList.begin();
- for (; it != caList.end(); it++) {
- m_caItems.push_back(extractCaItem(it->second));
- }
- m_localNdncertAnchor = configSection.get("local-ndncert-anchor", "");
-}
-
-void
-ClientConfig::save(const std::string& fileName)
-{
- JsonSection configJson;
- JsonSection caList;
- std::stringstream ss;
- for (const auto& item : m_caItems) {
- JsonSection caItem;
- caItem.put("ca-prefix", item.m_caPrefix.toUri());
- caItem.put("ca-info", item.m_caInfo);
- caItem.put("probe", item.m_probe);
- ss.str(std::string());
- io::save(item.m_anchor, ss);
- caItem.put("certificate", ss.str());
- caList.push_back(std::make_pair("", caItem));
- }
- configJson.add_child("ca-list", caList);
- ss.str(std::string());
- boost::property_tree::write_json(ss, configJson);
-
- std::ofstream configFile;
- configFile.open(fileName, std::ios::trunc);
- configFile << ss.str();
- configFile.close();
-}
-
-ClientCaItem
-ClientConfig::extractCaItem(const JsonSection& configSection)
-{
- ClientCaItem item;
- item.m_caPrefix = Name(configSection.get("ca-prefix", ""));
- if (item.m_caPrefix.empty()) {
- BOOST_THROW_EXCEPTION(Error("Cannot read ca-prefix from the config file"));
- }
- item.m_caInfo = configSection.get("ca-info", "");
- item.m_probe = configSection.get("probe", "");
- std::istringstream ss(configSection.get("certificate", ""));
- item.m_maxSuffixLength = configSection.get<size_t>(CONFIG_MAX_SUFFIX_LENGTH, 1);
- auto anchor = io::load<security::v2::Certificate>(ss);
- if (anchor == nullptr) {
- BOOST_THROW_EXCEPTION(Error("Cannot load the certificate from config file"));
- }
- item.m_anchor = *anchor;
- return item;
-}
-
-void
-ClientConfig::removeCaItem(const Name& caName)
-{
- m_caItems.remove_if([&](const ClientCaItem& item) { return item.m_caPrefix == caName; });
-}
-
-} // namespace ndncert
-} // namespace ndn
diff --git a/src/client-config.hpp b/src/client-config.hpp
deleted file mode 100644
index 0665808..0000000
--- a/src/client-config.hpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2020, Regents of the University of California.
- *
- * This file is part of ndncert, a certificate management system based on NDN.
- *
- * ndncert is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndncert authors and contributors.
- */
-
-#ifndef NDNCERT_CLIENT_CONFIG_HPP
-#define NDNCERT_CLIENT_CONFIG_HPP
-
-#include "request-state.hpp"
-#include <ndn-cxx/security/v2/certificate.hpp>
-
-namespace ndn {
-namespace ndncert {
-
-/**
- * @brief The configuration for a trusted CA from a requester's perspective
- */
-class ClientCaItem {
-public:
- /**
- * CA Name prefix (without /CA suffix).
- */
- Name m_caPrefix;
- /**
- * CA Information.
- */
- std::string m_caInfo;
- /**
- * A list of parameter-keys for PROBE.
- */
- std::list<std::string> m_probeParameterKeys;
- /**
- * Maximum allowed validity period of the certificate being requested.
- * The value is in the unit of second.
- */
- time::seconds m_maxValidityPeriod;
- /**
- * CA's certificate.
- */
- security::v2::Certificate m_anchor;
- /**
- * Maximum allowed suffix length of requested name.
- * E.g., When its value is 2, at most 2 name components can be assigned after m_caPrefix.
- */
- size_t m_maxSuffixLength;
-
- //=======old
-
- // The identity name of the CA. Extracted from config field "ca-prefix"
- Name m_caName;
-
- // An instruction for requesters to use _PROBE. Extracted from config field "probe"
- std::string m_probe; // "email::uid::name"
-};
-
-/**
- * @brief Represents Client configuration
- *
- * For Client configuration format, please refer to:
- * https://github.com/named-data/ndncert/wiki/Client-Configuration-Sample
- */
-class ClientConfig {
-public:
- class Error : public std::runtime_error {
- public:
- using std::runtime_error::runtime_error;
- };
-
-public:
- /**
- * @throw ClientConfig::Error when config file does not exist
- * @throw ClientConfig::Error when the JSON text in the file cannot be parsed correctly
- * @throw ClientConfig::Error when the ca-prefix attribute in JSON text is empty
- * @throw ClientConfig::Error when the certificate in JSON text cannot be parsed correctly
- */
- void
- load(const std::string& fileName);
-
- void
- load(const JsonSection& configSection);
-
- void
- save(const std::string& fileName);
-
- void
- addNewCaItem(const ClientCaItem& item);
-
- void
- removeCaItem(const Name& caName);
-
- static ClientCaItem
- extractCaItem(const JsonSection& configSection);
-
-public:
- std::list<ClientCaItem> m_caItems;
- std::string m_localNdncertAnchor;
-};
-
-} // namespace ndncert
-} // namespace ndn
-
-#endif // NDNCERT_CLIENT_CONFIG_HPP
diff --git a/src/client-module.cpp b/src/client-module.cpp
index 0fbd07b..0e7810e 100644
--- a/src/client-module.cpp
+++ b/src/client-module.cpp
@@ -68,10 +68,10 @@
ClientModule::verifyInfoResponse(const Data& reply)
{
// parse the ca item
- auto caItem = INFO::decodeClientConfigFromContent(reply.getContent());
+ auto caItem = INFO::decodeDataContentToCaProfile(reply.getContent());
// verify the probe Data's sig
- if (!security::verifySignature(reply, caItem.m_anchor)) {
+ if (!security::verifySignature(reply, *caItem.m_cert)) {
_LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
return false;
}
@@ -84,7 +84,7 @@
const Block& contentBlock = reply.getContent();
// parse the ca item
- auto caItem = INFO::decodeClientConfigFromContent(contentBlock);
+ auto caItem = INFO::decodeDataContentToCaProfile(contentBlock);
// update the local config
bool findItem = false;
@@ -100,15 +100,15 @@
}
shared_ptr<Interest>
-ClientModule::generateProbeInterest(const ClientCaItem& ca, const std::string& probeInfo)
+ClientModule::generateProbeInterest(const CaConfigItem& ca,
+ std::vector<std::tuple<std::string, std::string>>&& probeInfo)
{
Name interestName = ca.m_caPrefix;
interestName.append("CA").append("PROBE");
auto interest = make_shared<Interest>(interestName);
interest->setMustBeFresh(true);
interest->setCanBePrefix(false);
- interest->setApplicationParameters(
- PROBE::encodeApplicationParametersFromProbeInfo(ca, probeInfo));
+ interest->setApplicationParameters(PROBE::encodeApplicationParameters(std::move(probeInfo)));
// update local state
m_ca = ca;
@@ -118,7 +118,7 @@
void
ClientModule::onProbeResponse(const Data& reply)
{
- if (!security::verifySignature(reply, m_ca.m_anchor)) {
+ if (!security::verifySignature(reply, *m_ca.m_cert)) {
_LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
return;
}
@@ -213,7 +213,7 @@
std::list<std::string>
ClientModule::onNewRenewRevokeResponse(const Data& reply)
{
- if (!security::verifySignature(reply, m_ca.m_anchor)) {
+ if (!security::verifySignature(reply, *m_ca.m_cert)) {
_LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
return std::list<std::string>();
}
@@ -248,7 +248,7 @@
// Name requestedName = identityName;
bool findCa = false;
for (const auto& caItem : m_config.m_caItems) {
- if (caItem.m_caName.isPrefixOf(certificate.getName())) {
+ if (caItem.m_caPrefix.isPrefixOf(certificate.getName())) {
m_ca = caItem;
findCa = true;
}
@@ -296,7 +296,7 @@
void
ClientModule::onChallengeResponse(const Data& reply)
{
- if (!security::verifySignature(reply, m_ca.m_anchor)) {
+ if (!security::verifySignature(reply, *m_ca.m_cert)) {
_LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
return;
}
@@ -373,20 +373,5 @@
m_status = Status::ENDED;
}
-std::vector<std::string>
-ClientModule::parseProbeComponents(const std::string& probe)
-{
- std::vector<std::string> components;
- std::string delimiter = ":";
- size_t last = 0;
- size_t next = 0;
- while ((next = probe.find(delimiter, last)) != std::string::npos) {
- components.push_back(probe.substr(last, next - last));
- last = next + 1;
- }
- components.push_back(probe.substr(last));
- return components;
-}
-
} // namespace ndncert
} // namespace ndn
diff --git a/src/client-module.hpp b/src/client-module.hpp
index c439d3c..fd88129 100644
--- a/src/client-module.hpp
+++ b/src/client-module.hpp
@@ -21,7 +21,7 @@
#ifndef NDNCERT_CLIENT_MODULE_HPP
#define NDNCERT_CLIENT_MODULE_HPP
-#include "client-config.hpp"
+#include "configuration.hpp"
#include "request-state.hpp"
#include "crypto-support/crypto-helper.hpp"
@@ -30,7 +30,7 @@
// TODO
// For each CA item in Client.Conf, create a validator instance and initialize it with CA's cert
-// The validator instance should be in ClientCaItem
+// The validator instance should be in CaConfigItem
class ClientModule : noncopyable
{
@@ -83,7 +83,7 @@
addCaFromInfoResponse(const Data& reply);
shared_ptr<Interest>
- generateProbeInterest(const ClientCaItem& ca, const std::string& probeInfo);
+ generateProbeInterest(const CaConfigItem& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);
void
onProbeResponse(const Data& reply);
@@ -114,9 +114,6 @@
void
onCertFetchResponse(const Data& reply);
- static std::vector<std::string>
- parseProbeComponents(const std::string& probe);
-
void
endSession();
@@ -124,7 +121,7 @@
ClientConfig m_config;
security::v2::KeyChain& m_keyChain;
- ClientCaItem m_ca;
+ CaConfigItem m_ca;
security::Key m_key;
Name m_identityName;
@@ -132,7 +129,6 @@
Status m_status = Status::NOT_STARTED;
std::string m_challengeStatus = "";
std::string m_challengeType = "";
- std::string m_certId = "";
Name m_issuedCertName;
std::list<std::string> m_challengeList;
bool m_isCertInstalled = false;
diff --git a/src/configuration.cpp b/src/configuration.cpp
new file mode 100644
index 0000000..c4f2c72
--- /dev/null
+++ b/src/configuration.cpp
@@ -0,0 +1,198 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2020, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#include "configuration.hpp"
+#include "challenge-module.hpp"
+#include <ndn-cxx/util/io.hpp>
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+void
+CaConfigItem::parse(const JsonSection& configJson)
+{
+ // CA prefix
+ m_caPrefix = Name(configJson.get(CONFIG_CA_PREFIX, ""));
+ if (m_caPrefix.empty()) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Cannot parse ca-prefix from the config file"));
+ }
+ // CA info
+ m_caInfo = configJson.get(CONFIG_CA_INFO, "");
+ // CA max validity period
+ m_maxValidityPeriod = time::seconds(configJson.get(CONFIG_MAX_VALIDITY_PERIOD, 86400));
+ // CA max suffix length
+ m_maxSuffixLength = configJson.get_optional<size_t>(CONFIG_MAX_SUFFIX_LENGTH);
+ // probe parameter keys
+ m_probeParameterKeys.clear();
+ auto probeParametersJson = configJson.get_child_optional(CONFIG_PROBE_PARAMETERS);
+ if (probeParametersJson) {
+ for (const auto item : *probeParametersJson) {
+ auto probeParameter = item.second.get(CONFIG_PROBE_PARAMETER, "");
+ probeParameter = boost::algorithm::to_lower_copy(probeParameter);
+ if (probeParameter == "") {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Probe parameter key cannot be empty."));
+ }
+ m_probeParameterKeys.push_back(probeParameter);
+ }
+ }
+ // supported challenges
+ m_supportedChallenges.clear();
+ auto challengeListJson = configJson.get_child_optional(CONFIG_SUPPORTED_CHALLENGES);
+ if (challengeListJson) {
+ for (const auto item : *challengeListJson) {
+ auto challengeType = item.second.get(CONFIG_CHALLENGE, "");
+ challengeType = boost::algorithm::to_lower_copy(challengeType);
+ if (challengeType == "") {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Challenge type canont be empty."));
+ }
+ if (!ChallengeModule::isChallengeSupported(challengeType)) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Challenge " + challengeType + " is not supported."));
+ }
+ m_supportedChallenges.push_back(challengeType);
+ }
+ }
+ // anchor certificate
+ m_cert = nullptr;
+ auto certificateStr = configJson.get("certificate", "");
+ if (certificateStr != "") {
+ std::istringstream ss(certificateStr);
+ m_cert = io::load<security::v2::Certificate>(ss);
+ }
+}
+
+JsonSection
+CaConfigItem::toJson() const
+{
+ JsonSection caItem;
+ caItem.put(CONFIG_CA_PREFIX, m_caPrefix.toUri());
+ caItem.put(CONFIG_CA_INFO, m_caInfo);
+ caItem.put(CONFIG_MAX_VALIDITY_PERIOD, m_maxValidityPeriod.count());
+ caItem.put(CONFIG_MAX_SUFFIX_LENGTH, m_maxSuffixLength);
+ if (!m_probeParameterKeys.empty()) {
+ JsonSection probeParametersJson;
+ for (const auto& key : m_probeParameterKeys) {
+ JsonSection keyJson;
+ keyJson.put(CONFIG_PROBE_PARAMETER, key);
+ probeParametersJson.push_back(std::make_pair("", keyJson));
+ }
+ caItem.add_child("", probeParametersJson);
+ }
+ if (!m_supportedChallenges.empty()) {
+ JsonSection challengeListJson;
+ for (const auto& challenge : m_supportedChallenges) {
+ JsonSection challengeJson;
+ challengeJson.put(CONFIG_CHALLENGE, challenge);
+ challengeListJson.push_back(std::make_pair("", challengeJson));
+ }
+ caItem.add_child("", challengeListJson);
+ }
+ if (m_cert != nullptr) {
+ std::stringstream ss;
+ io::save(*m_cert, ss);
+ caItem.put("certificate", ss.str());
+ }
+ return caItem;
+}
+
+void
+CaConfig::load(const std::string& fileName)
+{
+ JsonSection configJson;
+ try {
+ boost::property_tree::read_json(fileName, configJson);
+ }
+ catch (const std::exception& error) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse configuration file " + fileName + ", " + error.what()));
+ }
+ if (configJson.begin() == configJson.end()) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("No JSON configuration found in file: " + fileName));
+ }
+ m_caItem.parse(configJson);
+ if (m_caItem.m_supportedChallenges.size() == 0) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("At least one challenge should be specified."));
+ }
+}
+
+void
+CaConfig::save(const std::string& fileName) const
+{
+ std::stringstream ss;
+ boost::property_tree::write_json(ss, m_caItem.toJson());
+ std::ofstream configFile;
+ configFile.open(fileName);
+ configFile << ss.str();
+ configFile.close();
+}
+
+void
+ClientConfig::load(const std::string& fileName)
+{
+ JsonSection configJson;
+ try {
+ boost::property_tree::read_json(fileName, configJson);
+ }
+ catch (const std::exception& error) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse configuration file " + fileName + ", " + error.what()));
+ }
+ if (configJson.begin() == configJson.end()) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("No JSON configuration found in file: " + fileName));
+ }
+ load(configJson);
+}
+
+void
+ClientConfig::load(const JsonSection& configSection)
+{
+ m_caItems.clear();
+ auto caList = configSection.get_child("ca-list");
+ for (auto item : caList) {
+ CaConfigItem caItem;
+ caItem.parse(item.second);
+ if (caItem.m_cert == nullptr) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("No CA certificate is loaded from JSON configuration."));
+ }
+ m_caItems.push_back(std::move(caItem));
+ }
+}
+
+void
+ClientConfig::save(const std::string& fileName) const
+{
+ JsonSection configJson;
+ for (const auto& caItem : m_caItems) {
+ configJson.push_back(std::make_pair("", caItem.toJson()));
+ }
+ std::stringstream ss;
+ boost::property_tree::write_json(ss, configJson);
+ std::ofstream configFile;
+ configFile.open(fileName);
+ configFile << ss.str();
+ configFile.close();
+}
+
+void
+ClientConfig::removeCaItem(const Name& caName)
+{
+ m_caItems.remove_if([&](const CaConfigItem& item) { return item.m_caPrefix == caName; });
+}
+
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/ca-config.hpp b/src/configuration.hpp
similarity index 75%
rename from src/ca-config.hpp
rename to src/configuration.hpp
index bba5af4..7f4f8a4 100644
--- a/src/ca-config.hpp
+++ b/src/configuration.hpp
@@ -22,11 +22,62 @@
#define NDNCERT_CA_CONFIG_HPP
#include "request-state.hpp"
-#include "client-config.hpp"
namespace ndn {
namespace ndncert {
+struct CaConfigItem {
+ /**
+ * CA Name prefix (without /CA suffix).
+ */
+ Name m_caPrefix;
+ /**
+ * CA Information.
+ * Default: "".
+ */
+ std::string m_caInfo;
+ /**
+ * A list of parameter-keys for PROBE.
+ * Default: empty list.
+ */
+ std::list<std::string> m_probeParameterKeys;
+ /**
+ * Maximum allowed validity period of the certificate being requested.
+ * The value is in the unit of second.
+ * Default: one day (86400 seconds).
+ */
+ time::seconds m_maxValidityPeriod;
+ /**
+ * Maximum allowed suffix length of requested name.
+ * E.g., When its value is 2, at most 2 name components can be assigned after m_caPrefix.
+ * Default: none.
+ */
+ boost::optional<size_t> m_maxSuffixLength;
+ /**
+ * A list of supported challenges. Only CA side will have m_supportedChallenges.
+ * Default: empty list.
+ */
+ std::list<std::string> m_supportedChallenges;
+ /**
+ * CA's certificate. Only Client side will have m_cert.
+ * Default: nullptr.
+ */
+ std::shared_ptr<security::v2::Certificate> m_cert;
+
+ void
+ parse(const JsonSection& configJson);
+
+ JsonSection
+ toJson() const;
+
+private:
+ void
+ parseProbeParameters(const JsonSection& section);
+
+ void
+ parseChallengeList(const JsonSection& configSection);
+};
+
/**
* @brief The name assignment function provided by the CA operator to generate available
* namecomponents.
@@ -75,53 +126,15 @@
public:
/**
* Load CA configuration from the file.
- *
- * @param fileName, the configuration file name.
- * @throw std::runtime_error when config file does not exist or the configuration
- * in the file cannot be parsed correctly.
- * @throw std::runtime_error when the ca-prefix attribute in JSON text is empty.
- * @throw std::runtime_error when the challenge is not specified or is not supported.
+ * @throw std::runtime_error when config file cannot be correctly parsed.
*/
void
load(const std::string& fileName);
-private:
void
- parse(const JsonSection& configJson);
+ save(const std::string& fileName) const;
- void
- parseProbeParameters(const JsonSection& section);
-
- void
- parseChallengeList(const JsonSection& configSection);
-
-public:
- /**
- * CA Name prefix (without /CA suffix).
- */
- Name m_caPrefix;
- /**
- * CA Information.
- */
- std::string m_caInfo;
- /**
- * A list of parameter-keys for PROBE.
- */
- std::list<std::string> m_probeParameterKeys;
- /**
- * Maximum allowed validity period of the certificate being requested.
- * The value is in the unit of second.
- */
- time::seconds m_maxValidityPeriod;
- /**
- * Maximum allowed suffix length of requested name.
- * E.g., When its value is 2, at most 2 name components can be assigned after m_caPrefix.
- */
- size_t m_maxSuffixLength;
- /**
- * A list of supported challenges.
- */
- std::list<std::string> m_supportedChallenges;
+ CaConfigItem m_caItem;
/**
* NameAssignmentFunc Callback function
*/
@@ -132,6 +145,35 @@
StatusUpdateCallback m_statusUpdateCallback;
};
+/**
+ * @brief Represents Client configuration
+ *
+ * For Client configuration format, please refer to:
+ * https://github.com/named-data/ndncert/wiki/Client-Configuration-Sample
+ */
+class ClientConfig {
+public:
+ /**
+ * @throw std::runtime_error when config file cannot be correctly parsed.
+ */
+ void
+ load(const std::string& fileName);
+
+ /**
+ * @throw std::runtime_error when config file cannot be correctly parsed.
+ */
+ void
+ load(const JsonSection& configSection);
+
+ void
+ save(const std::string& fileName) const;
+
+ void
+ removeCaItem(const Name& caName);
+
+ std::list<CaConfigItem> m_caItems;
+};
+
} // namespace ndncert
} // namespace ndn
diff --git a/src/protocol-detail/error.hpp b/src/protocol-detail/error.hpp
index 1234233..8a2cda0 100644
--- a/src/protocol-detail/error.hpp
+++ b/src/protocol-detail/error.hpp
@@ -21,8 +21,7 @@
#ifndef NDNCERT_PROTOCOL_DETAIL_ERROR_HPP
#define NDNCERT_PROTOCOL_DETAIL_ERROR_HPP
-#include "../ca-config.hpp"
-#include "../client-config.hpp"
+#include "../configuration.hpp"
namespace ndn {
namespace ndncert {
diff --git a/src/protocol-detail/info.cpp b/src/protocol-detail/info.cpp
index 59cc48e..306d060 100644
--- a/src/protocol-detail/info.cpp
+++ b/src/protocol-detail/info.cpp
@@ -24,14 +24,15 @@
namespace ndncert {
Block
-INFO::encodeDataContent(const CaConfig& caConfig, const security::v2::Certificate& certificate)
+INFO::encodeDataContent(const CaConfigItem& caConfig, const security::v2::Certificate& certificate)
{
auto content = makeEmptyBlock(tlv::Content);
content.push_back(makeNestedBlock(tlv_ca_prefix, caConfig.m_caPrefix));
std::string caInfo = "";
if (caConfig.m_caInfo == "") {
caInfo = "Issued by " + certificate.getSignature().getKeyLocator().getName().toUri();
- } else {
+ }
+ else {
caInfo = caConfig.m_caInfo;
}
content.push_back(makeStringBlock(tlv_ca_info, caInfo));
@@ -41,38 +42,42 @@
}
content.push_back(makeNonNegativeIntegerBlock(tlv_max_validity_period, caConfig.m_maxValidityPeriod.count()));
content.push_back(makeNestedBlock(tlv_ca_certificate, certificate));
- content.push_back(makeNonNegativeIntegerBlock(tlv_max_suffix_length, caConfig.m_maxSuffixLength));
+ if (caConfig.m_maxSuffixLength) {
+ content.push_back(makeNonNegativeIntegerBlock(tlv_max_suffix_length, *caConfig.m_maxSuffixLength));
+ }
content.encode();
return content;
}
-ClientCaItem
-INFO::decodeClientConfigFromContent(const Block& block)
+CaConfigItem
+INFO::decodeDataContentToCaProfile(const Block& block)
{
- ClientCaItem result;
+ CaConfigItem result;
block.parse();
for (auto const& item : block.elements()) {
- if (item.type() == tlv_ca_prefix) {
- item.parse();
+ item.parse();
+ switch (item.type()) {
+ case tlv_ca_prefix:
result.m_caPrefix.wireDecode(item.get(tlv::Name));
- }
- else if (item.type() == tlv_ca_info) {
+ break;
+ case tlv_ca_info:
result.m_caInfo = readString(item);
- }
- else if (item.type() == tlv_parameter_key) {
+ break;
+ case tlv_parameter_key:
result.m_probeParameterKeys.push_back(readString(item));
- }
- else if (item.type() == tlv_max_validity_period) {
+ break;
+ case tlv_max_validity_period:
result.m_maxValidityPeriod = time::seconds(readNonNegativeInteger(item));
- }
- else if (item.type() == tlv_ca_certificate) {
- item.parse();
- result.m_anchor.wireDecode(item.get(tlv::Data));
- } else if (item.type() == tlv_max_suffix_length) {
+ break;
+ case tlv_max_suffix_length:
result.m_maxSuffixLength = readNonNegativeInteger(item);
- }
- else {
+ break;
+ case tlv_ca_certificate:
+ result.m_cert->wireDecode(item.get(tlv::Data));
+ break;
+ default:
continue;
+ break;
}
}
return result;
diff --git a/src/protocol-detail/info.hpp b/src/protocol-detail/info.hpp
index a21040e..1c375bb 100644
--- a/src/protocol-detail/info.hpp
+++ b/src/protocol-detail/info.hpp
@@ -21,8 +21,7 @@
#ifndef NDNCERT_PROTOCOL_DETAIL_INFO_HPP
#define NDNCERT_PROTOCOL_DETAIL_INFO_HPP
-#include "../ca-config.hpp"
-#include "../client-config.hpp"
+#include "../configuration.hpp"
namespace ndn {
namespace ndncert {
@@ -33,13 +32,13 @@
* Encode CA configuration and its certificate into a TLV block as INFO Data packet content.
*/
static Block
- encodeDataContent(const CaConfig& caConfig, const security::v2::Certificate& certificate);
+ encodeDataContent(const CaConfigItem& caConfig, const security::v2::Certificate& certificate);
/**
* Decode CA configuration from the TLV block of INFO Data packet content.
*/
- static ClientCaItem
- decodeClientConfigFromContent(const Block& block);
+ static CaConfigItem
+ decodeDataContentToCaProfile(const Block& block);
};
} // namespace ndncert
diff --git a/src/protocol-detail/probe.cpp b/src/protocol-detail/probe.cpp
index 34b769e..93ba020 100644
--- a/src/protocol-detail/probe.cpp
+++ b/src/protocol-detail/probe.cpp
@@ -26,39 +26,13 @@
namespace ndncert {
// For Client
-std::vector<std::string>
-PROBE::parseProbeComponents(const std::string& probe)
-{
- std::vector<std::string> components;
- std::string delimiter = ":";
- size_t last = 0;
- size_t next = 0;
- while ((next = probe.find(delimiter, last)) != std::string::npos) {
- components.push_back(probe.substr(last, next - last));
- last = next + 1;
- }
- components.push_back(probe.substr(last));
- return components;
-}
-
Block
-PROBE::encodeApplicationParametersFromProbeInfo(const ClientCaItem& ca, const std::string& probeInfo)
+PROBE::encodeApplicationParameters(std::vector<std::tuple<std::string, std::string>>&& parameters)
{
auto content = makeEmptyBlock(tlv::ApplicationParameters);
-
- std::vector<std::string> fields = parseProbeComponents(ca.m_probe);
- std::vector<std::string> arguments = parseProbeComponents(probeInfo);
- ;
-
- if (arguments.size() != fields.size()) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Error in genProbeRequestJson: argument list does not match field list in the config file."));
- }
-
- for (size_t i = 0; i < fields.size(); ++i) {
- content.push_back(
- makeStringBlock(tlv_parameter_key, fields.at(i)));
- content.push_back(
- makeStringBlock(tlv_parameter_value, arguments.at(i)));
+ for (size_t i = 0; i < parameters.size(); ++i) {
+ content.push_back(makeStringBlock(tlv_parameter_key, std::get<0>(parameters[i])));
+ content.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(parameters[i])));
}
content.encode();
return content;
@@ -66,29 +40,15 @@
// For CA
Block
-PROBE::encodeDataContent(const Name& identifier, const std::string& m_probe, const Block& parameterTLV)
+PROBE::encodeDataContent(const std::vector<Name>& identifiers, boost::optional<size_t> maxSuffixLength)
{
- std::vector<std::string> fields;
- std::string delimiter = ":";
- size_t last = 0;
- size_t next = 0;
- while ((next = m_probe.find(delimiter, last)) != std::string::npos) {
- fields.push_back(m_probe.substr(last, next - last));
- last = next + 1;
- }
- fields.push_back(m_probe.substr(last));
-
Block content = makeEmptyBlock(tlv::Content);
-
- // TODO: Currently have no mechanism to utilize the given params to determine name
- //for (size_t i = 0; i < fields.size(); ++i) {
- // root.put(fields.at(i), parameterJson.get(fields.at(i), ""));
- //}
-
- content.push_back(makeNestedBlock(tlv_probe_response, identifier));
-
- // TODO: Must be determined based on CA config
- content.push_back(makeEmptyBlock(tlv_allow_longer_name));
+ for (const auto& name : identifiers) {
+ content.push_back(makeNestedBlock(tlv_probe_response, name));
+ }
+ if (maxSuffixLength) {
+ content.push_back(makeNonNegativeIntegerBlock(tlv_max_suffix_length, *maxSuffixLength));
+ }
content.encode();
return content;
}
diff --git a/src/protocol-detail/probe.hpp b/src/protocol-detail/probe.hpp
index 41b73c8..126fba4 100644
--- a/src/protocol-detail/probe.hpp
+++ b/src/protocol-detail/probe.hpp
@@ -21,22 +21,18 @@
#ifndef NDNCERT_PROTOCOL_DETAIL_PROBE_HPP
#define NDNCERT_PROTOCOL_DETAIL_PROBE_HPP
-#include "../ca-config.hpp"
-#include "../client-config.hpp"
+#include "../configuration.hpp"
namespace ndn {
namespace ndncert {
class PROBE {
public:
- static std::vector<std::string>
- parseProbeComponents(const std::string& probe);
+ static Block
+ encodeApplicationParameters(std::vector<std::tuple<std::string, std::string>>&& parameters);
static Block
- encodeApplicationParametersFromProbeInfo(const ClientCaItem& ca, const std::string& probeInfo);
-
- static Block
- encodeDataContent(const Name& identifier, const std::string& m_probe, const Block& parameterTLV);
+ encodeDataContent(const std::vector<Name>& identifiers, boost::optional<size_t> maxSuffixLength);
};
} // namespace ndncert