remove JSON parameter list from challenge module and add unified return interfaces for challenge modules
Change-Id: I0e69f7f8ef2ea36f38f11815aa980928b049cdc7
diff --git a/src/ca-config.cpp b/src/ca-config.cpp
index e6ab0f6..c8bc298 100644
--- a/src/ca-config.cpp
+++ b/src/ca-config.cpp
@@ -97,7 +97,7 @@
if (challengeType == "") {
BOOST_THROW_EXCEPTION(std::runtime_error("Cannot read type in supported-challenges from the config file"));
}
- if (!ChallengeModule::supportChallenge(challengeType)) {
+ if (!ChallengeModule::isChallengeSupported(challengeType)) {
BOOST_THROW_EXCEPTION(std::runtime_error("Does not support challenge read from the config file"));
}
m_supportedChallenges.push_back(challengeType);
diff --git a/src/challenge-module.cpp b/src/challenge-module.cpp
index 9288330..47dca5d 100644
--- a/src/challenge-module.cpp
+++ b/src/challenge-module.cpp
@@ -32,7 +32,7 @@
ChallengeModule::~ChallengeModule() = default;
bool
-ChallengeModule::supportChallenge(const std::string& challengeType)
+ChallengeModule::isChallengeSupported(const std::string& challengeType)
{
ChallengeFactory& factory = getFactory();
auto i = factory.find(challengeType);
@@ -70,16 +70,45 @@
return result;
}
-void
-ChallengeModule::updateRequestOnChallengeEnd(CertificateRequest& request)
+std::tuple<Error, std::string>
+ChallengeModule::returnWithError(CertificateRequest& request, Error errorCode, std::string&& errorInfo)
{
+ request.m_status = Status::FAILURE;
+ request.m_challengeType = "";
+ request.m_challengeStatus = "";
request.m_challengeSecrets = JsonSection();
request.m_challengeTp = "";
- request.m_challengeType = "";
request.m_remainingTime = 0;
request.m_remainingTries = 0;
+ return std::make_tuple(errorCode, std::move(errorInfo));
}
+std::tuple<Error, std::string>
+ChallengeModule::returnWithNewChallengeStatus(CertificateRequest& request, const std::string& challengeStatus,
+ JsonSection&& challengeSecret, size_t remainingTries, size_t remainingTime)
+{
+ request.m_status = Status::CHALLENGE;
+ request.m_challengeType = CHALLENGE_TYPE;
+ request.m_challengeStatus = std::move(challengeStatus);
+ request.m_challengeSecrets = std::move(challengeSecret);
+ request.m_challengeTp = time::toIsoString(time::system_clock::now());
+ request.m_remainingTime = remainingTries;
+ request.m_remainingTries = remainingTime;
+ return std::make_tuple(Error::NO_ERROR, "");
+}
+
+std::tuple<Error, std::string>
+ChallengeModule::returnWithSuccess(CertificateRequest& request)
+{
+ request.m_status = Status::PENDING;
+ request.m_challengeType = CHALLENGE_TYPE;
+ request.m_challengeStatus = "";
+ request.m_challengeSecrets = JsonSection();
+ request.m_challengeTp = "";
+ request.m_remainingTime = 0;
+ request.m_remainingTries = 0;
+ return std::make_tuple(Error::NO_ERROR, "");
+}
} // namespace ndncert
} // namespace ndn
diff --git a/src/challenge-module.hpp b/src/challenge-module.hpp
index fb687e1..660ff15 100644
--- a/src/challenge-module.hpp
+++ b/src/challenge-module.hpp
@@ -21,35 +21,21 @@
#ifndef NDNCERT_CHALLENGE_MODULE_HPP
#define NDNCERT_CHALLENGE_MODULE_HPP
-#include "ndncert-common.hpp"
+#include <tuple>
+
#include "certificate-request.hpp"
+#include "ndncert-common.hpp"
namespace ndn {
namespace ndncert {
-class ChallengeModule : noncopyable
-{
+class ChallengeModule : noncopyable {
public:
- /**
- * @brief Error that can be thrown from ChallengeModule
- *
- * ChallengeModule should throw Error to notice CA there's an Error. In this case, CA will
- * generate an Error JSON file back to end entity.
- */
- class Error : public std::runtime_error
- {
- public:
- using std::runtime_error::runtime_error;
- };
+ explicit ChallengeModule(const std::string& uniqueType);
-public:
- explicit
- ChallengeModule(const std::string& uniqueType);
+ virtual ~ChallengeModule();
- virtual
- ~ChallengeModule();
-
- template<class ChallengeType>
+ template <class ChallengeType>
static void
registerChallengeModule(const std::string& typeName)
{
@@ -59,56 +45,60 @@
}
static bool
- supportChallenge(const std::string& challengeType);
+ isChallengeSupported(const std::string& challengeType);
static unique_ptr<ChallengeModule>
createChallengeModule(const std::string& challengeType);
// For CA
- virtual void
+ virtual std::tuple<Error, std::string>
handleChallengeRequest(const Block& params, CertificateRequest& request) = 0;
// For Client
- virtual JsonSection
- getRequirementForChallenge(Status status, const std::string& challengeStatus) = 0;
-
- virtual JsonSection
- genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params) = 0;
+ virtual std::vector<std::tuple<std::string, std::string>>
+ getRequestedParameterList(Status status, const std::string& challengeStatus) = 0;
virtual Block
- genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params) = 0;
+ genChallengeRequestTLV(Status status, const std::string& challengeStatus,
+ std::vector<std::tuple<std::string, std::string>>&& params) = 0;
// helpers
static std::string
generateSecretCode();
protected:
+ // used by challenge modules
+ std::tuple<Error, std::string>
+ returnWithError(CertificateRequest& request, Error errorCode, std::string&& errorInfo);
- void
- updateRequestOnChallengeEnd(CertificateRequest& request);
+ std::tuple<Error, std::string>
+ returnWithNewChallengeStatus(CertificateRequest& request, const std::string& challengeStatus,
+ JsonSection&& challengeSecret, size_t remainingTries, size_t remainingTime);
+
+ std::tuple<Error, std::string>
+ returnWithSuccess(CertificateRequest& request);
public:
const std::string CHALLENGE_TYPE;
private:
- typedef function<unique_ptr<ChallengeModule> ()> ChallengeCreateFunc;
+ typedef function<unique_ptr<ChallengeModule>()> ChallengeCreateFunc;
typedef std::map<std::string, ChallengeCreateFunc> ChallengeFactory;
static ChallengeFactory&
getFactory();
};
-#define NDNCERT_REGISTER_CHALLENGE(C, T) \
-static class NdnCert ## C ## ChallengeRegistrationClass \
-{ \
-public: \
- NdnCert ## C ## ChallengeRegistrationClass() \
- { \
- ::ndn::ndncert::ChallengeModule::registerChallengeModule<C>(T);\
- } \
-} g_NdnCert ## C ## ChallengeRegistrationVariable
+#define NDNCERT_REGISTER_CHALLENGE(C, T) \
+ static class NdnCert##C##ChallengeRegistrationClass { \
+ public: \
+ NdnCert##C##ChallengeRegistrationClass() \
+ { \
+ ::ndn::ndncert::ChallengeModule::registerChallengeModule<C>(T); \
+ } \
+ } g_NdnCert##C##ChallengeRegistrationVariable
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
-#endif // NDNCERT_CHALLENGE_MODULE_HPP
+#endif // NDNCERT_CHALLENGE_MODULE_HPP
diff --git a/src/challenge-module/challenge-credential.cpp b/src/challenge-module/challenge-credential.cpp
index da24fef..fe120eb 100644
--- a/src/challenge-module/challenge-credential.cpp
+++ b/src/challenge-module/challenge-credential.cpp
@@ -28,15 +28,11 @@
namespace ndn {
namespace ndncert {
-_LOG_INIT(ndncert.ChallengeCredential);
-
+_LOG_INIT(ndncert.challenge.credential);
NDNCERT_REGISTER_CHALLENGE(ChallengeCredential, "Credential");
-const std::string ChallengeCredential::FAILURE_INVALID_FORMAT_CREDENTIAL = "failure-cannot-parse-credential";
-const std::string ChallengeCredential::FAILURE_INVALID_FORMAT_SELF_SIGNED = "failure-cannot-parse-self-signed";
-const std::string ChallengeCredential::FAILURE_INVALID_CREDENTIAL = "failure-invalid-credential";
-const std::string ChallengeCredential::JSON_CREDENTIAL_CERT = "issued-cert";
-const std::string ChallengeCredential::JSON_PROOF_OF_PRIVATE_KEY = "proof-of-private-key";
+const std::string ChallengeCredential::PARAMETER_KEY_CREDENTIAL_CERT = "issued-cert";
+const std::string ChallengeCredential::PARAMETER_KEY_PROOF_OF_PRIVATE_KEY = "proof-of-private-key";
ChallengeCredential::ChallengeCredential(const std::string& configPath)
: ChallengeModule("Credential")
@@ -57,12 +53,12 @@
boost::property_tree::read_json(m_configFile, config);
}
catch (const boost::property_tree::info_parser_error& error) {
- BOOST_THROW_EXCEPTION(Error("Failed to parse configuration file " + m_configFile +
- " " + error.message() + " line " + std::to_string(error.line())));
+ BOOST_THROW_EXCEPTION(std::runtime_error("Failed to parse configuration file " + m_configFile +
+ " " + error.message() + " line " + std::to_string(error.line())));
}
if (config.begin() == config.end()) {
- BOOST_THROW_EXCEPTION(Error("Error processing configuration file: " + m_configFile + " no data"));
+ BOOST_THROW_EXCEPTION(std::runtime_error("Error processing configuration file: " + m_configFile + " no data"));
}
m_trustAnchors.clear();
@@ -80,7 +76,7 @@
}
// For CA
-void
+std::tuple<Error, std::string>
ChallengeCredential::handleChallengeRequest(const Block& params, CertificateRequest& request)
{
params.parse();
@@ -91,26 +87,20 @@
auto& elements = params.elements();
for (size_t i = 0; i < elements.size(); i++) {
if (elements[i].type() == tlv_parameter_key) {
- if (readString(elements[i]) == JSON_CREDENTIAL_CERT) {
+ if (readString(elements[i]) == PARAMETER_KEY_CREDENTIAL_CERT) {
std::istringstream ss(readString(params.elements()[i + 1]));
credential = io::load<security::v2::Certificate>(ss);
if (credential == nullptr) {
- _LOG_ERROR("Cannot load credential parameter: cert");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_FORMAT_CREDENTIAL;
- updateRequestOnChallengeEnd(request);
- return;
+ _LOG_ERROR("Cannot load challenge parameter: credential");
+ return returnWithError(request, Error::INVALID_PARAMETER, "Cannot challenge credential: credential.");
}
}
- else if (readString(elements[i]) == JSON_PROOF_OF_PRIVATE_KEY) {
+ else if (readString(elements[i]) == PARAMETER_KEY_PROOF_OF_PRIVATE_KEY) {
std::istringstream ss(readString(params.elements()[i + 1]));
selfSigned = io::load<security::v2::Certificate>(ss);
if (selfSigned == nullptr) {
- _LOG_ERROR("Cannot load credential parameter: cert");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_FORMAT_SELF_SIGNED;
- updateRequestOnChallengeEnd(request);
- return;
+ _LOG_ERROR("Cannot load challenge parameter: proof of private key");
+ return returnWithError(request, Error::INVALID_PARAMETER, "Cannot load challenge parameter: proof of private key.");
}
}
else {
@@ -126,63 +116,56 @@
if (security::verifySignature(*selfSigned, anchor) &&
security::verifySignature(*selfSigned, *credential) &&
readString(selfSigned->getContent()) == request.m_requestId) {
- request.m_status = Status::PENDING;
- request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
- updateRequestOnChallengeEnd(request);
- return;
+ return returnWithSuccess(request);
}
}
}
- _LOG_TRACE("Cannot verify the credential + self-signed Data + data content");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_CREDENTIAL;
- updateRequestOnChallengeEnd(request);
- return;
+ _LOG_TRACE("Cannot verify the proof of private key against credential");
+ return returnWithError(request, Error::INVALID_PARAMETER, "Cannot verify the proof of private key against credential.");
}
// For Client
-JsonSection
-ChallengeCredential::getRequirementForChallenge(Status status, const std::string& challengeStatus)
+std::vector<std::tuple<std::string, std::string>>
+ChallengeCredential::getRequestedParameterList(Status status, const std::string& challengeStatus)
{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_CREDENTIAL_CERT, "Please_copy_anchor_signed_cert_here");
- result.put(JSON_PROOF_OF_PRIVATE_KEY, "Please_copy_key_signed_request_id_data_here");
+ std::vector<std::tuple<std::string, std::string>> result;
+ if (status == Status::BEFORE_CHALLENGE) {
+ result.push_back(std::make_tuple(PARAMETER_KEY_CREDENTIAL_CERT, "Please provide the certificate issued by a trusted CA."));
+ result.push_back(std::make_tuple(PARAMETER_KEY_PROOF_OF_PRIVATE_KEY, "Please sign a Data packet with request ID as the content."));
}
else {
- _LOG_ERROR("Client's status and challenge status are wrong");
- }
- return result;
-}
-
-JsonSection
-ChallengeCredential::genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params)
-{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_CREDENTIAL_CERT, params.get(JSON_CREDENTIAL_CERT, ""));
- result.put(JSON_PROOF_OF_PRIVATE_KEY, params.get(JSON_PROOF_OF_PRIVATE_KEY, ""));
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
return result;
}
Block
-ChallengeCredential::genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params)
+ChallengeCredential::genChallengeRequestTLV(Status status, const std::string& challengeStatus,
+ std::vector<std::tuple<std::string, std::string>>&& params)
{
Block request = makeEmptyBlock(tlv_encrypted_payload);
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
+ if (status == Status::BEFORE_CHALLENGE) {
+ if (params.size() != 2) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
+ }
request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_CREDENTIAL_CERT));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CREDENTIAL_CERT, "")));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_PROOF_OF_PRIVATE_KEY));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PROOF_OF_PRIVATE_KEY, "")));
+ for (const auto& item : params) {
+ if (std::get<0>(item) == PARAMETER_KEY_CREDENTIAL_CERT) {
+ request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_CREDENTIAL_CERT));
+ request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(item)));
+ }
+ else if (std::get<0>(item) == PARAMETER_KEY_PROOF_OF_PRIVATE_KEY) {
+ request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_PROOF_OF_PRIVATE_KEY));
+ request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(item)));
+ }
+ else {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
+ }
+ }
}
else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
request.encode();
return request;
diff --git a/src/challenge-module/challenge-credential.hpp b/src/challenge-module/challenge-credential.hpp
index c0e0e48..2afe38e 100644
--- a/src/challenge-module/challenge-credential.hpp
+++ b/src/challenge-module/challenge-credential.hpp
@@ -52,31 +52,26 @@
ChallengeCredential(const std::string& configPath = "");
// For CA
- void
+ std::tuple<Error, std::string>
handleChallengeRequest(const Block& params, CertificateRequest& request) override;
// For Client
- JsonSection
- getRequirementForChallenge(Status status, const std::string& challengeStatus) override;
-
- JsonSection
- genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ std::vector<std::tuple<std::string, std::string>>
+ getRequestedParameterList(Status status, const std::string& challengeStatus) override;
Block
- genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ genChallengeRequestTLV(Status status, const std::string& challengeStatus,
+ std::vector<std::tuple<std::string, std::string>>&& params) override;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
parseConfigFile();
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- static const std::string FAILURE_INVALID_CREDENTIAL;
- static const std::string FAILURE_INVALID_FORMAT_CREDENTIAL;
- static const std::string FAILURE_INVALID_FORMAT_SELF_SIGNED;
- static const std::string JSON_CREDENTIAL_CERT;
- static const std::string JSON_PROOF_OF_PRIVATE_KEY;
+ // parameters
+ static const std::string PARAMETER_KEY_CREDENTIAL_CERT;
+ static const std::string PARAMETER_KEY_PROOF_OF_PRIVATE_KEY;
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
std::list<security::v2::Certificate> m_trustAnchors;
std::string m_configFile;
};
diff --git a/src/challenge-module/challenge-email.cpp b/src/challenge-module/challenge-email.cpp
index cd08d9b..7e0134a 100644
--- a/src/challenge-module/challenge-email.cpp
+++ b/src/challenge-module/challenge-email.cpp
@@ -19,187 +19,130 @@
*/
#include "challenge-email.hpp"
+
+#include <regex>
+
#include "../ca-module.hpp"
#include "../logging.hpp"
-#include <regex>
namespace ndn {
namespace ndncert {
-_LOG_INIT(ndncert.ChallengeEmail);
-
+_LOG_INIT(ndncert.challenge.email);
NDNCERT_REGISTER_CHALLENGE(ChallengeEmail, "email");
const std::string ChallengeEmail::NEED_CODE = "need-code";
const std::string ChallengeEmail::WRONG_CODE = "wrong-code";
-const std::string ChallengeEmail::FAILURE_INVALID_EMAIL = "failure-invalid-email";
-const std::string ChallengeEmail::JSON_EMAIL = "email";
-const std::string ChallengeEmail::JSON_CODE = "code";
+const std::string ChallengeEmail::PARAMETER_KEY_EMAIL = "email";
+const std::string ChallengeEmail::PARAMETER_KEY_CODE = "code";
ChallengeEmail::ChallengeEmail(const std::string& scriptPath,
const size_t& maxAttemptTimes,
const time::seconds secretLifetime)
- : ChallengeModule("email")
- , m_sendEmailScript(scriptPath)
- , m_maxAttemptTimes(maxAttemptTimes)
- , m_secretLifetime(secretLifetime)
+ : ChallengeModule("email")
+ , m_sendEmailScript(scriptPath)
+ , m_maxAttemptTimes(maxAttemptTimes)
+ , m_secretLifetime(secretLifetime)
{
}
// For CA
-void
+std::tuple<Error, std::string>
ChallengeEmail::handleChallengeRequest(const Block& params, CertificateRequest& request)
{
params.parse();
auto currentTime = time::system_clock::now();
- if (request.m_challengeStatus == "") {
+ if (request.m_status == Status::BEFORE_CHALLENGE) {
// for the first time, init the challenge
std::string emailAddress = readString(params.get(tlv_parameter_value));
if (!isValidEmailAddress(emailAddress)) {
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_EMAIL;
- return;
+ return returnWithError(request, Error::INVALID_PARAMETER, "Invalid email address format.");
}
- // check whether this email is the same as the one used in PROBE
- if (request.m_probeToken != nullptr) {
- const auto& content = request.m_probeToken->getContent();
- const auto& json = CaModule::jsonFromBlock(content);
- const auto& expectedEmail = json.get("email", "");
- Name expectedPrefix(json.get(JSON_CA_NAME, ""));
- if (expectedEmail != emailAddress || !expectedPrefix.isPrefixOf(request.m_cert.getName())) {
- _LOG_ERROR("Cannot match with the PROBE token. Input email: " << emailAddress
- << " Email in Token: " << expectedEmail
- << " Requested Cert Name: " << request.m_cert.getName()
- << " Identity Name got from Token: " << expectedPrefix);
- return;
- }
+ auto lastComponentRequested = readString(request.m_cert.getIdentity().get(-1));
+ if (lastComponentRequested != emailAddress) {
+ _LOG_TRACE("Email and requested name do not match. Email " << emailAddress << "requested last component " << lastComponentRequested);
}
- request.m_status = Status::CHALLENGE;
- request.m_challengeStatus = NEED_CODE;
- request.m_challengeType = CHALLENGE_TYPE;
std::string emailCode = generateSecretCode();
JsonSection secretJson;
- secretJson.add(JSON_CODE, emailCode);
- request.m_challengeSecrets = secretJson;
- request.m_challengeTp = time::toIsoString(currentTime);
- request.m_remainingTime = m_secretLifetime.count();
- request.m_remainingTries = m_maxAttemptTimes;
+ secretJson.add(PARAMETER_KEY_CODE, emailCode);
// send out the email
sendEmail(emailAddress, emailCode, request);
_LOG_TRACE("Secret for request " << request.m_requestId << " : " << emailCode);
- return;
+ return returnWithNewChallengeStatus(request, NEED_CODE, std::move(secretJson), m_maxAttemptTimes, m_secretLifetime.count());
}
- else if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
+
+ if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
_LOG_TRACE("Challenge Interest arrives. Challenge Status: " << request.m_challengeStatus);
// the incoming interest should bring the pin code
std::string givenCode = readString(params.get(tlv_parameter_value));
- const auto realCode = request.m_challengeSecrets.get<std::string>(JSON_CODE);
+ auto secret = request.m_challengeSecrets;
+ // check if run out of time
if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
- // secret expires
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_TIMEOUT;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("Secret expired. Challenge failed.");
- return;
+ return returnWithError(request, Error::OUT_OF_TIME, "Secret expired.");
}
- else if (givenCode == realCode) {
+ // check if provided secret is correct
+ if (givenCode == secret.get<std::string>(PARAMETER_KEY_CODE)) {
// the code is correct
- request.m_status = Status::PENDING;
- request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("Secret code matched. Challenge succeeded.");
- return;
+ _LOG_TRACE("Correct secret code. Challenge succeeded.");
+ return returnWithSuccess(request);
+ }
+ // otherwise, check remaining attempt times
+ if (request.m_remainingTries > 1) {
+ auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
+ _LOG_TRACE("Wrong secret code provided. Remaining Tries - 1.");
+ return returnWithNewChallengeStatus(request, WRONG_CODE, std::move(secret), request.m_remainingTries - 1, remainTime.count());
}
else {
- // check rest attempt times
- if (request.m_remainingTries > 1) {
- request.m_challengeStatus = WRONG_CODE;
- request.m_remainingTries = request.m_remainingTries - 1;
- auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
- request.m_remainingTime = remainTime.count();
- _LOG_TRACE("Secret code didn't match. Remaining Tries - 1.");
- return;
- }
- else {
- // run out times
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_MAXRETRY;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("Secret code didn't match. Ran out tires. Challenge failed.");
- return;
- }
+ // run out times
+ _LOG_TRACE("Wrong secret code provided. Ran out tires. Challenge failed.");
+ return returnWithError(request, Error::OUT_OF_TRIES, "Ran out tires.");
}
}
- else {
- _LOG_ERROR("The challenge status is wrong");
- request.m_status = Status::FAILURE;
- return;
- }
+ return returnWithError(request, Error::INVALID_PARAMETER, "Unexpected status or challenge status");
}
// For Client
-JsonSection
-ChallengeEmail::getRequirementForChallenge(Status status, const std::string& challengeStatus)
+std::vector<std::tuple<std::string, std::string>>
+ChallengeEmail::getRequestedParameterList(Status status, const std::string& challengeStatus)
{
- JsonSection result;
+ std::vector<std::tuple<std::string, std::string>> result;
if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_EMAIL, "Please_input_your_email_address");
+ result.push_back(std::make_tuple(PARAMETER_KEY_EMAIL, "Please input your email address"));
}
else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
- result.put(JSON_CODE, "Please_input_your_verification_code");
+ result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Please input your verification code"));
}
else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- result.put(JSON_CODE, "Incorrect_code_please_try_again");
+ result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Incorrect code, please try again"));
}
else {
- _LOG_ERROR("CA's status and challenge status are wrong");
- }
- return result;
-}
-
-JsonSection
-ChallengeEmail::genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params)
-{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- result.put(JSON_EMAIL, params.get(JSON_EMAIL, ""));
- }
- else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- result.put(JSON_CODE, params.get(JSON_CODE, ""));
- }
- else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- result.put(JSON_CODE, params.get(JSON_CODE, ""));
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
return result;
}
Block
-ChallengeEmail::genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params)
+ChallengeEmail::genChallengeRequestTLV(Status status, const std::string& challengeStatus, std::vector<std::tuple<std::string, std::string>>&& params)
{
Block request = makeEmptyBlock(tlv_encrypted_payload);
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
+ if (status == Status::BEFORE_CHALLENGE) {
+ if (params.size() != 1 || std::get<0>(params[0]) != PARAMETER_KEY_EMAIL) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
+ }
request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_EMAIL));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_EMAIL,"")));
+ request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_EMAIL));
+ request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(params[0])));
}
- else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
+ else if (status == Status::CHALLENGE && (challengeStatus == NEED_CODE || challengeStatus == WRONG_CODE)) {
+ if (params.size() != 1 || std::get<0>(params[0]) != PARAMETER_KEY_CODE) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
+ }
request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
- }
- else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
+ request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_CODE));
+ request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(params[0])));
}
else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
request.encode();
return request;
@@ -218,8 +161,7 @@
const CertificateRequest& request) const
{
std::string command = m_sendEmailScript;
- command += " \"" + emailAddress + "\" \"" + secret + "\" \""
- + request.m_caPrefix.toUri() + "\" \"" + request.m_cert.getName().toUri() + "\"";
+ command += " \"" + emailAddress + "\" \"" + secret + "\" \"" + request.m_caPrefix.toUri() + "\" \"" + request.m_cert.getName().toUri() + "\"";
int result = system(command.c_str());
if (result == -1) {
_LOG_TRACE("EmailSending Script " + m_sendEmailScript + " fails.");
@@ -229,5 +171,5 @@
return;
}
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/challenge-module/challenge-email.hpp b/src/challenge-module/challenge-email.hpp
index b43a3de..f148d06 100644
--- a/src/challenge-module/challenge-email.hpp
+++ b/src/challenge-module/challenge-email.hpp
@@ -58,18 +58,16 @@
const time::seconds secretLifetime = time::minutes(20));
// For CA
- void
+ std::tuple<Error, std::string>
handleChallengeRequest(const Block& params, CertificateRequest& request) override;
// For Client
- JsonSection
- getRequirementForChallenge(Status status, const std::string& challengeStatus) override;
-
- JsonSection
- genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ std::vector<std::tuple<std::string, std::string>>
+ getRequestedParameterList(Status status, const std::string& challengeStatus) override;
Block
- genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ genChallengeRequestTLV(Status status, const std::string& challengeStatus,
+ std::vector<std::tuple<std::string, std::string>>&& params) override;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
static bool
@@ -83,10 +81,9 @@
// challenge status
static const std::string NEED_CODE;
static const std::string WRONG_CODE;
- static const std::string FAILURE_INVALID_EMAIL;
- // JSON attribute
- static const std::string JSON_EMAIL;
- static const std::string JSON_CODE;
+ // parameters
+ static const std::string PARAMETER_KEY_EMAIL;
+ static const std::string PARAMETER_KEY_CODE;
private:
std::string m_sendEmailScript;
diff --git a/src/challenge-module/challenge-pin.cpp b/src/challenge-module/challenge-pin.cpp
index 55b9435..cd20c51 100644
--- a/src/challenge-module/challenge-pin.cpp
+++ b/src/challenge-module/challenge-pin.cpp
@@ -19,162 +19,111 @@
*/
#include "challenge-pin.hpp"
-#include "logging.hpp"
+
#include <ndn-cxx/util/random.hpp>
+#include "logging.hpp"
+
namespace ndn {
namespace ndncert {
-_LOG_INIT(ndncert.challenge-pin);
-
+_LOG_INIT(ndncert.challenge.pin);
NDNCERT_REGISTER_CHALLENGE(ChallengePin, "pin");
const std::string ChallengePin::NEED_CODE = "need-code";
const std::string ChallengePin::WRONG_CODE = "wrong-code";
-const std::string ChallengePin::JSON_PIN_CODE = "pin-code";
+const std::string ChallengePin::PARAMETER_KEY_CODE = "pin-code";
ChallengePin::ChallengePin(const size_t& maxAttemptTimes, const time::seconds& secretLifetime)
- : ChallengeModule("pin")
- , m_secretLifetime(secretLifetime)
- , m_maxAttemptTimes(maxAttemptTimes)
+ : ChallengeModule("pin")
+ , m_secretLifetime(secretLifetime)
+ , m_maxAttemptTimes(maxAttemptTimes)
{
}
// For CA
-void
+std::tuple<Error, std::string>
ChallengePin::handleChallengeRequest(const Block& params, CertificateRequest& request)
{
params.parse();
auto currentTime = time::system_clock::now();
- if (request.m_challengeStatus == "") {
+ if (request.m_status == Status::BEFORE_CHALLENGE) {
_LOG_TRACE("Challenge Interest arrives. Init the challenge");
// for the first time, init the challenge
- request.m_status = Status::CHALLENGE;
- request.m_challengeStatus = NEED_CODE;
- request.m_challengeType = CHALLENGE_TYPE;
std::string secretCode = generateSecretCode();
JsonSection secretJson;
- secretJson.add(JSON_PIN_CODE, secretCode);
- request.m_challengeSecrets = secretJson;
- request.m_challengeTp = time::toIsoString(currentTime);
- request.m_remainingTime = m_secretLifetime.count();
- request.m_remainingTries = m_maxAttemptTimes;
+ secretJson.add(PARAMETER_KEY_CODE, secretCode);
_LOG_TRACE("Secret for request " << request.m_requestId << " : " << secretCode);
- return;
+ return returnWithNewChallengeStatus(request, NEED_CODE, std::move(secretJson), m_maxAttemptTimes, m_secretLifetime.count());
}
- else if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
+
+ if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
_LOG_TRACE("Challenge Interest arrives. Challenge Status: " << request.m_challengeStatus);
// the incoming interest should bring the pin code
std::string givenCode = readString(params.get(tlv_parameter_value));
- const auto realCode = request.m_challengeSecrets.get<std::string>(JSON_PIN_CODE);
+ auto secret = request.m_challengeSecrets;
if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
- // secret expires
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_TIMEOUT;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("Secret expired. Challenge failed.");
- return;
+ return returnWithError(request, Error::OUT_OF_TIME, "Secret expired.");
}
- else if (givenCode == realCode) {
- // the code is correct
- request.m_status = Status::PENDING;
- request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("PIN code matched. Challenge succeeded.");
- return;
+ if (givenCode == secret.get<std::string>(PARAMETER_KEY_CODE)) {
+ _LOG_TRACE("Correct PIN code. Challenge succeeded.");
+ return returnWithSuccess(request);
+ }
+ // check rest attempt times
+ if (request.m_remainingTries > 1) {
+ auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
+ _LOG_TRACE("Wrong PIN code provided. Remaining Tries - 1.");
+ return returnWithNewChallengeStatus(request, WRONG_CODE, std::move(secret), request.m_remainingTries - 1, remainTime.count());
}
else {
- // check rest attempt times
- if (request.m_remainingTries > 1) {
- request.m_challengeStatus = WRONG_CODE;
- request.m_remainingTries = request.m_remainingTries - 1;
- auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
- request.m_remainingTime = remainTime.count();
- _LOG_TRACE("PIN code didn't match. Remaining Tries - 1.");
- return;
- }
- else {
- // run out times
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_MAXRETRY;
- updateRequestOnChallengeEnd(request);
- _LOG_TRACE("PIN code didn't match. Ran out tires. Challenge failed.");
- return;
- }
+ // run out times
+ _LOG_TRACE("Wrong PIN code provided. Ran out tires. Challenge failed.");
+ return returnWithError(request, Error::OUT_OF_TRIES, "Ran out tires.");
}
}
- else {
- _LOG_ERROR("The challenge status is wrong");
- request.m_status = Status::FAILURE;
- return;
- }
+ return returnWithError(request, Error::INVALID_PARAMETER, "Unexpected status or challenge status");
}
// For Client
-JsonSection
-ChallengePin::getRequirementForChallenge(Status status, const std::string& challengeStatus)
+std::vector<std::tuple<std::string, std::string>>
+ChallengePin::getRequestedParameterList(Status status, const std::string& challengeStatus)
{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
+ std::vector<std::tuple<std::string, std::string>> result;
+ if (status == Status::BEFORE_CHALLENGE) {
// do nothing
}
else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
- result.put(JSON_PIN_CODE, "Please_input_your_verification_code");
+ result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Please input your PIN code"));
}
else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- result.put(JSON_PIN_CODE, "Incorrect_PIN_code_please_try_again");
+ result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Incorrect PIN code, please try again"));
}
else {
- _LOG_ERROR("Client's status and challenge status are wrong");
- }
- return result;
-}
-
-JsonSection
-ChallengePin::genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params)
-{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- // do nothing
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- }
- else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- result.put(JSON_PIN_CODE, params.get(JSON_PIN_CODE, ""));
- }
- else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
- result.put(JSON_PIN_CODE, params.get(JSON_PIN_CODE, ""));
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
return result;
}
Block
-ChallengePin::genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params)
+ChallengePin::genChallengeRequestTLV(Status status, const std::string& challengeStatus, std::vector<std::tuple<std::string, std::string>>&& params)
{
Block request = makeEmptyBlock(tlv_encrypted_payload);
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- // do nothing
+ if (status == Status::BEFORE_CHALLENGE) {
request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
}
- else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
+ else if (status == Status::CHALLENGE && (challengeStatus == NEED_CODE || challengeStatus == WRONG_CODE)) {
+ if (params.size() != 1 || std::get<0>(params[0]) != PARAMETER_KEY_CODE) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
+ }
request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_PIN_CODE));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PIN_CODE,"")));
- }
- else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
- request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_PIN_CODE));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PIN_CODE,"")));
+ request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_CODE));
+ request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(params[0])));
}
else {
- _LOG_ERROR("Client's status and challenge status are wrong");
+ BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
}
request.encode();
return request;
}
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/challenge-module/challenge-pin.hpp b/src/challenge-module/challenge-pin.hpp
index 44db7d8..88cf9bd 100644
--- a/src/challenge-module/challenge-pin.hpp
+++ b/src/challenge-module/challenge-pin.hpp
@@ -52,26 +52,24 @@
const time::seconds& secretLifetime = time::seconds(3600));
// For CA
- void
+ std::tuple<Error, std::string>
handleChallengeRequest(const Block& params, CertificateRequest& request) override;
// For Client
- JsonSection
- getRequirementForChallenge(Status status, const std::string& challengeStatus) override;
-
- JsonSection
- genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ std::vector<std::tuple<std::string, std::string>>
+ getRequestedParameterList(Status status, const std::string& challengeStatus) override;
Block
- genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params) override;
+ genChallengeRequestTLV(Status status, const std::string& challengeStatus,
+ std::vector<std::tuple<std::string, std::string>>&& params) override;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
// challenge status
static const std::string NEED_CODE;
static const std::string WRONG_CODE;
- // JSON attribute
- static const std::string JSON_PIN_CODE;
+ // parameters
+ static const std::string PARAMETER_KEY_CODE;
private:
time::seconds m_secretLifetime;
diff --git a/src/challenge-module/challenge-private-key.cpp b/src/challenge-module/challenge-private-key.cpp
deleted file mode 100644
index 74af413..0000000
--- a/src/challenge-module/challenge-private-key.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 "challenge-private-key.hpp"
-
-#include <iostream>
-#include <ndn-cxx/security/verification-helpers.hpp>
-#include <ndn-cxx/util/io.hpp>
-
-#include "../logging.hpp"
-
-namespace ndn {
-namespace ndncert {
-
-_LOG_INIT(ndncert.ChallengePrivateKey);
-
-NDNCERT_REGISTER_CHALLENGE(ChallengePrivateKey, "Private");
-
-const std::string ChallengePrivateKey::FAILURE_INVALID_REQUEST_TYPE = "failure-invalid-request-type";
-const std::string ChallengePrivateKey::FAILURE_INVALID_FORMAT_SELF_SIGNED = "failure-cannot-parse-self-signed";
-const std::string ChallengePrivateKey::FAILURE_INVALID_CREDENTIAL = "failure-invalid-credential";
-const std::string ChallengePrivateKey::JSON_PROOF_OF_PRIVATE_KEY = "proof-of-private-key";
-
-ChallengePrivateKey::ChallengePrivateKey()
- : ChallengeModule("PrivateKey")
-{
-}
-
-// For CA
-void
-ChallengePrivateKey::handleChallengeRequest(const Block& params, CertificateRequest& request)
-{
- if (request.m_requestType == REQUEST_TYPE_NEW) {
- _LOG_TRACE("Cannot use this private key challenge for new certificate request");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_REQUEST_TYPE;
- updateRequestOnChallengeEnd(request);
- }
- params.parse();
- shared_ptr<security::v2::Certificate> selfSigned;
- auto& elements = params.elements();
- for (size_t i = 0; i < elements.size(); i++) {
- if (elements[i].type() == tlv_parameter_key) {
- if (readString(elements[i]) == JSON_PROOF_OF_PRIVATE_KEY) {
- std::istringstream ss(readString(params.elements()[i + 1]));
- selfSigned = io::load<security::v2::Certificate>(ss);
- if (selfSigned == nullptr) {
- _LOG_ERROR("Cannot load credential parameter: cert");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_FORMAT_SELF_SIGNED;
- updateRequestOnChallengeEnd(request);
- return;
- }
- }
- else {
- continue;
- }
- }
- }
-
- // verify the credential and the self-signed cert
- if (security::verifySignature(*selfSigned, request.m_cert) &&
- readString(selfSigned->getContent()) == request.m_requestId) {
- request.m_status = Status::PENDING;
- request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
- updateRequestOnChallengeEnd(request);
- return;
- }
-
- _LOG_TRACE("Cannot verify the credential + self-signed Data + data content");
- request.m_status = Status::FAILURE;
- request.m_challengeStatus = FAILURE_INVALID_CREDENTIAL;
- updateRequestOnChallengeEnd(request);
-}
-
-// For Client
-JsonSection
-ChallengePrivateKey::getRequirementForChallenge(Status status, const std::string& challengeStatus)
-{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_PROOF_OF_PRIVATE_KEY, "Please_copy_key_signed_request_id_data_here");
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
- }
- return result;
-}
-
-JsonSection
-ChallengePrivateKey::genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params)
-{
- JsonSection result;
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- result.put(JSON_PROOF_OF_PRIVATE_KEY, params.get(JSON_PROOF_OF_PRIVATE_KEY, ""));
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
- }
- return result;
-}
-
-Block
-ChallengePrivateKey::genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params)
-{
- Block request = makeEmptyBlock(tlv_encrypted_payload);
- if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
- request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
- request.push_back(makeStringBlock(tlv_parameter_key, JSON_PROOF_OF_PRIVATE_KEY));
- request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PROOF_OF_PRIVATE_KEY, "")));
- }
- else {
- _LOG_ERROR("Client's status and challenge status are wrong");
- }
- request.encode();
- return request;
-}
-} // namespace ndncert
-} // namespace ndn
diff --git a/src/challenge-module/challenge-private-key.hpp b/src/challenge-module/challenge-private-key.hpp
deleted file mode 100644
index 5f0b936..0000000
--- a/src/challenge-module/challenge-private-key.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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_CHALLENGE_PRIVATE_KEY_HPP
-#define NDNCERT_CHALLENGE_PRIVATE_KEY_HPP
-
-#include "../challenge-module.hpp"
-
-namespace ndn {
-namespace ndncert {
-
-/**
- * @brief Private Key based challenge (for renewal and revocation)
- *
- * Once the requester could proof his/her possession of the private key corresponds to
- * the current CA's previous issued certificate, the requester could finish the challenge.
- *
- * The requester needs to provide the proof of the possession the private for the certificate
- * for the previous cerificate. The challenge require the requester to a BASE64 Data packet
- * signed by the credential pub key and whose content is the request id.
- *
- * The main process of this challenge module is:
- * 1. The requester sign a Data packet which content is the request id.
- * 2. The challenge module will verify the signature of the credential.
- *
- * Failure info when application fails:
- * FAILURE_INVALID_CREDENTIAL: When the signature cannot be validated.
- * FAILURE_INVALID_FORMAT: When the credential format is wrong.
- */
-class ChallengePrivateKey : public ChallengeModule
-{
-public:
- ChallengePrivateKey();
-
- // For CA
- void
- handleChallengeRequest(const Block& params, CertificateRequest& request) override;
-
- // For Client
- JsonSection
- getRequirementForChallenge(Status status, const std::string& challengeStatus) override;
-
- JsonSection
- genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params) override;
-
- Block
- genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params) override;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- static const std::string FAILURE_INVALID_REQUEST_TYPE;
- static const std::string FAILURE_INVALID_CREDENTIAL;
- static const std::string FAILURE_INVALID_FORMAT_SELF_SIGNED;
- static const std::string JSON_PROOF_OF_PRIVATE_KEY;
-};
-
-} // namespace ndncert
-} // namespace ndn
-
-#endif // NDNCERT_CHALLENGE_PRIVATE_KEY_HPP
diff --git a/src/ndncert-common.hpp b/src/ndncert-common.hpp
index cbbba39..6727a88 100644
--- a/src/ndncert-common.hpp
+++ b/src/ndncert-common.hpp
@@ -149,6 +149,7 @@
std::string statusToString(Status status);
enum class Error : uint16_t {
+ NO_ERROR = 0,
BAD_INTEREST_FORMAT = 1,
BAD_PARAMETER_FORMAT = 2,
BAD_SIGNATURE = 3,
diff --git a/src/protocol-detail/error.cpp b/src/protocol-detail/error.cpp
new file mode 100644
index 0000000..0b24eec
--- /dev/null
+++ b/src/protocol-detail/error.cpp
@@ -0,0 +1,46 @@
+/* -*- 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 "error.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+Block
+ERROR::encodeDataContent(Error errorCode, const std::string& description)
+{
+ Block response = makeEmptyBlock(tlv::Content);
+ response.push_back(makeNonNegativeIntegerBlock(tlv_error_code, static_cast<size_t>(errorCode)));
+ response.push_back(makeStringBlock(tlv_error_info, description));
+ response.encode();
+ return response;
+}
+
+std::tuple<Error, std::string>
+ERROR::decodefromDataContent(const Block& block)
+{
+ block.parse();
+ Error error = static_cast<Error>(readNonNegativeInteger(block.get(tlv_error_code)));
+ auto description = readString(block.get(tlv_error_info));
+ return std::make_tuple(error, description);
+}
+
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/protocol-detail/error.hpp b/src/protocol-detail/error.hpp
new file mode 100644
index 0000000..c03ec05
--- /dev/null
+++ b/src/protocol-detail/error.hpp
@@ -0,0 +1,48 @@
+/* -*- 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_PROTOCOL_DETAIL_ERROR_HPP
+#define NDNCERT_PROTOCOL_DETAIL_ERROR_HPP
+
+#include "../ca-config.hpp"
+#include "../client-config.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+class ERROR {
+public:
+ /**
+ * Encode error information into a Data content TLV
+ */
+ static Block
+ encodeDataContent(Error errorCode, const std::string& description);
+
+ /**
+ * Decode error information from Data content TLV
+ */
+ static std::tuple<Error, std::string>
+ decodefromDataContent(const Block& block);
+};
+
+} // namespace ndncert
+} // namespace ndn
+
+#endif // NDNCERT_PROTOCOL_ERROR_HPP
\ No newline at end of file
diff --git a/tests/unit-tests/bench.t.cpp b/tests/unit-tests/bench.t.cpp
index a8602ef..81f9cf4 100644
--- a/tests/unit-tests/bench.t.cpp
+++ b/tests/unit-tests/bench.t.cpp
@@ -110,10 +110,10 @@
if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
std::cout << "NEW Data Size: " << response.wireEncode().size() << std::endl;
client.onNewResponse(response);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
challengeInterest = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
count++;
@@ -123,10 +123,10 @@
BOOST_CHECK(client.m_status == Status::CHALLENGE);
BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::NEED_CODE);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
challengeInterest2 = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
count++;
@@ -136,16 +136,13 @@
BOOST_CHECK(client.m_status == Status::CHALLENGE);
BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::WRONG_CODE);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
auto request = ca.getCertificateRequest(*challengeInterest2);
- auto secret = request.m_challengeSecrets.get(ChallengePin::JSON_PIN_CODE, "");
- for (auto& i : paramJson) {
- if (i.first == ChallengePin::JSON_PIN_CODE)
- i.second.put("", secret);
- }
+ auto secret = request.m_challengeSecrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
+ std::get<1>(paramList[0]) = secret;
challengeInterest3 = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
std::cout << "CHALLENGE Interest Size: " << challengeInterest3->wireEncode().size() << std::endl;
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
@@ -155,7 +152,6 @@
client.onChallengeResponse(response);
BOOST_CHECK(client.m_status == Status::SUCCESS);
- BOOST_CHECK_EQUAL(client.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
}
});
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 9e0289a..3860060 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -46,49 +46,51 @@
advanceClocks(time::milliseconds(20), 60);
BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 2);
- BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // onInfo, onProbe, onNew, onChallenge, onRevoke
+ BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // onInfo, onProbe, onNew, onChallenge, onRevoke
}
-// BOOST_AUTO_TEST_CASE(HandleProbe)
-// {
-// auto identity = addIdentity(Name("/ndn"));
-// auto key = identity.getDefaultKey();
-// auto cert = key.getDefaultCertificate();
+BOOST_AUTO_TEST_CASE(HandleProbe)
+{
+ auto identity = addIdentity(Name("/ndn"));
+ auto key = identity.getDefaultKey();
+ 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");
-// ca.setProbeHandler([&](const Block& probeInfo) {
-// return "example";
-// });
-// advanceClocks(time::milliseconds(20), 60);
+ util::DummyClientFace face(io, m_keyChain, {true, true});
+ CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "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");
+ return result;
+ });
+ advanceClocks(time::milliseconds(20), 60);
-// Interest interest("/ndn/CA/PROBE");
-// interest.setCanBePrefix(false);
+ Interest interest("/ndn/CA/PROBE");
+ interest.setCanBePrefix(false);
-// Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
-// paramTLV.push_back(makeStringBlock(tlv_parameter_key, JSON_CLIENT_PROBE_INFO));
-// paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
-// paramTLV.encode();
+ Block paramTLV = makeEmptyBlock(tlv::ApplicationParameters);
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, JSON_CLIENT_PROBE_INFO));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi"));
+ paramTLV.encode();
-// interest.setApplicationParameters(paramTLV);
+ interest.setApplicationParameters(paramTLV);
-// int count = 0;
-// face.onSendData.connect([&](const Data& response) {
-// count++;
-// BOOST_CHECK(security::verifySignature(response, cert));
-// Block contentBlock = response.getContent();
-// contentBlock.parse();
-// Block probeResponse = contentBlock.get(tlv_probe_response);
-// probeResponse.parse();
-// Name caName;
-// caName.wireDecode(probeResponse.get(tlv::Name));
-// BOOST_CHECK_EQUAL(caName, "/ndn/example");
-// });
-// face.receive(interest);
+ int count = 0;
+ face.onSendData.connect([&](const Data& response) {
+ count++;
+ BOOST_CHECK(security::verifySignature(response, cert));
+ Block contentBlock = response.getContent();
+ contentBlock.parse();
+ Block probeResponse = contentBlock.get(tlv_probe_response);
+ probeResponse.parse();
+ Name caName;
+ caName.wireDecode(probeResponse.get(tlv::Name));
+ BOOST_CHECK_EQUAL(caName, "/ndn/example");
+ });
+ face.receive(interest);
-// advanceClocks(time::milliseconds(20), 60);
-// BOOST_CHECK_EQUAL(count, 1);
-// }
+ advanceClocks(time::milliseconds(20), 60);
+ BOOST_CHECK_EQUAL(count, 1);
+}
BOOST_AUTO_TEST_CASE(HandleInfo)
{
@@ -305,10 +307,10 @@
face.onSendData.connect([&](const Data& response) {
if (Name("/ndn/CA/NEW").isPrefixOf(response.getName())) {
client.onNewResponse(response);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
challengeInterest = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
count++;
@@ -318,10 +320,10 @@
BOOST_CHECK(client.m_status == Status::CHALLENGE);
BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::NEED_CODE);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
challengeInterest2 = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
count++;
@@ -331,16 +333,13 @@
BOOST_CHECK(client.m_status == Status::CHALLENGE);
BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::WRONG_CODE);
- auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+ auto paramList = pinChallenge.getRequestedParameterList(client.m_status, client.m_challengeStatus);
auto request = ca.getCertificateRequest(*challengeInterest2);
- auto secret = request.m_challengeSecrets.get(ChallengePin::JSON_PIN_CODE, "");
- for (auto& i : paramJson) {
- if (i.first == ChallengePin::JSON_PIN_CODE)
- i.second.put("", secret);
- }
+ auto secret = request.m_challengeSecrets.get(ChallengePin::PARAMETER_KEY_CODE, "");
+ std::get<1>(paramList[0]) = secret;
challengeInterest3 = client.generateChallengeInterest(pinChallenge.genChallengeRequestTLV(client.m_status,
client.m_challengeStatus,
- paramJson));
+ std::move(paramList)));
}
else if (Name("/ndn/CA/CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
count++;
@@ -348,7 +347,6 @@
client.onChallengeResponse(response);
BOOST_CHECK(client.m_status == Status::SUCCESS);
- BOOST_CHECK_EQUAL(client.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
}
});
@@ -369,7 +367,7 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
- util::DummyClientFace face(io, { true, true });
+ util::DummyClientFace face(io, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
@@ -383,7 +381,7 @@
clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
- time::system_clock::now() + time::hours(10)));
+ time::system_clock::now() + time::hours(10)));
m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
CertificateRequest certRequest(Name("/ndn"), "122", REQUEST_TYPE_NEW, Status::SUCCESS, clientCert);
auto issuedCert = ca.issueCertificate(certRequest);
@@ -397,7 +395,7 @@
auto interest = client.generateRevokeInterest(issuedCert);
int count = 0;
- face.onSendData.connect([&] (const Data& response) {
+ face.onSendData.connect([&](const Data& response) {
count++;
BOOST_CHECK(security::verifySignature(response, cert));
auto contentBlock = response.getContent();
@@ -409,16 +407,16 @@
auto challengeBlockCount = 0;
for (auto const& element : contentBlock.elements()) {
- if (element.type() == tlv_challenge) {
- challengeBlockCount++;
- }
+ if (element.type() == tlv_challenge) {
+ challengeBlockCount++;
+ }
}
BOOST_CHECK(challengeBlockCount != 0);
client.onRevokeResponse(response);
BOOST_CHECK_EQUAL_COLLECTIONS(client.m_aesKey, client.m_aesKey + sizeof(client.m_aesKey),
- ca.m_aesKey, ca.m_aesKey + sizeof(ca.m_aesKey));
+ ca.m_aesKey, ca.m_aesKey + sizeof(ca.m_aesKey));
});
face.receive(*interest);
@@ -432,7 +430,7 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
- util::DummyClientFace face(io, { true, true });
+ util::DummyClientFace face(io, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test", "ca-storage-memory");
advanceClocks(time::milliseconds(20), 60);
@@ -446,7 +444,7 @@
clientCert.setContent(clientKey.getPublicKey().data(), clientKey.getPublicKey().size());
SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
- time::system_clock::now() + time::hours(10)));
+ time::system_clock::now() + time::hours(10)));
m_keyChain.sign(clientCert, signingByKey(clientKey.getName()).setSignatureInfo(signatureInfo));
ClientModule client(m_keyChain);
@@ -458,7 +456,7 @@
auto interest = client.generateRevokeInterest(clientCert);
int count = 0;
- face.onSendData.connect([&] (const Data& response) {
+ face.onSendData.connect([&](const Data& response) {
count++;
});
face.receive(*interest);
@@ -467,8 +465,7 @@
BOOST_CHECK_EQUAL(count, 0);
}
-
-BOOST_AUTO_TEST_SUITE_END() // TestCaModule
+BOOST_AUTO_TEST_SUITE_END() // TestCaModule
} // namespace tests
} // namespace ndncert
diff --git a/tests/unit-tests/challenge-credential.t.cpp b/tests/unit-tests/challenge-credential.t.cpp
index e600e20..358175e 100644
--- a/tests/unit-tests/challenge-credential.t.cpp
+++ b/tests/unit-tests/challenge-credential.t.cpp
@@ -89,15 +89,14 @@
Block params = makeEmptyBlock(tlv_encrypted_payload);
params.push_back(makeStringBlock(tlv_selected_challenge, "Credential"));
- params.push_back(makeStringBlock(tlv_parameter_key, ChallengeCredential::JSON_CREDENTIAL_CERT));
+ params.push_back(makeStringBlock(tlv_parameter_key, ChallengeCredential::PARAMETER_KEY_CREDENTIAL_CERT));
params.push_back(makeStringBlock(tlv_parameter_value, credentialStr));
- params.push_back(makeStringBlock(tlv_parameter_key, ChallengeCredential::JSON_PROOF_OF_PRIVATE_KEY));
+ params.push_back(makeStringBlock(tlv_parameter_key, ChallengeCredential::PARAMETER_KEY_PROOF_OF_PRIVATE_KEY));
params.push_back(makeStringBlock(tlv_parameter_value, selfSignedStr));
params.encode();
challenge.handleChallengeRequest(params, request);
BOOST_CHECK(request.m_status == Status::PENDING);
- BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit-tests/challenge-email.t.cpp b/tests/unit-tests/challenge-email.t.cpp
index 4beb6b4..d397e58 100644
--- a/tests/unit-tests/challenge-email.t.cpp
+++ b/tests/unit-tests/challenge-email.t.cpp
@@ -48,7 +48,7 @@
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::BEFORE_CHALLENGE, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::JSON_EMAIL));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::PARAMETER_KEY_EMAIL));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi@cs.ucla.edu"));
ChallengeEmail challenge("./tests/unit-tests/test-send-email.sh");
@@ -56,7 +56,7 @@
BOOST_CHECK(request.m_status == Status::CHALLENGE);
BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengeEmail::NEED_CODE);
- BOOST_CHECK(request.m_challengeSecrets.get<std::string>(ChallengeEmail::JSON_CODE) != "");
+ BOOST_CHECK(request.m_challengeSecrets.get<std::string>(ChallengeEmail::PARAMETER_KEY_CODE) != "");
BOOST_CHECK(request.m_remainingTime != 0);
BOOST_CHECK(request.m_remainingTries != 0);
BOOST_CHECK(request.m_challengeTp != "");
@@ -76,7 +76,7 @@
end = line.find(delimiter);
std::string secret = line.substr(0, end);
- auto stored_secret = request.m_challengeSecrets.get<std::string>(ChallengeEmail::JSON_CODE);
+ auto stored_secret = request.m_challengeSecrets.get<std::string>(ChallengeEmail::PARAMETER_KEY_CODE);
BOOST_CHECK_EQUAL(secret, stored_secret);
line = line.substr(end + 1);
@@ -98,13 +98,12 @@
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::BEFORE_CHALLENGE, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::JSON_EMAIL));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::PARAMETER_KEY_EMAIL));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "zhiyi@cs"));
ChallengeEmail challenge;
challenge.handleChallengeRequest(paramTLV, request);
- BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengeEmail::FAILURE_INVALID_EMAIL);
BOOST_CHECK(request.m_status == Status::FAILURE);
}
@@ -114,18 +113,17 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
JsonSection json;
- json.put(ChallengeEmail::JSON_CODE, "4567");
+ json.put(ChallengeEmail::PARAMETER_KEY_CODE, "4567");
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::CHALLENGE, ChallengeEmail::NEED_CODE,
"Email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::JSON_CODE));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::PARAMETER_KEY_CODE));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "4567"));
ChallengeEmail challenge;
challenge.handleChallengeRequest(paramTLV, request);
- BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
BOOST_CHECK(request.m_status == Status::PENDING);
BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), true);
}
@@ -136,12 +134,12 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
JsonSection json;
- json.put(ChallengeEmail::JSON_CODE, "4567");
+ json.put(ChallengeEmail::PARAMETER_KEY_CODE, "4567");
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::CHALLENGE, ChallengeEmail::NEED_CODE,
"email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::JSON_CODE));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengeEmail::PARAMETER_KEY_CODE));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "7890"));
ChallengeEmail challenge;
diff --git a/tests/unit-tests/challenge-pin.t.cpp b/tests/unit-tests/challenge-pin.t.cpp
index ef0a572..a75444a 100644
--- a/tests/unit-tests/challenge-pin.t.cpp
+++ b/tests/unit-tests/challenge-pin.t.cpp
@@ -54,19 +54,18 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
JsonSection secret;
- secret.add(ChallengePin::JSON_PIN_CODE, "12345");
+ secret.add(ChallengePin::PARAMETER_KEY_CODE, "12345");
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::CHALLENGE, ChallengePin::NEED_CODE, "pin",
time::toIsoString(time::system_clock::now()), 3600, 3, secret, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengePin::JSON_PIN_CODE));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengePin::PARAMETER_KEY_CODE));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "12345"));
ChallengePin challenge;
challenge.handleChallengeRequest(paramTLV, request);
BOOST_CHECK(request.m_status == Status::PENDING);
- BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), true);
}
@@ -76,12 +75,12 @@
auto key = identity.getDefaultKey();
auto cert = key.getDefaultCertificate();
JsonSection secret;
- secret.add(ChallengePin::JSON_PIN_CODE, "12345");
+ secret.add(ChallengePin::PARAMETER_KEY_CODE, "12345");
CertificateRequest request(Name("/ndn/site1"), "123", REQUEST_TYPE_NEW, Status::CHALLENGE, ChallengePin::NEED_CODE, "pin",
time::toIsoString(time::system_clock::now()), 3600, 3, secret, cert);
Block paramTLV = makeEmptyBlock(tlv_encrypted_payload);
- paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengePin::JSON_PIN_CODE));
+ paramTLV.push_back(makeStringBlock(tlv_parameter_key, ChallengePin::PARAMETER_KEY_CODE));
paramTLV.push_back(makeStringBlock(tlv_parameter_value, "45678"));
ChallengePin challenge;
diff --git a/tests/unit-tests/challenge-private-key.t.cpp b/tests/unit-tests/challenge-private-key.t.cpp
deleted file mode 100644
index 20eceaa..0000000
--- a/tests/unit-tests/challenge-private-key.t.cpp
+++ /dev/null
@@ -1,75 +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 "challenge-module/challenge-private-key.hpp"
-#include "test-common.hpp"
-#include <ndn-cxx/security/signing-helpers.hpp>
-#include <ndn-cxx/util/io.hpp>
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(TestChallengeCredential, IdentityManagementFixture)
-
-BOOST_AUTO_TEST_CASE(HandlePrivateKeyChallengeRequest)
-{
- // create trust anchor
- ChallengePrivateKey challenge;
-
- // create certificate request
- auto identityA = addIdentity(Name("/example"));
- auto keyA = identityA.getDefaultKey();
- auto certA = keyA.getDefaultCertificate();
- CertificateRequest request(Name("/example"), "123", REQUEST_TYPE_REVOKE, Status::BEFORE_CHALLENGE, certA);
-
- security::v2::Certificate privateKeyProof;
- privateKeyProof.setName(Name(keyA.getName()).append("proof-of-private-key").appendVersion());
- privateKeyProof.setContent(makeStringBlock(tlv::Content, "123"));
- m_keyChain.sign(privateKeyProof, signingByKey(keyA));
-
- std::stringstream ss;
- io::save<security::v2::Certificate>(privateKeyProof, ss);
- auto checkCert = *(io::load<security::v2::Certificate>(ss));
- BOOST_CHECK_EQUAL(checkCert, privateKeyProof);
- ss.str("");
- ss.clear();
-
- io::save<security::v2::Certificate>(privateKeyProof, ss);
- std::string selfSignedStr = ss.str();
- ss.str("");
- ss.clear();
-
- Block params = makeEmptyBlock(tlv_encrypted_payload);
- params.push_back(makeStringBlock(tlv_selected_challenge, "Private Key"));
- params.push_back(makeStringBlock(tlv_parameter_key, ChallengePrivateKey::JSON_PROOF_OF_PRIVATE_KEY));
- params.push_back(makeStringBlock(tlv_parameter_value, selfSignedStr));
- params.encode();
-
- challenge.handleChallengeRequest(params, request);
- BOOST_CHECK(request.m_status == Status::PENDING);
- BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index 52d0fdb..4b3b38a 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -43,24 +43,20 @@
int validityPeriod = -1;
ClientModule client(keyChain);
-static std::list<std::string>
-captureParams(const JsonSection& requirement)
+static void
+captureParams(std::vector<std::tuple<std::string, std::string>>& requirement)
{
std::list<std::string> results;
- for (const auto& item : requirement) {
- std::cerr << item.second.get<std::string>("") << std::endl;
- std::cerr << "Please provide the argument: " << item.first << " : " << std::endl;
- std::string tempParam;
- getline(std::cin, tempParam);
- results.push_back(tempParam);
+ for (auto& item : requirement) {
+ std::cerr << std::get<1>(item) << std::endl;
+ std::string captured;
+ getline(std::cin, captured);
+ std::get<1>(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->first << " : " << *it1 << std::endl;
+ for (const auto& item : requirement) {
+ std::cerr << std::get<0>(item) << " : " << std::get<1>(item) << std::endl;
}
- return results;
}
static std::list<std::string>
@@ -135,22 +131,15 @@
}
auto challenge = ChallengeModule::createChallengeModule(challengeType);
- auto requirement = challenge->getRequirementForChallenge(client.getApplicationStatus(),
- client.getChallengeStatus());
+ auto requirement = challenge->getRequestedParameterList(client.getApplicationStatus(),
+ client.getChallengeStatus());
if (requirement.size() > 0) {
std::cerr << "Step " << nStep++ << ": Please satisfy following instruction(s)\n";
- std::string redo = "";
- std::list<std::string> capturedParams;
- capturedParams = captureParams(requirement);
- auto it1 = capturedParams.begin();
- auto it2 = requirement.begin();
- for (; it1 != capturedParams.end() && it2 != requirement.end(); it1++, it2++) {
- it2->second.put("", *it1);
- }
+ captureParams(requirement);
}
face.expressInterest(*client.generateChallengeInterest(challenge->genChallengeRequestTLV(client.getApplicationStatus(),
client.getChallengeStatus(),
- requirement)),
+ std::move(requirement))),
bind(&challengeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}
@@ -194,22 +183,15 @@
std::cerr << "Error. Cannot load selected Challenge Module. Exit." << std::endl;
return;
}
- auto requirement = challenge->getRequirementForChallenge(client.getApplicationStatus(),
- client.getChallengeStatus());
+ auto requirement = challenge->getRequestedParameterList(client.getApplicationStatus(),
+ client.getChallengeStatus());
if (requirement.size() > 0) {
- std::cerr << "Step " << nStep++ << ": Please satisfy following instruction(s)\n";
- std::string redo = "";
- std::list<std::string> capturedParams;
- capturedParams = captureParams(requirement);
- auto it1 = capturedParams.begin();
- auto it2 = requirement.begin();
- for (; it1 != capturedParams.end() && it2 != requirement.end(); it1++, it2++) {
- it2->second.put("", *it1);
- }
+ std::cerr << "Step " << nStep++ << ": Please provide parameters used for Identity Verification Challenge\n";
+ captureParams(requirement);
}
face.expressInterest(*client.generateChallengeInterest(challenge->genChallengeRequestTLV(client.getApplicationStatus(),
client.getChallengeStatus(),
- requirement)),
+ std::move(requirement))),
bind(&challengeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}