place encoding for NEW/REVOKE/CHALLENGE in protocol detail file

Change-Id: I37d421bf256564c2acf9246983001a525c510e1f
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 70aa887..b2d0176 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -224,18 +224,25 @@
   // REVOKE Naming Convention: /<CA-prefix>/CA/REVOKE/[SignedInterestParameters_Digest]
   // get ECDH pub key and cert request
   const auto& parameterTLV = request.getApplicationParameters();
-  parameterTLV.parse();
+  std::string ecdhPub;
+  shared_ptr<security::v2::Certificate> clientCert;
+  try {
+      NEW_RENEW_REVOKE::decodeApplicationParameters(parameterTLV, requestType, ecdhPub, clientCert);
+  } catch (const std::exception& e) {
+    if (!parameterTLV.hasValue()) {
+      _LOG_ERROR("Empty TLV obtained from the Interest parameter.");
+      m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER,
+                                         "Empty TLV obtained from the Interest parameter."));
+      return;
+    }
 
-  if (!parameterTLV.hasValue()) {
-    _LOG_ERROR("Empty TLV obtained from the Interest parameter.");
+    _LOG_ERROR("Unrecognized self-signed certificate: " << e.what());
     m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER,
-                                       "Empty TLV obtained from the Interest parameter."));
+                                       "Unrecognized self-signed certificate."));
     return;
   }
 
-  std::string peerKeyBase64 = readString(parameterTLV.get(tlv_ecdh_pub));
-
-  if (peerKeyBase64 == "") {
+  if (ecdhPub == "") {
     _LOG_ERROR("Empty ECDH PUB obtained from the Interest parameter.");
     m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER,
                                        "Empty ECDH PUB obtained from the Interest parameter."));
@@ -246,7 +253,7 @@
   ECDHState ecdh;
   auto myEcdhPubKeyBase64 = ecdh.getBase64PubKey();
   try {
-    ecdh.deriveSecret(peerKeyBase64);
+    ecdh.deriveSecret(ecdhPub);
   }
   catch (const std::exception& e) {
     _LOG_ERROR("Cannot derive a shared secret using the provided ECDH key: " << e.what());
@@ -261,27 +268,6 @@
   hkdf(ecdh.context->sharedSecret, ecdh.context->sharedSecretLen,
        (uint8_t*)&saltInt, sizeof(saltInt), aesKey, sizeof(aesKey));
 
-  shared_ptr<security::v2::Certificate> clientCert = nullptr;
-  // parse certificate request
-  Block requestPayload;
-  if (requestType == RequestType::NEW) {
-    requestPayload = parameterTLV.get(tlv_cert_request);
-  }
-  else if (requestType == RequestType::REVOKE) {
-    requestPayload = parameterTLV.get(tlv_cert_to_revoke);
-  }
-  requestPayload.parse();
-  try {
-    security::v2::Certificate cert = security::v2::Certificate(requestPayload.get(tlv::Data));
-    clientCert = make_shared<security::v2::Certificate>(cert);
-  }
-  catch (const std::exception& e) {
-    _LOG_ERROR("Unrecognized self-signed certificate: " << e.what());
-    m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER,
-                                        "Unrecognized self-signed certificate."));
-    return;
-  }
-
   // verify identity name
   if (!m_config.m_caItem.m_caPrefix.isPrefixOf(clientCert->getIdentity())
       || !security::v2::Certificate::isValidName(clientCert->getName())
diff --git a/src/protocol-detail/challenge.cpp b/src/protocol-detail/challenge.cpp
index 85875fd..847f7db 100644
--- a/src/protocol-detail/challenge.cpp
+++ b/src/protocol-detail/challenge.cpp
@@ -35,6 +35,23 @@
   return response;
 }
 
+CHALLENGE::DecodedData
+CHALLENGE::decodeDataPayload(const Block& data){
+    data.parse();
+    Status status = static_cast<Status>(readNonNegativeInteger(data.get(tlv_status)));
+    std::string challengeStatus = readString(data.get(tlv_challenge_status));
+    size_t remainingTries = readNonNegativeInteger(data.get(tlv_remaining_tries));
+    time::seconds remainingTime = time::seconds(readNonNegativeInteger(data.get(tlv_remaining_time)));
+
+    if (data.find(tlv_issued_cert_name) != data.elements_end()) {
+        Block issuedCertNameBlock = data.get(tlv_issued_cert_name);
+        issuedCertNameBlock.parse();
+        return DecodedData{status, challengeStatus, remainingTries, remainingTime, Name(issuedCertNameBlock.get(tlv::Name))};
+    }
+
+    return DecodedData{status, challengeStatus, remainingTries, remainingTime, nullopt};
+}
+
 } // namespace ndncert
 } // namespace ndn
 
diff --git a/src/protocol-detail/challenge.hpp b/src/protocol-detail/challenge.hpp
index aafcd42..8078237 100644
--- a/src/protocol-detail/challenge.hpp
+++ b/src/protocol-detail/challenge.hpp
@@ -30,6 +30,17 @@
 public:
   static Block
   encodeDataPayload(const RequestState& request);
+
+  struct DecodedData{
+      Status status;
+      std::string challengeStatus;
+      size_t remainingTries;
+      time::seconds remainingTime;
+      optional<Name> issuedCertName;
+  };
+
+  static DecodedData
+  decodeDataPayload(const Block& data);
 };
 
 }  // namespace ndncert
diff --git a/src/protocol-detail/new-renew-revoke.cpp b/src/protocol-detail/new-renew-revoke.cpp
index 0a941b1..6cae7ff 100644
--- a/src/protocol-detail/new-renew-revoke.cpp
+++ b/src/protocol-detail/new-renew-revoke.cpp
@@ -28,7 +28,7 @@
 namespace ndn {
 namespace ndncert {
 
-_LOG_INIT(ndncert.client);
+_LOG_INIT(ndncert.encoding.new_renew_revoke);
 
 Block
 NEW_RENEW_REVOKE::encodeApplicationParameters(RequestType requestType, const std::string& ecdhPub, const security::v2::Certificate& certRequest)
@@ -55,6 +55,25 @@
   return request;
 }
 
+void
+NEW_RENEW_REVOKE::decodeApplicationParameters(const Block& payload, RequestType requestType, std::string& ecdhPub,
+                                              shared_ptr<security::v2::Certificate>& clientCert) {
+  payload.parse();
+
+  ecdhPub = readString(payload.get(tlv_ecdh_pub));
+  Block requestPayload;
+  if (requestType == RequestType::NEW) {
+    requestPayload = payload.get(tlv_cert_request);
+  }
+  else if (requestType == RequestType::REVOKE) {
+    requestPayload = payload.get(tlv_cert_to_revoke);
+  }
+  requestPayload.parse();
+
+  security::v2::Certificate cert = security::v2::Certificate(requestPayload.get(tlv::Data));
+  clientCert = make_shared<security::v2::Certificate>(cert);
+}
+
 Block
 NEW_RENEW_REVOKE::encodeDataContent(const std::string& ecdhKey, const std::string& salt,
                                     const RequestState& request,
@@ -72,5 +91,22 @@
   return response;
 }
 
+NEW_RENEW_REVOKE::DecodedData
+NEW_RENEW_REVOKE::decodeDataContent(const Block& content)
+{
+  content.parse();
+  const auto& ecdhKey = readString(content.get(tlv_ecdh_pub));
+  const auto& salt = readString(content.get(tlv_salt));
+  const auto& requestStatus = static_cast<Status>(readNonNegativeInteger(content.get(tlv_status)));
+  const auto& requestId = readString(content.get(tlv_request_id));
+  std::list<std::string> challenges;
+  for (auto const& element : content.elements()) {
+    if (element.type() == tlv_challenge) {
+      challenges.push_back(readString(element));
+    }
+  }
+  return DecodedData{ecdhKey, salt, requestId, requestStatus, challenges};
+}
+
 }  // namespace ndncert
 }  // namespace ndn
\ No newline at end of file
diff --git a/src/protocol-detail/new-renew-revoke.hpp b/src/protocol-detail/new-renew-revoke.hpp
index aac51d2..4c9cb18 100644
--- a/src/protocol-detail/new-renew-revoke.hpp
+++ b/src/protocol-detail/new-renew-revoke.hpp
@@ -31,10 +31,22 @@
   static Block
   encodeApplicationParameters(RequestType requestType, const std::string& ecdhPub, const security::v2::Certificate& certRequest);
 
+  static void
+  decodeApplicationParameters(const Block& block, RequestType requestType, std::string& ecdhPub, shared_ptr<security::v2::Certificate>& certRequest);
+
   static Block
   encodeDataContent(const std::string& ecdhKey, const std::string& salt,
                              const RequestState& request,
                              const std::list<std::string>& challenges);
+  struct DecodedData {
+    std::string ecdhKey;
+    std::string salt;
+    std::string requestId;
+    Status requestStatus;
+    std::list<std::string> challenges;
+  };
+  static DecodedData
+  decodeDataContent(const Block& content);
 };
 
 }  // namespace ndncert
diff --git a/src/requester.cpp b/src/requester.cpp
index 7bf9594..165ad93 100644
--- a/src/requester.cpp
+++ b/src/requester.cpp
@@ -181,28 +181,21 @@
   processIfError(reply);
 
   auto contentTLV = reply.getContent();
-  contentTLV.parse();
+  const auto content = NEW_RENEW_REVOKE::decodeDataContent(contentTLV);
 
   // ECDH
-  const auto& peerKeyBase64Str = readString(contentTLV.get(tlv_ecdh_pub));
-  const auto& saltStr = readString(contentTLV.get(tlv_salt));
-  uint64_t saltInt = std::stoull(saltStr);
-  state.m_ecdh.deriveSecret(peerKeyBase64Str);
+  uint64_t saltInt = std::stoull(content.salt);
+  state.m_ecdh.deriveSecret(content.ecdhKey);
 
   // HKDF
   hkdf(state.m_ecdh.context->sharedSecret, state.m_ecdh.context->sharedSecretLen,
        (uint8_t*)&saltInt, sizeof(saltInt), state.m_aesKey, sizeof(state.m_aesKey));
 
   // update state
-  state.m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
-  state.m_requestId = readString(contentTLV.get(tlv_request_id));
-  std::list<std::string> challengeList;
-  for (auto const& element : contentTLV.elements()) {
-    if (element.type() == tlv_challenge) {
-      challengeList.push_back(readString(element));
-    }
-  }
-  return challengeList;
+  state.m_status = content.requestStatus;
+  state.m_requestId = content.requestId;
+
+  return content.challenges;
 }
 
 std::vector<std::tuple<std::string, std::string>>
@@ -254,19 +247,16 @@
   processIfError(reply);
   auto result = decodeBlockWithAesGcm128(reply.getContent(), state.m_aesKey, (const uint8_t*)"test", strlen("test"));
   Block contentTLV = makeBinaryBlock(tlv_encrypted_payload, result.data(), result.size());
-  contentTLV.parse();
+  auto decoded = CHALLENGE::decodeDataPayload(contentTLV);
 
   // update state
-  state.m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
-  state.m_challengeStatus = readString(contentTLV.get(tlv_challenge_status));
-  state.m_remainingTries = readNonNegativeInteger(contentTLV.get(tlv_remaining_tries));
-  state.m_freshBefore = time::system_clock::now() +
-                  time::seconds(readNonNegativeInteger(contentTLV.get(tlv_remaining_time)));
+  state.m_status = decoded.status;
+  state.m_challengeStatus = decoded.challengeStatus;
+  state.m_remainingTries = decoded.remainingTries;
+  state.m_freshBefore = time::system_clock::now() + decoded.remainingTime;
 
-  if (contentTLV.find(tlv_issued_cert_name) != contentTLV.elements_end()) {
-    Block issuedCertNameBlock = contentTLV.get(tlv_issued_cert_name);
-    issuedCertNameBlock.parse();
-    state.m_issuedCertName.wireDecode(issuedCertNameBlock.get(tlv::Name));
+  if (decoded.issuedCertName) {
+    state.m_issuedCertName = *decoded.issuedCertName;
   }
 }