list func: update ca config format

Change-Id: I761f6c27d15a7909450a921785923ccbf9b6a597
diff --git a/src/ca-config.cpp b/src/ca-config.cpp
index 1032709..0f4edc8 100644
--- a/src/ca-config.cpp
+++ b/src/ca-config.cpp
@@ -28,37 +28,51 @@
 void
 CaConfig::load(const std::string& fileName)
 {
+  JsonSection configJson;
   try {
-    boost::property_tree::read_json(fileName, m_config);
+    boost::property_tree::read_json(fileName, configJson);
   }
   catch (const boost::property_tree::info_parser_error& error) {
     BOOST_THROW_EXCEPTION(Error("Failed to parse configuration file " + fileName +
                                 " " + error.message() + " line " + std::to_string(error.line())));
   }
 
-  if (m_config.begin() == m_config.end()) {
+  if (configJson.begin() == configJson.end()) {
     BOOST_THROW_EXCEPTION(Error("Error processing configuration file: " + fileName + " no data"));
   }
 
-  parse();
+  parse(configJson);
 }
 
 void
-CaConfig::parse()
+CaConfig::parse(const JsonSection& configJson)
 {
   m_caItems.clear();
-  auto caList = m_config.get_child("ca-list");
+  auto caList = configJson.get_child("ca-list");
   auto it = caList.begin();
   for (; it != caList.end(); it++) {
     CaItem item;
-    item.m_caName = Name(it->second.get<std::string>("ca-prefix"));
-    item.m_probe = it->second.get("probe", false);
-    item.m_freshnessPeriod = time::seconds(it->second.get<uint64_t>("issuing-freshness"));
-    item.m_validityPeriod = time::days(it->second.get<uint64_t>("validity-period"));
 
+    // essential info
+    item.m_caName = Name(it->second.get<std::string>("ca-prefix"));
+    item.m_freshnessPeriod = time::seconds(it->second.get("issuing-freshness", 720));
+    item.m_validityPeriod = time::days(it->second.get("validity-period", 360));
+
+    // optional info
+    item.m_probe = it->second.get("probe", "");
+    item.m_caInfo = it->second.get("ca-info", "");
+    item.m_targetedList = it->second.get("targeted-list", "");
+
+    // optional supported challenges
     auto challengeList = it->second.get_child("supported-challenges");
     item.m_supportedChallenges = parseChallengeList(challengeList);
-    item.m_anchor = Name(it->second.get<std::string>("ca-anchor"));
+
+    // related cas
+    auto relatedCaList = it->second.get_child_optional("related-ca-list");
+    if (relatedCaList) {
+      item.m_relatedCaList = parseRelatedCaList(*relatedCaList);
+    }
+
     m_caItems.push_back(item);
   }
 }
@@ -74,5 +88,18 @@
   return result;
 }
 
+std::list<ClientCaItem>
+CaConfig::parseRelatedCaList(const JsonSection& section)
+{
+  std::list<ClientCaItem> result;
+  auto it = section.begin();
+  for (; it != section.end(); it++) {
+    ClientCaItem item;
+    item.m_caName = Name(it->second.get<std::string>("ca-prefix"));
+    result.push_back(item);
+  }
+  return result;
+}
+
 } // namespace ndncert
 } // namespace ndn
diff --git a/src/ca-config.hpp b/src/ca-config.hpp
index 12cc396..b117ac3 100644
--- a/src/ca-config.hpp
+++ b/src/ca-config.hpp
@@ -22,6 +22,7 @@
 #define NDNCERT_CA_CONFIG_HPP
 
 #include "certificate-request.hpp"
+#include "client-config.hpp"
 #include <ndn-cxx/security/v2/certificate.hpp>
 
 namespace ndn {
@@ -30,16 +31,30 @@
 class CaItem
 {
 public:
+  // basic info
   Name m_caName;
-  bool m_probe;
+
+  // related CAs
+  std::list<ClientCaItem> m_relatedCaList;
+
+  // essential config
   time::seconds m_freshnessPeriod;
   time::days m_validityPeriod;
   std::list<std::string> m_supportedChallenges;
-  Name m_anchor;
+
+  // optional parameters
+  std::string m_probe;
+  std::string m_targetedList;
+  std::string m_caInfo;
 };
 
 /**
  * @brief Represents a CA configuration instance
+ *
+ * For CA configuration format, please refer to:
+ *   https://github.com/named-data/ndncert/wiki/Ca-Configuration-Sample
+ *
+ * @note Changes made to CaConfig won't be written back to the config
  */
 class CaConfig
 {
@@ -59,16 +74,16 @@
 
 private:
   void
-  parse();
+  parse(const JsonSection& configJson);
 
   std::list<std::string>
   parseChallengeList(const JsonSection& configSection);
 
+  std::list<ClientCaItem>
+  parseRelatedCaList(const JsonSection& section);
+
 public:
   std::list<CaItem> m_caItems;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  JsonSection m_config;
 };
 
 } // namespace ndncert
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 94fb2bc..904886d 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -55,30 +55,32 @@
     try {
       const RegisteredPrefixId* prefixId = m_face.registerPrefix(prefix,
         [&] (const Name& name) {
-          const InterestFilterId* filterId = m_face.setInterestFilter(Name(name).append("_PROBE"),
-                                                                      bind(&CaModule::handleProbe, this, _2, item));
-          m_interestFilterIds.push_back(filterId);
-
-          filterId = m_face.setInterestFilter(Name(name).append("_NEW"),
+          // NEW
+          const InterestFilterId* filterId = m_face.setInterestFilter(Name(name).append("_NEW"),
                                               bind(&CaModule::handleNew, this, _2, item));
           m_interestFilterIds.push_back(filterId);
-
+          // SELECT
           filterId = m_face.setInterestFilter(Name(name).append("_SELECT"),
                                               bind(&CaModule::handleSelect, this, _2, item));
           m_interestFilterIds.push_back(filterId);
-
+          // VALIDATE
           filterId = m_face.setInterestFilter(Name(name).append("_VALIDATE"),
                                               bind(&CaModule::handleValidate, this, _2, item));
           m_interestFilterIds.push_back(filterId);
-
+          // STATUS
           filterId = m_face.setInterestFilter(Name(name).append("_STATUS"),
                                               bind(&CaModule::handleStatus, this, _2, item));
           m_interestFilterIds.push_back(filterId);
-
+          // DOWNLOAD
           filterId = m_face.setInterestFilter(Name(name).append("_DOWNLOAD"),
                                               bind(&CaModule::handleDownload, this, _2, item));
           m_interestFilterIds.push_back(filterId);
-
+          // PROBE
+          if (item.m_probe != "") {
+            filterId = m_face.setInterestFilter(Name(name).append("_PROBE"),
+                                                bind(&CaModule::handleProbe, this, _2, item));
+            m_interestFilterIds.push_back(filterId);
+          }
           _LOG_TRACE("Prefix " << name << " got registered");
         },
         bind(&CaModule::onRegisterFailed, this, _2));
@@ -120,7 +122,7 @@
   Data result;
   result.setName(request.getName());
   result.setContent(dataContentFromJson(genResponseProbeJson(identityName, "")));
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 
   _LOG_TRACE("Handle PROBE: generate identity " << identityName);
@@ -165,7 +167,7 @@
   result.setName(request.getName());
   result.setContent(dataContentFromJson(genResponseNewJson(requestId, certRequest.getStatus(),
                                                            caItem.m_supportedChallenges)));
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 
   m_requestUpdateCallback(certRequest);
@@ -219,7 +221,7 @@
   Data result;
   result.setName(request.getName());
   result.setContent(dataContentFromJson(contentJson));
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 
   m_requestUpdateCallback(certRequest);
@@ -264,7 +266,7 @@
   Data result;
   result.setName(request.getName());
   result.setContent(dataContentFromJson(contentJson));
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 
   m_requestUpdateCallback(certRequest);
@@ -301,7 +303,7 @@
   Data result;
   result.setName(request.getName());
   result.setContent(dataContentFromJson(contentJson));
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 }
 
@@ -325,7 +327,7 @@
   Data result;
   result.setName(request.getName());
   result.setContent(signedCert.wireEncode());
-  m_keyChain.sign(result, signingByCertificate(caItem.m_anchor));
+  m_keyChain.sign(result, signingByIdentity(caItem.m_caName));
   m_face.put(result);
 }
 
@@ -342,8 +344,8 @@
   security::ValidityPeriod period(time::system_clock::now(),
                                   time::system_clock::now() + caItem.m_validityPeriod);
   signatureInfo.setValidityPeriod(period);
-  security::SigningInfo signingInfo(security::SigningInfo::SIGNER_TYPE_CERT,
-                                    caItem.m_anchor, signatureInfo);
+  security::SigningInfo signingInfo(security::SigningInfo::SIGNER_TYPE_ID,
+                                    caItem.m_caName, signatureInfo);
   newCert.setFreshnessPeriod(caItem.m_freshnessPeriod);
 
   m_keyChain.sign(newCert, signingInfo);
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 0e768da..5388fe6 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -70,6 +70,7 @@
     return m_storage;
   }
 
+  // @Deprecated This function should be set for each CA
   void
   setProbeHandler(const ProbeHandler& handler)
   {