merge ca config and client config, remove old format of probe
Change-Id: I73500f532f166851d82c1bf1cc008c7ffc241ef3
diff --git a/ca.conf.sample b/ca.conf.sample
index 977005a..cdc2aab 100644
--- a/ca.conf.sample
+++ b/ca.conf.sample
@@ -1,8 +1,8 @@
{
"ca-prefix": "/example",
- "issuing-freshness": "720",
- "validity-period": "360",
"ca-info": "An example NDNCERT CA",
+ "max-validity-period": "1296000",
+ "max-suffix-length": "2",
"probe-parameters":
[
{"probe-parameter-key": "email"},
diff --git a/client.conf.sample b/client.conf.sample
index e9fe68d..4753504 100644
--- a/client.conf.sample
+++ b/client.conf.sample
@@ -4,9 +4,25 @@
{
"ca-prefix": "/example",
"ca-info": "An example NDNCERT CA",
- "probe": "email",
+ "max-validity-period": "1296000",
+ "max-suffix-length": "2",
+ "probe-parameters":
+ [
+ {"probe-parameter-key": "email"},
+ {"probe-parameter-key": "uid"}
+ ],
"certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
- }
- ],
- "local-ndncert-anchor": "/usr/local/etc/ndncert/anchor.key"
+ },
+ {
+ "ca-prefix": "/example2",
+ "ca-info": "An example NDNCERT CA 2",
+ "max-validity-period": "1296000",
+ "max-suffix-length": "1",
+ "probe-parameters":
+ [
+ {"probe-parameter-key": "email"},
+ ],
+ "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
+ },
+ ]
}
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
diff --git a/tests/unit-tests/bench.t.cpp b/tests/unit-tests/bench.t.cpp
index 2721811..4caed86 100644
--- a/tests/unit-tests/bench.t.cpp
+++ b/tests/unit-tests/bench.t.cpp
@@ -37,7 +37,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
@@ -63,10 +63,10 @@
BOOST_CHECK(security::verifySignature(response, cert));
auto contentBlock = response.getContent();
contentBlock.parse();
- auto caItem = INFO::decodeClientConfigFromContent(contentBlock);
+ auto caItem = INFO::decodeDataContentToCaProfile(contentBlock);
BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
- BOOST_CHECK_EQUAL(caItem.m_probe, "");
- BOOST_CHECK_EQUAL(caItem.m_anchor.wireEncode(), cert.wireEncode());
+ BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 0);
+ BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
}
});
@@ -85,14 +85,14 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
// generate NEW Interest
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto newInterest = client.generateNewInterest(time::system_clock::now(),
time::system_clock::now() + time::days(1), Name("/ndn/alice"));
diff --git a/tests/unit-tests/ca-config.t.cpp b/tests/unit-tests/ca-config.t.cpp
deleted file mode 100644
index 2e054cb..0000000
--- a/tests/unit-tests/ca-config.t.cpp
+++ /dev/null
@@ -1,83 +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 "ca-config.hpp"
-#include "protocol-detail/info.hpp"
-#include "test-common.hpp"
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(TestCaConfig, IdentityManagementFixture)
-
-BOOST_AUTO_TEST_CASE(ReadConfigFile)
-{
- CaConfig config;
- config.load("tests/unit-tests/ca.conf.test");
- BOOST_CHECK_EQUAL(config.m_caPrefix, "/ndn");
- BOOST_CHECK_EQUAL(config.m_caInfo, "ndn testbed ca");
- BOOST_CHECK_EQUAL(config.m_maxValidityPeriod, time::seconds(86400));
- BOOST_CHECK_EQUAL(config.m_probeParameterKeys.size(), 1);
- BOOST_CHECK_EQUAL(config.m_probeParameterKeys.front(), "full name");
- BOOST_CHECK_EQUAL(config.m_supportedChallenges.size(), 1);
- BOOST_CHECK_EQUAL(config.m_supportedChallenges.front(), "pin");
-}
-
-BOOST_AUTO_TEST_CASE(ReadNonexistConfigFile)
-{
- CaConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/Nonexist"), std::runtime_error);
-}
-
-BOOST_AUTO_TEST_CASE(ReadConfigFileWithoutCaPrefix)
-{
- CaConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/ca.conf.test2"), std::runtime_error);
-}
-
-BOOST_AUTO_TEST_CASE(ReadConfigFileWithChallengeNotSupported)
-{
- CaConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/ca.conf.test3"), std::runtime_error);
-}
-
-BOOST_AUTO_TEST_CASE(InfoContentEncodingDecoding)
-{
- CaConfig config;
- config.load("tests/unit-tests/ca.conf.test");
-
- const auto& identity = addIdentity("/test");
- const auto& cert = identity.getDefaultKey().getDefaultCertificate();
- auto encoded = INFO::encodeDataContent(config, cert);
- auto decoded = INFO::decodeClientConfigFromContent(encoded);
- BOOST_CHECK_EQUAL(config.m_caPrefix, decoded.m_caPrefix);
- BOOST_CHECK_EQUAL(config.m_caInfo, decoded.m_caInfo);
- BOOST_CHECK_EQUAL(config.m_maxValidityPeriod, decoded.m_maxValidityPeriod);
- BOOST_CHECK_EQUAL(config.m_probeParameterKeys.size(), decoded.m_probeParameterKeys.size());
- BOOST_CHECK_EQUAL(config.m_probeParameterKeys.front(), decoded.m_probeParameterKeys.front());
- BOOST_CHECK_EQUAL(cert.wireEncode(), decoded.m_anchor.wireEncode());
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestCaConfig
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 365cb90..599b6ce 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -35,8 +35,8 @@
BOOST_AUTO_TEST_CASE(Initialization)
{
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
- BOOST_CHECK_EQUAL(ca.getCaConf().m_caPrefix, "/ndn");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
+ BOOST_CHECK_EQUAL(ca.getCaConf().m_caItem.m_caPrefix, "/ndn");
auto identity = addIdentity(Name("/ndn/site2"));
auto key = identity.getDefaultKey();
@@ -56,7 +56,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
Interest interest("/ndn/CA/INFO");
@@ -68,10 +68,10 @@
BOOST_CHECK(security::verifySignature(response, cert));
auto contentBlock = response.getContent();
contentBlock.parse();
- auto caItem = INFO::decodeClientConfigFromContent(contentBlock);
+ auto caItem = INFO::decodeDataContentToCaProfile(contentBlock);
BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
- BOOST_CHECK_EQUAL(caItem.m_probe, "");
- BOOST_CHECK_EQUAL(caItem.m_anchor.wireEncode(), cert.wireEncode());
+ BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 0);
+ BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
});
face.receive(interest);
@@ -87,7 +87,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
ca.setNameAssignmentFunction([&](const std::vector<std::tuple<std::string, std::string>>) -> std::vector<std::string> {
std::vector<std::string> result;
result.push_back("example");
@@ -130,7 +130,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
Interest interest("/ndn/CA/PROBE");
@@ -168,13 +168,13 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto interest = client.generateNewInterest(time::system_clock::now(),
@@ -219,13 +219,13 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
advanceClocks(time::milliseconds(20), 60);
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto current_tp = time::system_clock::now();
auto interest1 = client.generateNewInterest(current_tp, current_tp - time::hours(1),
@@ -255,13 +255,13 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto interest1 = client.generateNewInterest(time::system_clock::now(),
@@ -300,13 +300,13 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1");
advanceClocks(time::milliseconds(20), 60);
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto current_tp = time::system_clock::now();
auto interest1 = client.generateNewInterest(current_tp, current_tp + time::days(1), Name("/ndn"));
@@ -330,14 +330,14 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, m_keyChain, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
// generate NEW Interest
ClientModule client(m_keyChain);
- ClientCaItem item;
+ CaConfigItem item;
item.m_caPrefix = Name("/ndn");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto newInterest = client.generateNewInterest(time::system_clock::now(),
time::system_clock::now() + time::days(1), Name("/ndn/zhiyi"));
@@ -413,7 +413,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
//generate a certificate
@@ -432,9 +432,9 @@
auto issuedCert = ca.issueCertificate(certRequest);
ClientModule client(m_keyChain);
- ClientCaItem item;
- item.m_caName = Name("/ndn");
- item.m_anchor = cert;
+ CaConfigItem item;
+ item.m_caPrefix = Name("/ndn");
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto interest = client.generateRevokeInterest(issuedCert);
@@ -477,7 +477,7 @@
auto cert = key.getDefaultCertificate();
util::DummyClientFace face(io, {true, true});
- CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
+ CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
//generate a certificate
@@ -494,9 +494,9 @@
m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
ClientModule client(m_keyChain);
- ClientCaItem item;
- item.m_caName = Name("/ndn");
- item.m_anchor = cert;
+ CaConfigItem item;
+ item.m_caPrefix = Name("/ndn");
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
auto interest = client.generateRevokeInterest(clientCert);
diff --git a/tests/unit-tests/ca.conf.test2 b/tests/unit-tests/ca.conf.test2
deleted file mode 100644
index 22cd83c..0000000
--- a/tests/unit-tests/ca.conf.test2
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "ca-info": "ndn testbed ca",
- "max-validity-period": "86400",
- "supported-challenges":
- [
- { "challenge": "PIN" }
- ]
-}
\ No newline at end of file
diff --git a/tests/unit-tests/ca.conf.test3 b/tests/unit-tests/ca.conf.test3
deleted file mode 100644
index b330134..0000000
--- a/tests/unit-tests/ca.conf.test3
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "ca-prefix": "/ndn",
- "ca-info": "ndn testbed ca",
- "max-validity-period": "86400",
- "supported-challenges":
- [
- { "challenge": "ABC" }
- ]
-}
\ No newline at end of file
diff --git a/tests/unit-tests/client-config.t.cpp b/tests/unit-tests/client-config.t.cpp
deleted file mode 100644
index f23f502..0000000
--- a/tests/unit-tests/client-config.t.cpp
+++ /dev/null
@@ -1,89 +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 "test-common.hpp"
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(TestClientConfig)
-
-BOOST_AUTO_TEST_CASE(ReadConfigFile)
-{
- ClientConfig config;
- config.load("tests/unit-tests/client.conf.test");
- BOOST_CHECK_EQUAL(config.m_caItems.size(), 2);
-
- const auto& item = config.m_caItems.front();
- BOOST_CHECK_EQUAL(item.m_caPrefix, "/ndn/edu/ucla");
- BOOST_CHECK_EQUAL(item.m_caInfo, "UCLA's ceritificate authority, located in BH4805.");
- BOOST_CHECK_EQUAL(item.m_probe, "email");
- BOOST_CHECK_EQUAL(item.m_anchor.getName(),
- "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5");
-
- BOOST_CHECK_EQUAL(config.m_localNdncertAnchor, "/usr/local/etc/ndncert/anchor.key");
-}
-
-BOOST_AUTO_TEST_CASE(ReadNonexistConfigFile)
-{
- ClientConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/nonexist"), ClientConfig::Error);
-}
-
-BOOST_AUTO_TEST_CASE(ReadConfigFileWithInvalidCert)
-{
- ClientConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/client.conf.test2"), ClientConfig::Error);
-}
-
-BOOST_AUTO_TEST_CASE(ReadConfigFileWithoutCaPrefix)
-{
- ClientConfig config;
- BOOST_CHECK_THROW(config.load("tests/unit-tests/client.conf.test3"), ClientConfig::Error);
-}
-
-BOOST_AUTO_TEST_CASE(AddAndRemoveCaItem)
-{
- ClientConfig config;
- config.load("tests/unit-tests/client.conf.test");
-
- ClientCaItem item;
- item.m_caPrefix = Name("/test");
- item.m_caInfo = "test";
- item.m_probe = "test";
-
- config.m_caItems.push_back(item);
- BOOST_CHECK_EQUAL(config.m_caItems.size(), 3);
- auto lastItem = config.m_caItems.back();
- BOOST_CHECK_EQUAL(lastItem.m_caPrefix, "/test");
-
- config.removeCaItem(Name("/test"));
- BOOST_CHECK_EQUAL(config.m_caItems.size(), 2);
- lastItem = config.m_caItems.back();
- BOOST_CHECK_EQUAL(lastItem.m_caPrefix, "/ndn/edu/ucla/zhiyi");
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestClientConfig
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/unit-tests/client-module.t.cpp b/tests/unit-tests/client-module.t.cpp
index 159eaaf..e8dccaf 100644
--- a/tests/unit-tests/client-module.t.cpp
+++ b/tests/unit-tests/client-module.t.cpp
@@ -32,26 +32,32 @@
BOOST_AUTO_TEST_CASE(ClientModuleInitialize)
{
ClientModule client(m_keyChain);
- client.getClientConf().load("tests/unit-tests/client.conf.test");
+ client.getClientConf().load("tests/unit-tests/config-files/config-client-1");
BOOST_CHECK_EQUAL(client.getClientConf().m_caItems.size(), 2);
}
BOOST_AUTO_TEST_CASE(Probe)
{
ClientModule client(m_keyChain);
- client.getClientConf().load("tests/unit-tests/client.conf.test");
+ client.getClientConf().load("tests/unit-tests/config-files/config-client-1");
auto identity = addIdentity(Name("/site"));
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
- ClientCaItem item;
- item.m_probe = "email:uid:name";
+ CaConfigItem item;
+ item.m_probeParameterKeys.push_back("email");
+ item.m_probeParameterKeys.push_back("uid");
+ item.m_probeParameterKeys.push_back("name");
item.m_caPrefix = Name("/site");
- item.m_anchor = cert;
+ item.m_cert = std::make_shared<security::v2::Certificate>(cert);
client.getClientConf().m_caItems.push_back(item);
- auto firstInterest = client.generateProbeInterest(item, "zhiyi@cs.ucla.edu:987654321:Zhiyi Zhang");
+ std::vector<std::tuple<std::string, std::string>> probeParams;
+ probeParams.push_back(std::make_tuple("email", "zhiyi@cs.ucla.edu"));
+ probeParams.push_back(std::make_tuple("uid", "987654321"));
+ probeParams.push_back(std::make_tuple("name", "Zhiyi Zhang"));
+ auto firstInterest = client.generateProbeInterest(item, std::move(probeParams));
BOOST_CHECK(firstInterest->getName().at(-1).isParametersSha256Digest());
// ignore the last name component (ParametersSha256Digest)
BOOST_CHECK_EQUAL(firstInterest->getName().getPrefix(-1), "/site/CA/PROBE");
@@ -62,16 +68,16 @@
// BOOST_AUTO_TEST_CASE(GenProbeRequestJson)
// {
// ClientModule client(m_keyChain);
-// client.getClientConf().load("tests/unit-tests/client.conf.test");
+// client.getClientConf().load("tests/unit-tests/config-files/config-client-1");
// auto identity = addIdentity(Name("/site"));
// auto key = identity.getDefaultKey();
// auto cert = key.getDefaultCertificate();
-// ClientCaItem item;
+// CaConfigItem item;
// item.m_probe = "email:uid:name";
// item.m_caPrefix = Name("/site");
-// item.m_anchor = cert;
+// item.m_cert = std::make_shared<security::v2::Certificate>(cert);
// client.getClientConf().m_caItems.push_back(item);
// auto interestPacket = client.genProbeRequestJson(item, "yufeng@ucla.edu:123456789:Yufeng Zhang");
diff --git a/tests/unit-tests/client.conf.test2 b/tests/unit-tests/client.conf.test2
deleted file mode 100644
index f3d5630..0000000
--- a/tests/unit-tests/client.conf.test2
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "ca-list":
- [
- {
- "ca-prefix": "/ndn/edu/ucla",
- "ca-info": "UCLA's ceritificate authority, located in BH4805.",
- "probe": "email",
- "certificate": "ANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
- },
- {
- "ca-prefix": "/ndn/edu/ucla/zhiyi",
- "ca-info": "Zhiyi's own ceritificate authority",
- "probe": "email",
- "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
- }
- ],
- "local-ndncert-anchor": "/usr/local/etc/ndncert/anchor.key"
-}
\ No newline at end of file
diff --git a/tests/unit-tests/client.conf.test3 b/tests/unit-tests/client.conf.test3
deleted file mode 100644
index 257850a..0000000
--- a/tests/unit-tests/client.conf.test3
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "ca-list":
- [
- {
- "ca-info": "UCLA's ceritificate authority, located in BH4805.",
- "probe": "email",
- "certificate": "ANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
- },
- {
- "ca-prefix": "/ndn/edu/ucla/zhiyi",
- "ca-info": "Zhiyi's own ceritificate authority",
- "probe": "email",
- "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
- }
- ],
- "local-ndncert-anchor": "/usr/local/etc/ndncert/anchor.key"
-}
\ No newline at end of file
diff --git a/tests/unit-tests/ca.conf.test b/tests/unit-tests/config-files/config-ca-1
similarity index 74%
rename from tests/unit-tests/ca.conf.test
rename to tests/unit-tests/config-files/config-ca-1
index bf795fd..8ea5d38 100644
--- a/tests/unit-tests/ca.conf.test
+++ b/tests/unit-tests/config-files/config-ca-1
@@ -1,7 +1,8 @@
{
"ca-prefix": "/ndn",
- "max-validity-period": "86400",
"ca-info": "ndn testbed ca",
+ "max-validity-period": "864000",
+ "max-suffix-length": 3,
"probe-parameters":
[
{ "probe-parameter-key": "full name" }
@@ -9,6 +10,5 @@
"supported-challenges":
[
{ "challenge": "PIN" }
- ],
- "max-suffix-length": 3
+ ]
}
\ No newline at end of file
diff --git a/tests/unit-tests/config-files/config-ca-2 b/tests/unit-tests/config-files/config-ca-2
new file mode 100644
index 0000000..9b7c2bd
--- /dev/null
+++ b/tests/unit-tests/config-files/config-ca-2
@@ -0,0 +1,9 @@
+{
+ "ca-prefix": "/ndn",
+ "ca-info": "missing max validity period, max suffix length, and probe",
+ "supported-challenges":
+ [
+ { "challenge": "pin" },
+ { "challenge": "email" }
+ ]
+}
\ No newline at end of file
diff --git a/tests/unit-tests/config-files/config-ca-3 b/tests/unit-tests/config-files/config-ca-3
new file mode 100644
index 0000000..7946ca0
--- /dev/null
+++ b/tests/unit-tests/config-files/config-ca-3
@@ -0,0 +1,10 @@
+{
+ "ca-prefix": "/ndn",
+ "ca-info": "missing challenge",
+ "max-validity-period": "86400",
+ "max-suffix-length": 3,
+ "probe-parameters":
+ [
+ { "probe-parameter-key": "full name" }
+ ]
+}
\ No newline at end of file
diff --git a/tests/unit-tests/ca.conf.test b/tests/unit-tests/config-files/config-ca-4
similarity index 61%
copy from tests/unit-tests/ca.conf.test
copy to tests/unit-tests/config-files/config-ca-4
index bf795fd..98d6c92 100644
--- a/tests/unit-tests/ca.conf.test
+++ b/tests/unit-tests/config-files/config-ca-4
@@ -1,14 +1,14 @@
{
"ca-prefix": "/ndn",
+ "ca-info": "unsupported challenge",
"max-validity-period": "86400",
- "ca-info": "ndn testbed ca",
+ "max-suffix-length": 3,
"probe-parameters":
[
{ "probe-parameter-key": "full name" }
],
"supported-challenges":
[
- { "challenge": "PIN" }
- ],
- "max-suffix-length": 3
+ { "challenge": "something" }
+ ]
}
\ No newline at end of file
diff --git a/tests/unit-tests/client.conf.test b/tests/unit-tests/config-files/config-client-1
similarity index 86%
rename from tests/unit-tests/client.conf.test
rename to tests/unit-tests/config-files/config-client-1
index 903c2bd..20daad1 100644
--- a/tests/unit-tests/client.conf.test
+++ b/tests/unit-tests/config-files/config-client-1
@@ -3,16 +3,18 @@
[
{
"ca-prefix": "/ndn/edu/ucla",
- "ca-info": "UCLA's ceritificate authority, located in BH4805.",
- "probe": "email",
+ "ca-info": "ndn testbed ca",
+ "max-validity-period": "864000",
+ "max-suffix-length": 3,
+ "probe-parameters":
+ [
+ { "probe-parameter-key": "email" }
+ ],
"certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
},
{
"ca-prefix": "/ndn/edu/ucla/zhiyi",
- "ca-info": "Zhiyi's own ceritificate authority",
- "probe": "email",
"certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
}
- ],
- "local-ndncert-anchor": "/usr/local/etc/ndncert/anchor.key"
+ ]
}
\ No newline at end of file
diff --git a/tests/unit-tests/config-files/config-client-2 b/tests/unit-tests/config-files/config-client-2
new file mode 100644
index 0000000..4eb3958
--- /dev/null
+++ b/tests/unit-tests/config-files/config-client-2
@@ -0,0 +1,13 @@
+{
+ "ca-list":
+ [
+ {
+ "ca-prefix": "/ndn/edu/ucla",
+ "ca-info": "missing certificate",
+ "probe-parameters":
+ [
+ { "probe-parameter-key": "email" }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/unit-tests/config-files/config-client-3 b/tests/unit-tests/config-files/config-client-3
new file mode 100644
index 0000000..66ec4b6
--- /dev/null
+++ b/tests/unit-tests/config-files/config-client-3
@@ -0,0 +1,13 @@
+{
+ "ca-list":
+ [
+ {
+ "ca-info": "missing ca prefix",
+ "probe-parameters":
+ [
+ { "probe-parameter-key": "email" }
+ ],
+ "certificate": "ANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/unit-tests/configuration.t.cpp b/tests/unit-tests/configuration.t.cpp
new file mode 100644
index 0000000..2c0ca02
--- /dev/null
+++ b/tests/unit-tests/configuration.t.cpp
@@ -0,0 +1,145 @@
+/* -*- 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 "configuration.hpp"
+#include "protocol-detail/info.hpp"
+#include "test-common.hpp"
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TestConfig, IdentityManagementFixture)
+
+BOOST_AUTO_TEST_CASE(CAConfigFile)
+{
+ CaConfig config;
+ config.load("tests/unit-tests/config-files/config-ca-1");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caPrefix, "/ndn");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caInfo, "ndn testbed ca");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_maxValidityPeriod, time::seconds(864000));
+ BOOST_CHECK_EQUAL(*config.m_caItem.m_maxSuffixLength, 3);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.size(), 1);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.front(), "full name");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_supportedChallenges.size(), 1);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_supportedChallenges.front(), "pin");
+
+ config.load("tests/unit-tests/config-files/config-ca-2");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caPrefix, "/ndn");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caInfo, "missing max validity period, max suffix length, and probe");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_maxValidityPeriod, time::seconds(86400));
+ BOOST_CHECK(!config.m_caItem.m_maxSuffixLength);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.size(), 0);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_supportedChallenges.size(), 0);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_supportedChallenges.front(), "pin");
+ BOOST_CHECK_EQUAL(config.m_caItem.m_supportedChallenges.back(), "email");
+}
+
+BOOST_AUTO_TEST_CASE(CAConfigFileWithErrors)
+{
+ CaConfig config;
+ // nonexistent file
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/Nonexist"), std::runtime_error);
+ // missing challenge
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/config-ca-3"), std::runtime_error);
+ // unsupported challenge
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/config-ca-4"), std::runtime_error);
+}
+
+BOOST_AUTO_TEST_CASE(ClientConfigFile)
+{
+ ClientConfig config;
+ config.load("tests/unit-tests/config-files/config-client-1");
+ BOOST_CHECK_EQUAL(config.m_caItems.size(), 2);
+
+ auto& config1 = config.m_caItems.front();
+ BOOST_CHECK_EQUAL(config1.m_caPrefix, "/ndn");
+ BOOST_CHECK_EQUAL(config1.m_caInfo, "ndn testbed ca");
+ BOOST_CHECK_EQUAL(config1.m_maxValidityPeriod, time::seconds(864000));
+ BOOST_CHECK_EQUAL(*config1.m_maxSuffixLength, 3);
+ BOOST_CHECK_EQUAL(config1.m_probeParameterKeys.size(), 1);
+ BOOST_CHECK_EQUAL(config1.m_probeParameterKeys.front(), "email");
+ BOOST_CHECK_EQUAL(config1.m_cert->getName(),
+ "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5");
+
+ auto& config2 = config.m_caItems.front();
+ BOOST_CHECK_EQUAL(config2.m_caPrefix, "/ndn");
+ BOOST_CHECK_EQUAL(config2.m_caInfo, "ndn testbed ca");
+ BOOST_CHECK_EQUAL(config2.m_maxValidityPeriod, time::seconds(86400));
+ BOOST_CHECK(!config2.m_maxSuffixLength);
+ BOOST_CHECK_EQUAL(config2.m_probeParameterKeys.size(), 0);
+ BOOST_CHECK_EQUAL(config2.m_cert->getName(),
+ "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5");
+}
+
+BOOST_AUTO_TEST_CASE(ClientConfigFileWithErrors)
+{
+ ClientConfig config;
+ // nonexistent file
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/Nonexist"), std::runtime_error);
+ // missing certificate
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/config-client-2"), std::runtime_error);
+ // missing ca prefix
+ BOOST_CHECK_THROW(config.load("tests/unit-tests/config-files/config-client-3"), std::runtime_error);
+}
+
+BOOST_AUTO_TEST_CASE(ClientConfigFileAddAndRemoveCaItem)
+{
+ ClientConfig config;
+ config.load("tests/unit-tests/config-files/config-client-1");
+
+ CaConfigItem item;
+ item.m_caPrefix = Name("/test");
+ item.m_caInfo = "test";
+
+ config.m_caItems.push_back(item);
+ BOOST_CHECK_EQUAL(config.m_caItems.size(), 3);
+ auto lastItem = config.m_caItems.back();
+ BOOST_CHECK_EQUAL(lastItem.m_caPrefix, "/test");
+
+ config.removeCaItem(Name("/test"));
+ BOOST_CHECK_EQUAL(config.m_caItems.size(), 2);
+ lastItem = config.m_caItems.back();
+ BOOST_CHECK_EQUAL(lastItem.m_caPrefix, "/ndn/edu/ucla/zhiyi");
+}
+
+BOOST_AUTO_TEST_CASE(InfoEncodingDecoding)
+{
+ CaConfig config;
+ config.load("tests/unit-tests/config-files/config-ca-1");
+
+ const auto& identity = addIdentity("/test");
+ const auto& cert = identity.getDefaultKey().getDefaultCertificate();
+ auto encoded = INFO::encodeDataContent(config.m_caItem, cert);
+ auto decoded = INFO::decodeDataContentToCaProfile(encoded);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caPrefix, decoded.m_caPrefix);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_caInfo, decoded.m_caInfo);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_maxValidityPeriod, decoded.m_maxValidityPeriod);
+ BOOST_CHECK_EQUAL(*config.m_caItem.m_maxSuffixLength, *decoded.m_maxSuffixLength);
+ BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.size(), decoded.m_probeParameterKeys.size());
+ BOOST_CHECK_EQUAL(config.m_caItem.m_probeParameterKeys.front(), decoded.m_probeParameterKeys.front());
+ BOOST_CHECK_EQUAL(cert.wireEncode(), decoded.m_cert->wireEncode());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestCaConfig
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index 73ae8c3..8e2da5e 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -58,21 +58,19 @@
}
}
-static std::list<std::string>
-captureParams(const std::vector<std::string>& requirement)
+static std::vector<std::tuple<std::string, std::string>>
+captureParams(const std::list<std::string>& requirement)
{
- std::list<std::string> results;
+ std::vector<std::tuple<std::string, std::string>> results;
for (const auto& item : requirement) {
std::cerr << "Please provide the argument: " << item << " : " << std::endl;
- std::string tempParam;
- getline(std::cin, tempParam);
- results.push_back(tempParam);
+ std::string captured;
+ getline(std::cin, captured);
+ results.push_back(std::make_tuple(item, captured));
}
std::cerr << "Got it. This is what you've provided:" << std::endl;
- auto it1 = results.begin();
- auto it2 = requirement.begin();
- for (; it1 != results.end() && it2 != requirement.end(); it1++, it2++) {
- std::cerr << *it2 << " : " << *it1 << std::endl;
+ for (const auto& item : results) {
+ std::cerr << std::get<0>(item) << " : " << std::get<1>(item) << std::endl;
}
return results;
}
@@ -203,12 +201,12 @@
std::cerr << "The fetched CA information cannot be trusted because its integrity is broken" << std::endl;
return;
}
- auto caItem = INFO::decodeClientConfigFromContent(contentBlock);
+ auto caItem = INFO::decodeDataContentToCaProfile(contentBlock);
std::cerr << "Will use a new trust anchor, please double check the identity info: \n"
<< "This trust anchor information is signed by " << reply.getSignature().getKeyLocator()
<< std::endl
- << "The certificate is " << caItem.m_anchor << std::endl
+ << "The certificate is " << *caItem.m_cert << std::endl
<< "Do you trust the information? Type in YES or NO" << std::endl;
std::string answer;
@@ -259,7 +257,7 @@
<< "Introduction: " << item.m_caInfo << "\n"
<< "***************************************\n";
}
- std::vector<ClientCaItem> caVector{std::begin(caList), std::end(caList)};
+ std::vector<CaConfigItem> caVector{std::begin(caList), std::end(caList)};
std::cerr << "Step "
<< nStep++ << ": Please type in the CA INDEX that you want to apply"
<< " or type in NONE if your expected CA is not in the list\n";
@@ -290,19 +288,10 @@
}
auto targetCaItem = caVector[caIndex];
- if (targetCaItem.m_probe != "") {
+ if (!targetCaItem.m_probeParameterKeys.empty()) {
std::cerr << "Step " << nStep++ << ": Please provide information for name assignment" << std::endl;
- std::vector<std::string> probeFields = ClientModule::parseProbeComponents(targetCaItem.m_probe);
- std::string redo = "";
- std::list<std::string> capturedParams;
- capturedParams = captureParams(probeFields);
- std::string probeInfo;
- for (const auto& item : capturedParams) {
- probeInfo += item;
- probeInfo += ":";
- }
- probeInfo = probeInfo.substr(0, probeInfo.size() - 1);
- face.expressInterest(*client.generateProbeInterest(targetCaItem, probeInfo),
+ auto capturedParams = captureParams(targetCaItem.m_probeParameterKeys);
+ face.expressInterest(*client.generateProbeInterest(targetCaItem, std::move(capturedParams)),
bind(&probeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}
else {