update profile fetching
Change-Id: I788ece8371f7e24c87918a57062673be1d866e5b
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index c32a4f4..9125cc6 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -66,29 +66,16 @@
void
CaModule::registerPrefix()
{
- // register localhop discovery prefix
- Name localhopInfoPrefix("/localhop/CA/INFO");
- auto prefixId = m_face.setInterestFilter(InterestFilter(localhopInfoPrefix),
- bind(&CaModule::onInfo, this, _2),
- bind(&CaModule::onRegisterFailed, this, _2));
- m_registeredPrefixHandles.push_back(prefixId);
- _LOG_TRACE("Prefix " << localhopInfoPrefix << " got registered");
-
// register prefixes
Name prefix = m_config.m_caItem.m_caPrefix;
prefix.append("CA");
- prefixId = m_face.registerPrefix(
+ auto prefixId = m_face.registerPrefix(
prefix,
[&](const Name& name) {
- // register INFO prefix
- auto filterId = m_face.setInterestFilter(Name(name).append("INFO"),
- bind(&CaModule::onInfo, this, _2));
- m_interestFilterHandles.push_back(filterId);
-
// register PROBE prefix
- filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
- bind(&CaModule::onProbe, this, _2));
+ auto filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
+ bind(&CaModule::onProbe, this, _2));
m_interestFilterHandles.push_back(filterId);
// register NEW prefix
@@ -164,21 +151,6 @@
}
void
-CaModule::onInfo(const Interest& request)
-{
- _LOG_TRACE("Received INFO request");
-
- if (request.getName().get(-1).type() == 32) {
- m_face.put(*generateCaConfigMetaData());
- }
- else {
- m_face.put(*generateCaConfigData());
- }
-
- _LOG_TRACE("Handle INFO: send out the INFO response");
-}
-
-void
CaModule::onProbe(const Interest& request)
{
// PROBE Naming Convention: /<CA-Prefix>/CA/PROBE/[ParametersSha256DigestComponent]
@@ -502,31 +474,6 @@
_LOG_ERROR("Failed to register prefix in local hub's daemon, REASON: " << reason);
}
-Block
-CaModule::dataContentFromJson(const JsonSection& jsonSection)
-{
- std::stringstream ss;
- boost::property_tree::write_json(ss, jsonSection);
- return makeStringBlock(ndn::tlv::Content, ss.str());
-}
-
-JsonSection
-CaModule::jsonFromBlock(const Block& block)
-{
- std::string jsonString;
- try {
- jsonString = encoding::readString(block);
- std::istringstream ss(jsonString);
- JsonSection json;
- boost::property_tree::json_parser::read_json(ss, json);
- return json;
- }
- catch (const std::exception& e) {
- _LOG_ERROR("Cannot read JSON string from TLV Value: " << e.what());
- return JsonSection();
- }
-}
-
Data
CaModule::generateErrorDataPacket(const Name& name, ErrorCode error, const std::string& errorInfo)
{
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index ac2a741..76713d0 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -31,16 +31,6 @@
class CaModule : noncopyable
{
public:
- /**
- * @brief Error that can be thrown from CaModule
- */
- class Error : public std::runtime_error
- {
- public:
- using std::runtime_error::runtime_error;
- };
-
-public:
CaModule(Face& face, security::v2::KeyChain& keyChain, const std::string& configPath,
const std::string& storageType = "ca-storage-sqlite3");
@@ -64,12 +54,6 @@
void
setStatusUpdateCallback(const StatusUpdateCallback& onUpdateCallback);
- static JsonSection
- jsonFromBlock(const Block& block);
-
- static Block
- dataContentFromJson(const JsonSection& jsonSection);
-
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
shared_ptr<Data>
generateCaConfigMetaData();
@@ -113,7 +97,6 @@
std::list<RegisteredPrefixHandle> m_registeredPrefixHandles;
std::list<InterestFilterHandle> m_interestFilterHandles;
-
};
} // namespace ndncert
diff --git a/src/requester.cpp b/src/requester.cpp
index 6c147e9..fda2f4f 100644
--- a/src/requester.cpp
+++ b/src/requester.cpp
@@ -33,6 +33,7 @@
#include <ndn-cxx/security/verification-helpers.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/util/random.hpp>
+#include <ndn-cxx/metadata-object.hpp>
namespace ndn {
namespace ndncert {
@@ -47,14 +48,22 @@
}
shared_ptr<Interest>
-Requester::genCaProfileInterest(const Name& caName)
+Requester::genCaProfileDiscoveryInterest(const Name& caName)
{
- Name interestName = caName;
+ Name contentName = caName;
if (readString(caName.at(-1)) != "CA")
- interestName.append("CA");
- interestName.append("INFO");
- auto interest = make_shared<Interest>(interestName);
- interest->setMustBeFresh(true);
+ contentName.append("CA");
+ contentName.append("INFO");
+ return std::make_shared<Interest>(MetadataObject::makeDiscoveryInterest(contentName));
+}
+
+shared_ptr<Interest>
+Requester::genCaProfileInterestFromDiscoveryResponse(const Data& reply)
+{
+ auto metaData = MetadataObject(reply);
+ auto interestName= metaData.getVersionedName();
+ interestName.appendSegment(0);
+ auto interest = std::make_shared<Interest>(interestName);
interest->setCanBePrefix(false);
return interest;
}
diff --git a/src/requester.hpp b/src/requester.hpp
index ab987dd..c6510b1 100644
--- a/src/requester.hpp
+++ b/src/requester.hpp
@@ -99,31 +99,49 @@
{
public:
/**
- * Generates a INFO interest corresponds to the CA for given prefix.
- * @param caName the name prefix of the CA.
- * @return A shared pointer to an interest ready to be sent.
+ * Generates a CA profile discovery Interest following RDR protocol.
+ * @param caName, the name prefix of the CA.
+ * @return A shared pointer to an Interest ready to be sent.
*/
static shared_ptr<Interest>
- genCaProfileInterest(const Name& caName);
+ genCaProfileDiscoveryInterest(const Name& caName);
/**
- * Decodes the replied data for the configuration of the CA.
+ * Generates a CA profile fetching Interest following RDR protocol.
+ * @param reply, the Data packet replied from discovery Interest.
+ * @return A shared pointer to an Interest ready to be sent.
+ */
+ static shared_ptr<Interest>
+ genCaProfileInterestFromDiscoveryResponse(const Data& reply);
+
+ /**
+ * Decodes the CA profile from the replied CA profile Data packet.
* Will first verify the signature of the packet using the key provided inside the profile.
* The application should be cautious whether to add CaProfile into the RequesterCaCache.
- * @param reply
+ * @param reply, the Data packet replied from CA profile fetching Interest.
* @return the CaProfile if decoding is successful
* @throw std::runtime_error if the decoding fails or receiving an error packet.
*/
static boost::optional<CaProfile>
onCaProfileResponse(const Data& reply);
+ /**
+ * Decodes the CA profile from the replied CA profile Data packet after the redirection.
+ * Will first verify the signature of the packet using the key provided inside the profile and
+ * verify the certificate's digest matches the one obtained from the original CA.
+ * The application should be cautious whether to add CaProfile into the RequesterCaCache.
+ * @param reply, the Data packet replied from CA profile fetching Interest.
+ * @param caCertFullName, the full name obtained from original CA's probe response.
+ * @return the CaProfile if decoding is successful
+ * @throw std::runtime_error if the decoding fails or receiving an error packet.
+ */
static boost::optional<CaProfile>
onCaProfileResponseAfterRedirection(const Data& reply, const Name& caCertFullName);
/**
* Generates a PROBE interest to the CA (for suggested name assignments).
- * @param ca the CA that interest is send to
- * @param probeInfo the requester information to carry to the CA
+ * @param ca, the CA that interest is send to
+ * @param probeInfo, the requester information to carry to the CA
* @return A shared pointer of to the encoded interest, ready to be sent.
*/
static shared_ptr<Interest>
@@ -132,10 +150,10 @@
/**
* Decodes the replied data for PROBE process from the CA.
* Will first verify the signature of the packet using the key provided inside the profile.
- * @param reply The replied data packet
- * @param ca the profile of the CA that replies the packet
- * @param identityNames The vector to load the decoded identity names from the data.
- * @param otherCas The vector to load the decoded redirection CA prefixes from the data.
+ * @param reply, The replied data packet
+ * @param ca, the profile of the CA that replies the packet
+ * @param identityNames, The vector to load the decoded identity names from the data.
+ * @param otherCas, The vector to load the decoded redirection CA prefixes from the data.
* @throw std::runtime_error if the decoding fails or receiving an error packet.
*/
static void
@@ -145,10 +163,10 @@
// NEW/REVOKE/RENEW related helpers
/**
* Generates a NEW interest to the CA.
- * @param state The current requester state for this request. Will be modified in the function.
- * @param identityName The identity name to be requested.
- * @param notBefore The expected notBefore field for the certificate (starting time)
- * @param notAfter The expected notAfter field for the certificate (expiration time)
+ * @param state, The current requester state for this request. Will be modified in the function.
+ * @param identityName, The identity name to be requested.
+ * @param notBefore, The expected notBefore field for the certificate (starting time)
+ * @param notAfter, The expected notAfter field for the certificate (expiration time)
* @return The shared pointer to the encoded interest.
*/
static shared_ptr<Interest>
@@ -158,8 +176,8 @@
/**
* Generates a REVOKE interest to the CA.
- * @param state The current requester state for this request. Will be modified in the function.
- * @param certificate the certificate to the revoked.
+ * @param state, The current requester state for this request. Will be modified in the function.
+ * @param certificate, the certificate to the revoked.
* @return The shared pointer to the encoded interest.
*/
static shared_ptr<Interest>
@@ -167,8 +185,8 @@
/**
* Decodes the replied data of NEW, RENEW, or REVOKE interest from the CA.
- * @param state the current requester state for the request. Will be updated in the function.
- * @param reply the replied data from the network
+ * @param state, the current requester state for the request. Will be updated in the function.
+ * @param reply, the replied data from the network
* @return the list of challenge accepted by the CA, for CHALLENGE step.
* @throw std::runtime_error if the decoding fails or receiving an error packet.
*/
@@ -178,8 +196,8 @@
// CHALLENGE helpers
/**
* Generates the required parameter for the selected challenge for the request
- * @param state The requester state of the request.Will be updated in the function.
- * @param challengeSelected The selected challenge for the request.
+ * @param state, The requester state of the request.Will be updated in the function.
+ * @param challengeSelected, The selected challenge for the request.
* Can use state.m_challengeType to continue.
* @return The requirement list for the current stage of the challenge, in name, prompt mapping.
*/
@@ -188,8 +206,8 @@
/**
* Generates the CHALLENGE interest for the request.
- * @param state The requester state of the request.
- * @param parameters The requirement list, in name, value mapping.
+ * @param state, The requester state of the request.
+ * @param parameters, The requirement list, in name, value mapping.
* @return The shared pointer to the encoded interest
*/
static shared_ptr<Interest>
@@ -197,9 +215,9 @@
std::vector<std::tuple<std::string, std::string>>&& parameters);
/**
- * Decodes the responsed data from the CHALLENGE interest.
- * @param state the corresponding requester state of the request. Will be modified.
- * @param reply the response data.
+ * Decodes the responded data from the CHALLENGE interest.
+ * @param state, the corresponding requester state of the request. Will be modified.
+ * @param reply, the response data.
* @throw std::runtime_error if the decoding fails or receiving an error packet.
*/
static void
@@ -207,7 +225,7 @@
/**
* Generate the interest to fetch the issued certificate
- * @param state the state of the request.
+ * @param state, the state of the request.
* @return The shared pointer to the encoded interest
*/
static shared_ptr<Interest>
@@ -215,7 +233,7 @@
/**
* Decoded and installs the response certificate from the certificate fetch.
- * @param reply the data replied from the certificate fetch interest.
+ * @param reply, the data replied from the certificate fetch interest.
* @return The shared pointer to the certificate being fetched.
*/
static shared_ptr<security::v2::Certificate>
@@ -223,7 +241,7 @@
/**
* End the current request session and performs cleanup if necessary.
- * @param state the requester state for the request.
+ * @param state, the requester state for the request.
*/
static void
endSession(RequesterState& state);
diff --git a/tests/unit-tests/bench.t.cpp b/tests/unit-tests/bench.t.cpp
index 28850a8..09986c6 100644
--- a/tests/unit-tests/bench.t.cpp
+++ b/tests/unit-tests/bench.t.cpp
@@ -19,9 +19,9 @@
*/
#include "ca-module.hpp"
-#include "requester.hpp"
#include "challenge-modules/challenge-pin.hpp"
#include "protocol-detail/info.hpp"
+#include "requester.hpp"
#include "test-common.hpp"
namespace ndn {
@@ -38,12 +38,26 @@
util::DummyClientFace face(io, m_keyChain, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
+ auto metaData = ca.generateCaConfigMetaData();
+ auto profileData = ca.generateCaConfigData();
advanceClocks(time::milliseconds(20), 60);
Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
std::cout << "CA Config discovery Interest Size: " << interest.wireEncode().size() << std::endl;
shared_ptr<Interest> infoInterest = nullptr;
+ face.setInterestFilter(InterestFilter("/ndn/CA/INFO"),
+ [&](const auto&, const Interest& interest) {
+ if (interest.matchesData(*metaData)) {
+ face.put(*metaData);
+ }
+ else {
+ BOOST_CHECK(interest.matchesData(*profileData));
+ face.put(*profileData);
+ }
+ }, nullptr, nullptr);
+ advanceClocks(time::milliseconds(20), 60);
+
int count = 0;
face.onSendData.connect([&](const Data& response) {
if (count == 0) {
@@ -55,7 +69,6 @@
interest.setCanBePrefix(true);
infoInterest = make_shared<Interest>(interest);
std::cout << "CA Config fetch Interest Size: " << infoInterest->wireEncode().size() << std::endl;
-
}
else {
count++;
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 7abb727..774484d 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -39,11 +39,11 @@
BOOST_CHECK_EQUAL(ca.getCaConf().m_caItem.m_caPrefix, "/ndn");
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_registeredPrefixHandles.size(), 1); // removed local discovery registration
+ BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 4); // onProbe, onNew, onChallenge, onRevoke
}
-BOOST_AUTO_TEST_CASE(HandleInfo)
+BOOST_AUTO_TEST_CASE(HandleProfileFetching)
{
auto identity = addIdentity(Name("/ndn"));
auto key = identity.getDefaultKey();
@@ -51,27 +51,53 @@
util::DummyClientFace face(io, m_keyChain, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-1", "ca-storage-memory");
+ auto metaData = ca.generateCaConfigMetaData();
+ auto profileData = ca.generateCaConfigData();
advanceClocks(time::milliseconds(20), 60);
- Interest interest("/ndn/CA/INFO");
- interest.setCanBePrefix(false);
+ Interest interest = MetadataObject::makeDiscoveryInterest(Name("/ndn/CA/INFO"));
+ shared_ptr<Interest> infoInterest = nullptr;
+
+ face.setInterestFilter(InterestFilter("/ndn/CA/INFO"),
+ [&](const auto&, const Interest& interest) {
+ if (interest.matchesData(*metaData)) {
+ face.put(*metaData);
+ }
+ else {
+ BOOST_CHECK(interest.matchesData(*profileData));
+ face.put(*profileData);
+ }
+ }, nullptr, nullptr);
+ advanceClocks(time::milliseconds(20), 60);
int count = 0;
face.onSendData.connect([&](const Data& response) {
- count++;
- BOOST_CHECK(security::verifySignature(response, cert));
- auto contentBlock = response.getContent();
- contentBlock.parse();
- auto caItem = INFO::decodeDataContent(contentBlock);
- BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
- BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
- BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
- BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
+ if (count == 0) {
+ count++;
+ auto block = response.getContent();
+ block.parse();
+ Interest interest(Name(block.get(tlv::Name)));
+ interest.setCanBePrefix(true);
+ infoInterest = make_shared<Interest>(interest);
+ }
+ else {
+ count++;
+ BOOST_CHECK(security::verifySignature(response, cert));
+ auto contentBlock = response.getContent();
+ contentBlock.parse();
+ auto caItem = INFO::decodeDataContent(contentBlock);
+ BOOST_CHECK_EQUAL(caItem.m_caPrefix, "/ndn");
+ BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.size(), 1);
+ BOOST_CHECK_EQUAL(caItem.m_probeParameterKeys.front(), "full name");
+ BOOST_CHECK_EQUAL(caItem.m_cert->wireEncode(), cert.wireEncode());
+ BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
+ }
});
face.receive(interest);
-
advanceClocks(time::milliseconds(20), 60);
- BOOST_CHECK_EQUAL(count, 1);
+ face.receive(*infoInterest);
+ advanceClocks(time::milliseconds(20), 60);
+ BOOST_CHECK_EQUAL(count, 2);
}
BOOST_AUTO_TEST_CASE(HandleProbe)
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index 7f0d005..cecb978 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -275,10 +275,19 @@
}
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));
+ auto redirectedCaFullName = redirects[index - names.size()];
+ std::cerr << "You selected redirects with certificate: " << redirectedCaFullName.getPrefix(-1).toUri() << std::endl;
+ face.expressInterest(
+ *Requester::genCaProfileDiscoveryInterest(redirectedCaFullName.getPrefix(-1)),
+ [&](const Interest&, const Data& data) {
+ auto fetchingInterest = Requester::genCaProfileInterestFromDiscoveryResponse(data);
+ face.expressInterest(*fetchingInterest,
+ bind(&InfoCb, _2, redirectedCaFullName),
+ bind(&onNackCb),
+ bind(&timeoutCb));
+ },
+ bind(&onNackCb),
+ bind(&timeoutCb));
}
}
@@ -312,8 +321,17 @@
<< "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, Name()), bind(&onNackCb), bind(&timeoutCb));
+ face.expressInterest(
+ *Requester::genCaProfileDiscoveryInterest(Name(expectedCAName)),
+ [&](const Interest&, const Data& data) {
+ auto fetchingInterest = Requester::genCaProfileInterestFromDiscoveryResponse(data);
+ face.expressInterest(*fetchingInterest,
+ bind(&InfoCb, _2, Name()),
+ bind(&onNackCb),
+ bind(&timeoutCb));
+ },
+ bind(&onNackCb),
+ bind(&timeoutCb));
}
else {
size_t caIndex;