Probe: make probe a token for better security
Change-Id: I079d70146b3e5c22e789d2ed754018fe562ddd6c
diff --git a/AUTHORS.md b/AUTHORS.md
index 2a0da5c..efe9a10 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -4,6 +4,7 @@
## The primary authors are (and/or have been):
* Zhiyi Zhang <https://zhiyi-zhang.com>
+* Yufeng Zhang <yufeng@ucla.edu>
* Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
* Lixia Zhang <http://web.cs.ucla.edu/~lixia/>
diff --git a/src/ca-config.hpp b/src/ca-config.hpp
index 83bd821..e20b8b4 100644
--- a/src/ca-config.hpp
+++ b/src/ca-config.hpp
@@ -33,7 +33,7 @@
*
* The function should throw exceptions when there is an unexpected input.
*/
-using ProbeHandler = function<std::string/*identity name*/ (const std::string&/*requester input*/)>;
+using ProbeHandler = function<std::string/*identity name*/ (const JsonSection& json/*requester input*/)>;
/**
* @brief The function would be invoked whenever the certificate request status gets update
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 7a575a9..b91a03c 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -127,10 +127,12 @@
// if not a PROBE INFO, find an available name
std::string availableId = "";
const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
- std::string probeInfoStr = parameterJson.get(JSON_CLIENT_PROBE_INFO, "");
+ //m_config.m_probe
+
+ //std::string probeInfoStr = parameterJson.get(JSON_CLIENT_PROBE_INFO, "");
if (m_config.m_probeHandler) {
try {
- availableId = m_config.m_probeHandler(probeInfoStr);
+ availableId = m_config.m_probeHandler(parameterJson);
}
catch (const std::exception& e) {
_LOG_TRACE("Cannot find PROBE input from PROBE parameters " << e.what());
@@ -144,7 +146,7 @@
Name newIdentityName = m_config.m_caName;
_LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
newIdentityName.append(availableId);
- contentJson = genProbeResponseJson(newIdentityName.toUri());
+ contentJson = genProbeResponseJson(newIdentityName.toUri(), m_config.m_probe, parameterJson);
}
Data result;
@@ -404,14 +406,28 @@
*
* PROBE response JSON format:
* {
- * "name": "@p identifier",
- * "ca-config": "@p caInformation"
+ * "name": "@p identifier"
* }
*/
const JsonSection
-CaModule::genProbeResponseJson(const Name& identifier)
+CaModule::genProbeResponseJson(const Name& identifier, const std::string& m_probe, const JsonSection& parameterJson)
{
+ std::vector<std::string> fields;
+ std::string delimiter = ":";
+ size_t last = 0;
+ size_t next = 0;
+ while ((next = m_probe.find(delimiter, last)) != std::string::npos) {
+ fields.push_back(m_probe.substr(last, next - last));
+ last = next + 1;
+ }
+ fields.push_back(m_probe.substr(last));
+
JsonSection root;
+
+ for (size_t i = 0; i < fields.size(); ++i) {
+ root.put(fields.at(i), parameterJson.get(fields.at(i), ""));
+ }
+
root.put(JSON_CA_NAME, identifier.toUri());
return root;
}
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 47e30c9..9f40c24 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -97,7 +97,9 @@
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
const JsonSection
- genProbeResponseJson(const Name& identifier);
+ genProbeResponseJson(const Name& identifier,
+ const std::string& m_probe,
+ const JsonSection& parameterJson);
const JsonSection
genProbeResponseJson();
diff --git a/src/client-config.hpp b/src/client-config.hpp
index b3aa0fc..ddbdc74 100644
--- a/src/client-config.hpp
+++ b/src/client-config.hpp
@@ -39,7 +39,7 @@
// A brief introduction to the CA. Extracted from config field "ca-info"
std::string m_caInfo;
// An instruction for requesters to use _PROBE. Extracted from config field "probe"
- std::string m_probe;
+ std::string m_probe; // "email::uid::name"
// CA's certificate
security::v2::Certificate m_anchor;
diff --git a/src/client-module.cpp b/src/client-module.cpp
index 5b03a23..29898bc 100644
--- a/src/client-module.cpp
+++ b/src/client-module.cpp
@@ -89,7 +89,7 @@
auto interest = make_shared<Interest>(interestName);
interest->setMustBeFresh(true);
interest->setCanBePrefix(false);
- auto paramJson = genProbeRequestJson(probeInfo);
+ auto paramJson = genProbeRequestJson(ca, probeInfo);
interest->setApplicationParameters(paramFromJson(paramJson));
// update local state
@@ -305,10 +305,38 @@
}
const JsonSection
-ClientModule::genProbeRequestJson(const std::string& probeInfo)
+ClientModule::genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo)
{
+ std::string delimiter = ":";
+ size_t last = 0;
+ size_t next = 0;
+
JsonSection root;
- root.put(JSON_CLIENT_PROBE_INFO, probeInfo);
+
+ std::vector<std::string> fields;
+ while ((next = ca.m_probe.find(delimiter, last)) != std::string::npos) {
+ fields.push_back(ca.m_probe.substr(last, next - last));
+ last = next + 1;
+ }
+ fields.push_back(ca.m_probe.substr(last));
+
+ std::vector<std::string> arguments;
+ last = 0;
+ next = 0;
+ while ((next = probeInfo.find(delimiter, last)) != std::string::npos) {
+ arguments.push_back(probeInfo.substr(last, next - last));
+ last = next + 1;
+ }
+ arguments.push_back(probeInfo.substr(last));
+
+ if (arguments.size() != fields.size()) {
+ BOOST_THROW_EXCEPTION(Error("Error in genProbeRequestJson: argument list does not match field list in the config file."));
+ }
+
+ for (size_t i = 0; i < fields.size(); ++i) {
+ root.put(fields.at(i), arguments.at(i));
+ }
+
return root;
}
diff --git a/src/client-module.hpp b/src/client-module.hpp
index bbf124c..30cd333 100644
--- a/src/client-module.hpp
+++ b/src/client-module.hpp
@@ -121,7 +121,7 @@
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
const JsonSection
- genProbeRequestJson(const std::string& probeInfo);
+ genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo);
const JsonSection
genNewRequestJson(const std::string& ecdhPub, const security::v2::Certificate& certRequest);
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 34e2721..45600b8 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -61,8 +61,8 @@
util::DummyClientFace face(m_io, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
- ca.setProbeHandler([&] (const std::string& probeInfo) {
- return probeInfo + "example";
+ ca.setProbeHandler([&] (const JsonSection& probeInfo) {
+ return "example";
});
advanceClocks(time::milliseconds(20), 60);
@@ -77,7 +77,7 @@
count++;
BOOST_CHECK(security::verifySignature(response, cert));
auto contentJson = ClientModule::getJsonFromData(response);
- BOOST_CHECK_EQUAL(contentJson.get<std::string>(JSON_CA_NAME), "/ndn/zhiyiexample");
+ BOOST_CHECK_EQUAL(contentJson.get<std::string>(JSON_CA_NAME), "/ndn/example");
});
face.receive(interest);
@@ -93,8 +93,8 @@
util::DummyClientFace face(m_io, {true, true});
CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
- ca.setProbeHandler([&] (const std::string& probeInfo) {
- return probeInfo + "example";
+ ca.setProbeHandler([&] (const JsonSection& probeInfo) {
+ return "example";
});
advanceClocks(time::milliseconds(20), 60);
diff --git a/tests/unit-tests/client-module.t.cpp b/tests/unit-tests/client-module.t.cpp
index da08d9b..1da13ce 100644
--- a/tests/unit-tests/client-module.t.cpp
+++ b/tests/unit-tests/client-module.t.cpp
@@ -50,16 +50,38 @@
auto cert = key.getDefaultCertificate();
ClientCaItem item;
+ item.m_probe = "email:uid:name";
item.m_caName = Name("/site");
item.m_anchor = cert;
client.getClientConf().m_caItems.push_back(item);
- auto firstInterest = client.generateProbeInterest(item, "zhiyi@cs.ucla.edu");
+ auto firstInterest = client.generateProbeInterest(item, "zhiyi@cs.ucla.edu:987654321:Zhiyi Zhang");
BOOST_CHECK_EQUAL(firstInterest->getName().toUri(), "/site/CA/_PROBE");
- BOOST_CHECK_EQUAL(CaModule::jsonFromBlock(firstInterest->getApplicationParameters()).get<std::string>(JSON_CLIENT_PROBE_INFO),
+ BOOST_CHECK_EQUAL(CaModule::jsonFromBlock(firstInterest->getApplicationParameters()).get<std::string>("email"),
"zhiyi@cs.ucla.edu");
}
+BOOST_AUTO_TEST_CASE(genProbeRequestJson)
+{
+ ClientModule client(m_keyChain);
+ client.getClientConf().load("tests/unit-tests/client.conf.test");
+
+ auto identity = addIdentity(Name("/site"));
+ auto key = identity.getDefaultKey();
+ auto cert = key.getDefaultCertificate();
+
+ ClientCaItem item;
+ item.m_probe = "email:uid:name";
+ item.m_caName = Name("/site");
+ item.m_anchor = cert;
+ client.getClientConf().m_caItems.push_back(item);
+
+ auto interestPacket = client.genProbeRequestJson(item, "yufeng@ucla.edu:123456789:Yufeng Zhang");
+ BOOST_CHECK_EQUAL(interestPacket.get("email", ""), "yufeng@ucla.edu");
+ BOOST_CHECK_EQUAL(interestPacket.get("uid", ""), "123456789");
+ BOOST_CHECK_EQUAL(interestPacket.get("name", ""), "Yufeng Zhang");
+}
+
BOOST_AUTO_TEST_SUITE_END() // TestClientModule
} // namespace tests