update requester and cmd line tool after testing cmd line tool
Change-Id: I301ac41a402ef3e808017aad9a79ddfe7117942d
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index d85c839..96064b6 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -19,14 +19,14 @@
*/
#include "challenge-module.hpp"
-#include "requester.hpp"
#include "protocol-detail/info.hpp"
-#include <ndn-cxx/security/verification-helpers.hpp>
+#include "requester.hpp"
#include <boost/asio.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <iostream>
+#include <ndn-cxx/security/verification-helpers.hpp>
#include <string>
namespace ndn {
@@ -40,10 +40,8 @@
runNew(CaProfile profile, Name identityName);
static void
runChallenge(const std::string& challengeType);
-static void
-startApplication(std::string configFilePath);
-int nStep;
+size_t nStep = 1;
Face face;
security::v2::KeyChain keyChain;
shared_ptr<RequesterState> requesterState = nullptr;
@@ -69,7 +67,7 @@
{
std::vector<std::tuple<std::string, std::string>> results;
for (const auto& r : requirement) {
- results.emplace_back(r, "Please input: " + r);
+ results.emplace_back(r, "Please input: " + r);
}
captureParams(results);
return results;
@@ -78,7 +76,8 @@
static int
captureValidityPeriod()
{
- std::cerr << "Step " << nStep++
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
<< ": Please type in your expected validity period of your certificate."
<< " Type the number of hours (168 for week, 730 for month, 8760 for year)."
<< " The CA may reject your application if your expected period is too long." << std::endl;
@@ -86,13 +85,9 @@
std::string periodStr = "";
getline(std::cin, periodStr);
try {
- int validityPeriod = std::stoi(periodStr);
- if (validityPeriod < 0) {
- BOOST_THROW_EXCEPTION(std::runtime_error(""));
- }
- return validityPeriod;
+ return std::stoul(periodStr);
}
- catch (const std::exception &e) {
+ catch (const std::exception& e) {
std::cerr << "Your input is invalid. Try again: " << std::endl;
}
}
@@ -115,11 +110,14 @@
{
auto item = Requester::onCertFetchResponse(reply);
if (item) {
- keyChain.addCertificate(keyChain.getPib().getIdentity(item->getIdentity()).getKey(item->getKeyName()), *item);
+ keyChain.addCertificate(keyChain.getPib().getIdentity(item->getIdentity()).getKey(item->getKeyName()), *item);
}
- std::cerr << "Step " << nStep++
- << ": DONE! Certificate has already been installed to local keychain\n"
- << "Certificate Name: " << reply.getName().toUri() << std::endl;
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
+ << ": DONE\nCertificate with Name: " << reply.getName().toUri()
+ << "has already been installed to your local keychain" << std::endl
+ << "Exit now";
+ face.getIoService().stop();
}
static void
@@ -127,12 +125,13 @@
{
try {
Requester::onChallengeResponse(*requesterState, reply);
- } catch (const std::exception& e) {
+ }
+ catch (const std::exception& e) {
std::cerr << "Error when decoding challenge step: " << e.what() << std::endl;
exit(1);
}
if (requesterState->m_status == Status::SUCCESS) {
- std::cerr << "Certificate has already been issued, downloading certificate... \n";
+ std::cerr << "Certificate has already been issued, downloading certificate..." << std::endl;
face.expressInterest(*Requester::genCertFetchInterest(*requesterState), bind(&certFetchCb, _2),
bind(&onNackCb), bind(&timeoutCb));
return;
@@ -146,39 +145,43 @@
{
std::list<std::string> challengeList;
try {
- challengeList = Requester::onNewRenewRevokeResponse(*requesterState, reply);
- } catch (const std::exception& e) {
+ challengeList = Requester::onNewRenewRevokeResponse(*requesterState, reply);
+ }
+ catch (const std::exception& e) {
std::cerr << "Error on decoding NEW step reply because: " << e.what() << std::endl;
exit(1);
}
- int challengeIndex = 0;
+ size_t challengeIndex = 0;
if (challengeList.size() < 1) {
std::cerr << "There is no available challenge provided by the CA. Exit" << std::endl;
exit(1);
}
else if (challengeList.size() > 1) {
- int count = 0;
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
+ << ": CHALLENGE SELECTION" << std::endl;
+ size_t count = 0;
std::string choice = "";
- std::cerr << "Step " << nStep++ << ": Please type in the challenge index that you want to perform\n";
- count = 0;
for (auto item : challengeList) {
- std::cerr << "\t" << count++ << " : " << item << std::endl;
+ std::cerr << "> Index: " << count++ << std::endl
+ << ">> Challenge:" << item << std::endl;
}
+ std::cerr << "Please type in the challenge index that you want to perform:" << std::endl;
while (true) {
- getline(std::cin, choice);
- try {
- challengeIndex = std::stoi(choice);
- }
- catch (const std::exception &e) {
- std::cerr << "Your input is not valid. Try again:" << std::endl;
- continue;
- }
- if (challengeIndex < 0 || challengeIndex >= count) {
- std::cerr << "Your input index is out of range. Try again:" << std::endl;
- continue;
- }
- break;
+ getline(std::cin, choice);
+ try {
+ challengeIndex = std::stoul(choice);
+ }
+ catch (const std::exception& e) {
+ std::cerr << "Your input is not valid. Try again:" << std::endl;
+ continue;
+ }
+ if (challengeIndex >= count) {
+ std::cerr << "Your input index is out of range. Try again:" << std::endl;
+ continue;
+ }
+ break;
}
}
auto it = challengeList.begin();
@@ -195,24 +198,26 @@
}
static void
-InfoCb(const Data& reply)
+InfoCb(const Data& reply, const Name& certFullName)
{
- CaProfile profile;
+ boost::optional<CaProfile> profile;
try {
- auto profileOpt = Requester::onCaProfileResponse(reply);
- if (!profileOpt) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Invalid reply"));
+ if (certFullName.empty()) {
+ profile = Requester::onCaProfileResponse(reply);
}
- profile = *profileOpt;
- } catch(const std::exception& e) {
- std::cerr << "The fetched CA information cannot be used because: "<< e.what() << std::endl;
- return;
+ else {
+ profile = Requester::onCaProfileResponseAfterRedirection(reply, certFullName);
+ }
+ }
+ catch (const std::exception& e) {
+ std::cerr << "The fetched CA information cannot be used because: " << e.what() << std::endl;
+ return;
}
- std::cerr << "Will use a new trust anchor, please double check the identity info: \n"
+ std::cerr << "Will use a new trust anchor, please double check the identity info:" << std::endl
<< "This trust anchor information is signed by " << reply.getSignature().getKeyLocator()
<< std::endl
- << "The certificate is " << profile.m_cert << std::endl
+ << "The certificate is " << profile->m_cert << std::endl
<< "Do you trust the information? Type in YES or NO" << std::endl;
std::string answer;
@@ -220,7 +225,7 @@
boost::algorithm::to_lower(answer);
if (answer == "yes") {
std::cerr << "You answered YES: new CA will be used" << std::endl;
- runProbe(profile);
+ runProbe(*profile);
// client.getClientConf().save(std::string(SYSCONFDIR) + "/ndncert/client.conf");
}
else {
@@ -235,38 +240,45 @@
std::vector<Name> names;
std::vector<Name> redirects;
Requester::onProbeResponse(reply, profile, names, redirects);
- int count = 0;
- std::cerr << "Here is CA's suggested names: " << std::endl;
+ size_t count = 0;
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
+ << ": You can either select one of the following names suggested by the CA: " << std::endl;
for (const auto& name : names) {
- std::cerr << count ++ << ": " << name.toUri() << std::endl;
+ std::cerr << "> Index: " << count++ << std::endl
+ << ">> Suggested name: " << name.toUri() << std::endl;
}
- std::cerr << "Here is CA's suggested redirects to other CAs: " << std::endl;
+ std::cerr << "\nOr choose another trusted CA suggested by the CA: " << std::endl;
for (const auto& redirect : redirects) {
- std::cerr << count ++ << ": " << redirect.toUri() << std::endl;
+ std::cerr << "> Index: " << count++ << std::endl
+ << ">> Suggested CA: " << security::v2::extractIdentityFromCertName(redirect.getPrefix(-1)) << std::endl;
}
- int index;
+ std::cerr << "Please type in the index of your choice:" << std::endl;
+ size_t index = 0;
try {
std::string input;
getline(std::cin, input);
- index = std::stoi(input);
+ index = std::stoul(input);
}
catch (const std::exception& e) {
std::cerr << "Your input is Invalid. Exit" << std::endl;
exit(0);
}
- if (index < 0 || index >= names.size() + redirects.size()) {
+ if (index >= names.size() + redirects.size()) {
std::cerr << "Your input is not an existing index. Exit" << std::endl;
return;
}
if (index < names.size()) {
- //names
- std::cerr << "You selected name: " << names[index].toUri() << std::endl;
- runNew(profile, names[index]);
- } else {
- //redirects
- std::cerr << "You selected redirects with certificate: " << redirects[index - names.size()].toUri() << std::endl;
- face.expressInterest(*Requester::genCaProfileInterest(redirects[index - names.size()]),
- bind(&InfoCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ //names
+ std::cerr << "You selected name: " << names[index].toUri() << std::endl;
+ runNew(profile, names[index]);
+ }
+ else {
+ //redirects
+ auto redirectedCaName = redirects[index - names.size()];
+ std::cerr << "You selected redirects with certificate: " << redirectedCaName.getPrefix(-1).toUri() << std::endl;
+ face.expressInterest(*Requester::genCaProfileInterest(redirects[index - names.size()]),
+ bind(&InfoCb, _2, redirectedCaName), bind(&onNackCb), bind(&timeoutCb));
}
}
@@ -275,45 +287,44 @@
{
RequesterCaCache caCache;
try {
- caCache.load(configFilePath);
+ caCache.load(configFilePath);
}
catch (const std::exception& e) {
std::cerr << "Cannot load the configuration file: " << e.what() << std::endl;
exit(1);
}
- int count = 0;
+ size_t count = 0;
+ std::cerr << "***************************************\n"
+ << "Step " << nStep++ << ": CA SELECTION" << std::endl;
for (auto item : caCache.m_caItems) {
- std::cerr << "***************************************\n"
- << "Index: " << count++ << "\n"
- << "CA prefix:" << item.m_caPrefix << "\n"
- << "Introduction: " << item.m_caInfo << "\n"
- << "***************************************\n";
+ std::cerr << "> Index: " << count++ << std::endl
+ << ">> CA prefix:" << item.m_caPrefix << std::endl
+ << ">> Introduction: " << item.m_caInfo << std::endl;
}
- 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";
+ std::cerr << "Please type in the CA's index that you want to apply or type in NONE if your expected CA is not in the list:\n";
std::string caIndexS, caIndexSLower;
getline(std::cin, caIndexS);
caIndexSLower = caIndexS;
boost::algorithm::to_lower(caIndexSLower);
if (caIndexSLower == "none") {
- std::cerr << "Step " << nStep << ": Please type in the CA Name\n";
+ 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(*Requester::genCaProfileInterest(Name(expectedCAName)),
- bind(&InfoCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ bind(&InfoCb, _2, Name()), bind(&onNackCb), bind(&timeoutCb));
}
else {
- int caIndex;
+ size_t caIndex;
try {
- caIndex = std::stoi(caIndexS);
+ caIndex = std::stoul(caIndexS);
}
catch (const std::exception& e) {
std::cerr << "Your input is neither NONE nor a valid index. Exit" << std::endl;
return;
}
- if (caIndex < 0 || caIndex >= count) {
+ if (caIndex >= count) {
std::cerr << "Your input is not an existing index. Exit" << std::endl;
return;
}
@@ -324,48 +335,55 @@
}
}
-static void runProbe(CaProfile profile)
+static void
+runProbe(CaProfile profile)
{
- std::cerr << "Do you have the identity name already? Type in YES or NO" << std::endl;
- bool validAnswer = false;
- while (!validAnswer) {
- std::string answer;
- getline(std::cin, answer);
- boost::algorithm::to_lower(answer);
- if (answer == "yes") {
- validAnswer = true;
- std::cerr << "You answered YES: " << std::endl;
- std::cerr << "Step " << nStep++ << ": Please type in the full identity name you want to get (with CA prefix)\n";
- std::string identityNameStr;
- getline(std::cin, identityNameStr);
- runNew(profile, Name(identityNameStr));
- } else if (answer == "no") {
- validAnswer = true;
- std::cerr << "You answered NO: new CA will not be used" << std::endl;
- std::cerr << "Step " << nStep++ << ": Please provide information for name assignment" << std::endl;
- auto capturedParams = captureParams(profile.m_probeParameterKeys);
- face.expressInterest(*Requester::genProbeInterest(profile, std::move(capturedParams)),
- bind(&probeCb, _2, profile), bind(&onNackCb), bind(&timeoutCb));
- } else {
- std::cerr << "Invalid answer. Type in YES or NO" << std::endl;
- }
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++ << ": Do you have the identity name already? Type in YES or NO" << std::endl;
+ bool validAnswer = false;
+ while (!validAnswer) {
+ std::string answer;
+ getline(std::cin, answer);
+ boost::algorithm::to_lower(answer);
+ if (answer == "yes") {
+ validAnswer = true;
+ std::cerr << "You answered YES" << std::endl;
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++
+ << ": Please type in the full identity name you want to get (with CA prefix):" << std::endl;
+ std::string identityNameStr;
+ getline(std::cin, identityNameStr);
+ runNew(profile, Name(identityNameStr));
}
+ else if (answer == "no") {
+ validAnswer = true;
+ std::cerr << "You answered NO" << std::endl;
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep++ << ": Please provide information for name assignment" << std::endl;
+ auto capturedParams = captureParams(profile.m_probeParameterKeys);
+ face.expressInterest(*Requester::genProbeInterest(profile, std::move(capturedParams)),
+ bind(&probeCb, _2, profile), bind(&onNackCb), bind(&timeoutCb));
+ }
+ else {
+ std::cerr << "Invalid answer. Type in YES or NO" << std::endl;
+ }
+ }
}
static void
runNew(CaProfile profile, Name identityName)
{
- int validityPeriod = captureValidityPeriod();
- auto now = time::system_clock::now();
- std::cerr << "The validity period of your certificate will be: " << validityPeriod << " hours" << std::endl;
- requesterState = make_shared<RequesterState>(keyChain, profile, RequestType::NEW);
- auto interest = Requester::genNewInterest(*requesterState, identityName, now, now + time::hours(validityPeriod));
- if (interest != nullptr) {
- face.expressInterest(*interest, bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
- }
- else {
- std::cerr << "Cannot generate the Interest for NEW step. Exit" << std::endl;
- }
+ int validityPeriod = captureValidityPeriod();
+ auto now = time::system_clock::now();
+ std::cerr << "The validity period of your certificate will be: " << validityPeriod << " hours" << std::endl;
+ requesterState = make_shared<RequesterState>(keyChain, profile, RequestType::NEW);
+ auto interest = Requester::genNewInterest(*requesterState, identityName, now, now + time::hours(validityPeriod));
+ if (interest != nullptr) {
+ face.expressInterest(*interest, bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
+ }
+ else {
+ std::cerr << "Cannot generate the Interest for NEW step. Exit" << std::endl;
+ }
}
static void
@@ -373,19 +391,13 @@
{
auto requirement = Requester::selectOrContinueChallenge(*requesterState, challengeType);
if (requirement.size() > 0) {
- std::cerr << "Step " << nStep++ << ": Please provide parameters used for Identity Verification Challenge\n";
- captureParams(requirement);
+ std::cerr << "\n***************************************\n"
+ << "Step " << nStep
+ << ": Please provide parameters used for Identity Verification Challenge" << std::endl;
+ captureParams(requirement);
}
face.expressInterest(*Requester::genChallengeInterest(*requesterState, std::move(requirement)),
- bind(&challengeCb, _2), bind(&onNackCb), bind(&timeoutCb));
-
-}
-
-
-static void
-startApplication(std::string configFilePath)
-{
- selectCaProfile(configFilePath);
+ bind(&challengeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}
static void
@@ -421,9 +433,7 @@
namespace po = boost::program_options;
std::string configFilePath = std::string(SYSCONFDIR) + "/ndncert/client.conf";
po::options_description description("General Usage\n ndncert-client [-h] [-c] [-v]\n");
- description.add_options()
- ("help,h", "produce help message")
- ("config-file,c", po::value<std::string>(&configFilePath), "configuration file name");
+ description.add_options()("help,h", "produce help message")("config-file,c", po::value<std::string>(&configFilePath), "configuration file name");
po::positional_options_description p;
po::variables_map vm;
@@ -439,7 +449,7 @@
std::cerr << description << std::endl;
return 0;
}
- startApplication(configFilePath);
+ selectCaProfile(configFilePath);
face.processEvents();
return 0;
}