Probe: make probe a token for better security

Change-Id: I079d70146b3e5c22e789d2ed754018fe562ddd6c
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);