client: fetch ca profile and validate with preconfigured ca cert
Change-Id: I0e6819d9f8030a960e20d0a545f5c29c5f9589ce
diff --git a/client.conf.sample b/client.conf.sample
index 53dbd95..f3bf724 100644
--- a/client.conf.sample
+++ b/client.conf.sample
@@ -2,16 +2,8 @@
"ca-list":
[
{
- "ca-prefix": "/ndncert-demo",
- "ca-info": "NDN Testbed NDNCERT CA (Demo)",
- "max-validity-period": "1296000",
- "max-suffix-length": "5",
- "probe-parameters": [
- {
- "probe-parameter-key": "email"
- }
- ],
- "certificate": "Bv0BLwctCAxuZG5jZXJ0LWRlbW8IA0tFWQgI92c9QI8lJGoIBHNlbGY2CAAAAX7YsardFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNIu6i4dFU2FwW9641O4XehbwZD3INSgsEehPfZVRnDhQ0l5oRdUGJo6OQhOutExKov7dp+hzmRSAHbiO3dRjdIWThsBAxwfBx0IDG5kbmNlcnQtZGVtbwgDS0VZCAj3Zz1AjyUkav0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwNDIwMjAzVDA5MzcwORdGMEQCIA7CEGlG+KQnJudjqpCzt7IlHRgPV2ni1k5mSu0yZXKtAiAGkqnGwTu1e8LVqZ1XIidt/wDzcYXTQGEoltwhcN6jUw=="
+ "ca-prefix": "/ndn",
+ "certificate": "Bv0BSwcjCANuZG4IA0tFWQgIJ8SyKp97gScIA25kbjYIAAABgHX6c7QUCRgBAhkEADbugBVbMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPuDnW4oq0mULLT8PDXh0zuBg+0SJ1yPC85jylUU+hgxX9fDNyjlykLrvb1D6IQRJWJHMKWe6TJKPUhGgOT658hZyGwEDHBYHFAgDbmRuCANLRVkICCfEsiqfe4En/QD9Jv0A/g8yMDIyMDQyOVQxNTM5NTD9AP8PMjAyNjEyMzFUMjM1OTU5/QECKf0CACX9AgEIZnVsbG5hbWX9AgIVTkROIFRlc3RiZWQgUm9vdCAyMjA0F0gwRgIhAPYUOjNakdfDGh5j9dcCGOz+Ie1MqoAEsjM9PEUEWbnqAiEApu0rg9GAK1LNExjLYAF6qVgpWQgU+atPn63Gtuubqyg="
}
]
}
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index ee22db5..3c7d3de 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -51,6 +51,7 @@
static ndn::KeyChain keyChain;
static std::shared_ptr<Request> requesterState;
static std::shared_ptr<std::multimap<std::string, std::string>> capturedProbeParams;
+static std::shared_ptr<Certificate> trustedCert;
static Name newlyCreatedIdentityName;
static Name newlyCreatedKeyName;
@@ -279,6 +280,9 @@
std::optional<CaProfile> profile;
try {
if (certFullName.empty()) {
+ if (trustedCert && !ndn::security::verifySignature(reply, *trustedCert)) {
+ NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
+ }
profile = Request::onCaProfileResponse(reply);
}
else {
@@ -289,24 +293,31 @@
std::cerr << "The fetched CA information cannot be used because: " << e.what() << std::endl;
return;
}
- std::cerr << "\n***************************************\n"
- << "Step " << nStep++
- << ": Will use a new trust anchor, please double check the identity info:" << std::endl
- << "> New CA name: " << profile->caPrefix << std::endl
- << "> This trust anchor information is signed by: " << reply.getSignatureInfo().getKeyLocator() << std::endl
- << "> The certificate: " << *profile->cert << std::endl
- << "Do you trust the information? Type in YES or NO" << std::endl;
+ if (!trustedCert)
+ {
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
+ << ": Will use the following CA, please double check the identity info:" << std::endl
+ << "> CA name: " << profile->caPrefix << std::endl
+ << "> This CA information is signed by: " << reply.getSignatureInfo().getKeyLocator() << std::endl
+ << "> The certificate:" << std::endl << *profile->cert << std::endl
+ << "Do you trust the information? Type in YES or NO" << std::endl;
- std::string answer;
- getline(std::cin, answer);
- boost::algorithm::to_lower(answer);
- if (answer == "yes") {
- std::cerr << "You answered YES: new CA " << profile->caPrefix << " will be used" << std::endl;
- runProbe(*profile);
+ std::string answer;
+ getline(std::cin, answer);
+ boost::algorithm::to_lower(answer);
+ if (answer == "yes") {
+ std::cerr << "You answered YES: new CA " << profile->caPrefix << " will be used" << std::endl;
+ trustedCert = profile->cert;
+ runProbe(*profile);
+ }
+ else {
+ std::cerr << "You answered NO: new CA " << profile->caPrefix << " will not be used" << std::endl;
+ exit(0);
+ }
}
else {
- std::cerr << "You answered NO: new CA " << profile->caPrefix << " will not be used" << std::endl;
- exit(0);
+ runProbe(*profile);
}
}
@@ -435,22 +446,19 @@
getline(std::cin, caIndexS);
caIndexSLower = caIndexS;
boost::algorithm::to_lower(caIndexSLower);
+ Name selectedCaName;
if (caIndexSLower == "none") {
std::cerr << "\n***************************************\n"
<< "Step " << nStep << ": ADD NEW CA\nPlease type in the CA's Name:" << std::endl;
- std::string expectedCAName;
- getline(std::cin, expectedCAName);
- face.expressInterest(
- *Request::genCaProfileDiscoveryInterest(Name(expectedCAName)),
- [&] (const auto&, const auto& data) {
- auto fetchingInterest = Request::genCaProfileInterestFromDiscoveryResponse(data);
- face.expressInterest(*fetchingInterest,
- [] (const auto&, const auto& data2) { infoCb(data2, {}); },
- [] (auto&&...) { onNackCb(); },
- [] (auto&&...) { timeoutCb(); });
- },
- [] (auto&&...) { onNackCb(); },
- [] (auto&&...) { timeoutCb(); });
+ std::string targetCaName;
+ getline(std::cin, targetCaName);
+ try {
+ selectedCaName = Name(targetCaName);
+ }
+ catch (const std::exception&) {
+ std::cerr << "Your input is not a valid name. Exit" << std::endl;
+ exit(1);
+ }
}
else {
size_t caIndex;
@@ -468,8 +476,20 @@
auto itemIterator = profileStorage.getKnownProfiles().cbegin();
std::advance(itemIterator, caIndex);
auto targetCaItem = *itemIterator;
- runProbe(targetCaItem);
+ trustedCert = targetCaItem.cert;
+ selectedCaName = targetCaItem.caPrefix;
}
+ face.expressInterest(
+ *Request::genCaProfileDiscoveryInterest(selectedCaName),
+ [&] (const auto&, const auto& data) {
+ auto fetchingInterest = Request::genCaProfileInterestFromDiscoveryResponse(data);
+ face.expressInterest(*fetchingInterest,
+ [] (const auto&, const auto& data2) { infoCb(data2, {}); },
+ [] (auto&&...) { onNackCb(); },
+ [] (auto&&...) { timeoutCb(); });
+ },
+ [] (auto&&...) { onNackCb(); },
+ [] (auto&&...) { timeoutCb(); });
}
static void