diff --git a/src/challenge-modules/challenge-email.cpp b/src/challenge-modules/challenge-email.cpp
index 327fb79..c12ba88 100644
--- a/src/challenge-modules/challenge-email.cpp
+++ b/src/challenge-modules/challenge-email.cpp
@@ -19,7 +19,6 @@
  */
 
 #include "challenge-email.hpp"
-#include "../ca-module.hpp"
 #include <regex>
 
 namespace ndn {
diff --git a/src/challenge-modules/challenge-pin.cpp b/src/challenge-modules/challenge-pin.cpp
index 4853eed..fd5b5a5 100644
--- a/src/challenge-modules/challenge-pin.cpp
+++ b/src/challenge-modules/challenge-pin.cpp
@@ -19,7 +19,6 @@
  */
 
 #include "challenge-pin.hpp"
-
 #include <ndn-cxx/util/random.hpp>
 
 namespace ndn {
diff --git a/src/client-module.cpp b/src/client-module.cpp
deleted file mode 100644
index ffda468..0000000
--- a/src/client-module.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2020, Regents of the University of California.
- *
- * This file is part of ndncert, a certificate management system based on NDN.
- *
- * ndncert is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndncert authors and contributors.
- */
-
-#include "client-module.hpp"
-
-#include <ndn-cxx/security/signing-helpers.hpp>
-#include <ndn-cxx/security/transform/base64-encode.hpp>
-#include <ndn-cxx/security/transform/buffer-source.hpp>
-#include <ndn-cxx/security/transform/stream-sink.hpp>
-#include <ndn-cxx/security/verification-helpers.hpp>
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/util/random.hpp>
-
-#include "challenge-module.hpp"
-#include "crypto-support/enc-tlv.hpp"
-#include "protocol-detail/challenge.hpp"
-#include "protocol-detail/info.hpp"
-#include "protocol-detail/new-renew-revoke.hpp"
-#include "protocol-detail/probe.hpp"
-#include "protocol-detail/error.hpp"
-#include "ndncert-common.hpp"
-
-namespace ndn {
-namespace ndncert {
-
-_LOG_INIT(ndncert.client);
-
-ClientModule::ClientModule(security::v2::KeyChain& keyChain)
-    : m_keyChain(keyChain)
-{
-}
-
-ClientModule::~ClientModule()
-{
-  endSession();
-}
-
-shared_ptr<Interest>
-ClientModule::generateInfoInterest(const Name& caName)
-{
-  Name interestName = caName;
-  if (readString(caName.at(-1)) != "CA")
-    interestName.append("CA");
-  interestName.append("INFO");
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  return interest;
-}
-
-bool
-ClientModule::verifyInfoResponse(const Data& reply)
-{
-  // parse the ca item
-  auto caItem = INFO::decodeDataContent(reply.getContent());
-
-  // verify the probe Data's sig
-  if (!security::verifySignature(reply, *caItem.m_cert)) {
-    _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
-    return false;
-  }
-  return true;
-}
-
-void
-ClientModule::addCaFromInfoResponse(const Data& reply)
-{
-  const Block& contentBlock = reply.getContent();
-
-  // parse the ca item
-  auto caItem = INFO::decodeDataContent(contentBlock);
-
-  // update the local config
-  bool findItem = false;
-  for (auto& item : m_config.m_caItems) {
-    if (item.m_caPrefix == caItem.m_caPrefix) {
-      findItem = true;
-      item = caItem;
-    }
-  }
-  if (!findItem) {
-    m_config.m_caItems.push_back(caItem);
-  }
-}
-
-shared_ptr<Interest>
-ClientModule::generateProbeInterest(const CaConfigItem& ca,
-                                    std::vector<std::tuple<std::string, std::string>>&& probeInfo)
-{
-  Name interestName = ca.m_caPrefix;
-  interestName.append("CA").append("PROBE");
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  interest->setApplicationParameters(PROBE::encodeApplicationParameters(std::move(probeInfo)));
-
-  // update local state
-  m_ca = ca;
-  return interest;
-}
-
-void
-ClientModule::onProbeResponse(const Data& reply)
-{
-  if (!security::verifySignature(reply, *m_ca.m_cert)) {
-    _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
-    return;
-  }
-
-  // error handling
-  processIfError(reply);
-
-  auto contentTLV = reply.getContent();
-  contentTLV.parse();
-
-  // read the available name and put it into the state
-  if (contentTLV.get(tlv_probe_response).hasValue()) {
-    Block probeResponseBlock = contentTLV.get(tlv_probe_response);
-    probeResponseBlock.parse();
-    m_identityName.wireDecode(probeResponseBlock.get(tlv::Name));
-  }
-  else {
-    NDN_LOG_TRACE("The JSON_CA_NAME is empty.");
-  }
-}
-
-shared_ptr<Interest>
-ClientModule::generateNewInterest(const time::system_clock::TimePoint& notBefore,
-                                  const time::system_clock::TimePoint& notAfter,
-                                  const Name& identityName)
-{
-  // Name requestedName = identityName;
-  if (!identityName.empty()) {  // if identityName is not empty, find the corresponding CA
-    bool findCa = false;
-    for (const auto& caItem : m_config.m_caItems) {
-      if (caItem.m_caPrefix.isPrefixOf(identityName)) {
-        m_ca = caItem;
-        findCa = true;
-      }
-    }
-    if (!findCa) {  // if cannot find, cannot proceed
-      return nullptr;
-    }
-    m_identityName = identityName;
-  }
-  else {  // if identityName is empty, check m_identityName or generate a random name
-    if (!m_identityName.empty()) {
-      // do nothing
-    }
-    else {
-      NDN_LOG_TRACE("Randomly create a new name because m_identityName is empty and the param is empty.");
-      auto id = std::to_string(random::generateSecureWord64());
-      m_identityName = m_ca.m_caPrefix;
-      m_identityName.append(id);
-    }
-  }
-
-  // generate a newly key pair or use an existing key
-  const auto& pib = m_keyChain.getPib();
-  security::pib::Identity identity;
-  try {
-    identity = pib.getIdentity(m_identityName);
-  }
-  catch (const security::Pib::Error& e) {
-    identity = m_keyChain.createIdentity(m_identityName);
-    m_isNewlyCreatedIdentity = true;
-    m_isNewlyCreatedKey = true;
-  }
-  try {
-    m_key = identity.getDefaultKey();
-  }
-  catch (const security::Pib::Error& e) {
-    m_key = m_keyChain.createKey(identity);
-    m_isNewlyCreatedKey = true;
-  }
-
-  // generate certificate request
-  security::v2::Certificate certRequest;
-  certRequest.setName(Name(m_key.getName()).append("cert-request").appendVersion());
-  certRequest.setContentType(tlv::ContentType_Key);
-  certRequest.setContent(m_key.getPublicKey().data(), m_key.getPublicKey().size());
-  SignatureInfo signatureInfo;
-  signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
-  m_keyChain.sign(certRequest, signingByKey(m_key.getName()).setSignatureInfo(signatureInfo));
-
-  // generate Interest packet
-  Name interestName = m_ca.m_caPrefix;
-  interestName.append("CA").append("NEW");
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  interest->setApplicationParameters(
-      NEW_RENEW_REVOKE::encodeApplicationParameters(RequestType::NEW, m_ecdh.getBase64PubKey(), certRequest));
-
-  // sign the Interest packet
-  m_keyChain.sign(*interest, signingByKey(m_key.getName()));
-  return interest;
-}
-
-std::list<std::string>
-ClientModule::onNewRenewRevokeResponse(const Data& reply)
-{
-  if (!security::verifySignature(reply, *m_ca.m_cert)) {
-    _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
-    return std::list<std::string>();
-  }
-
-  // error handling
-  processIfError(reply);
-
-  auto contentTLV = reply.getContent();
-  contentTLV.parse();
-
-  // ECDH
-  const auto& peerKeyBase64Str = readString(contentTLV.get(tlv_ecdh_pub));
-  const auto& saltStr = readString(contentTLV.get(tlv_salt));
-  uint64_t saltInt = std::stoull(saltStr);
-  m_ecdh.deriveSecret(peerKeyBase64Str);
-
-  // HKDF
-  hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
-       (uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
-
-  // update state
-  m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
-  m_requestId = readString(contentTLV.get(tlv_request_id));
-  m_challengeList.clear();
-  for (auto const& element : contentTLV.elements()) {
-    if (element.type() == tlv_challenge) {
-      m_challengeList.push_back(readString(element));
-    }
-  }
-  return m_challengeList;
-}
-
-shared_ptr<Interest>
-ClientModule::generateRevokeInterest(const security::v2::Certificate& certificate)
-{
-  // Name requestedName = identityName;
-  bool findCa = false;
-  for (const auto& caItem : m_config.m_caItems) {
-    if (caItem.m_caPrefix.isPrefixOf(certificate.getName())) {
-      m_ca = caItem;
-      findCa = true;
-    }
-  }
-  if (!findCa) {  // if cannot find, cannot proceed
-    _LOG_TRACE("Cannot find corresponding CA for the certificate.");
-    return nullptr;
-  }
-
-  // generate Interest packet
-  Name interestName = m_ca.m_caPrefix;
-  interestName.append("CA").append("REVOKE");
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  interest->setApplicationParameters(
-      NEW_RENEW_REVOKE::encodeApplicationParameters(RequestType::REVOKE, m_ecdh.getBase64PubKey(), certificate));
-
-  // return the Interest packet
-  return interest;
-}
-
-shared_ptr<Interest>
-ClientModule::generateChallengeInterest(const Block& challengeRequest)
-{
-  challengeRequest.parse();
-  m_challengeType = readString(challengeRequest.get(tlv_selected_challenge));
-
-  Name interestName = m_ca.m_caPrefix;
-  interestName.append("CA").append("CHALLENGE").append(m_requestId);
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-
-  // encrypt the Interest parameters
-  auto paramBlock = encodeBlockWithAesGcm128(tlv::ApplicationParameters, m_aesKey,
-                                             challengeRequest.value(), challengeRequest.value_size(),
-                                             (const uint8_t*)"test", strlen("test"));
-  interest->setApplicationParameters(paramBlock);
-
-  m_keyChain.sign(*interest, signingByKey(m_key.getName()));
-  return interest;
-}
-
-void
-ClientModule::onChallengeResponse(const Data& reply)
-{
-  if (!security::verifySignature(reply, *m_ca.m_cert)) {
-    _LOG_ERROR("Cannot verify data signature from " << m_ca.m_caPrefix.toUri());
-    return;
-  }
-
-  // error handling
-  processIfError(reply);
-
-  auto result = decodeBlockWithAesGcm128(reply.getContent(), m_aesKey, (const uint8_t*)"test", strlen("test"));
-
-  Block contentTLV = makeBinaryBlock(tlv_encrypted_payload, result.data(), result.size());
-  contentTLV.parse();
-
-  // update state
-  m_status = static_cast<Status>(readNonNegativeInteger(contentTLV.get(tlv_status)));
-  m_challengeStatus = readString(contentTLV.get(tlv_challenge_status));
-  m_remainingTries = readNonNegativeInteger(contentTLV.get(tlv_remaining_tries));
-  m_freshBefore = time::system_clock::now() +
-                  time::seconds(readNonNegativeInteger(contentTLV.get(tlv_remaining_time)));
-
-  if (contentTLV.find(tlv_issued_cert_name) != contentTLV.elements_end()) {
-    Block issuedCertNameBlock = contentTLV.get(tlv_issued_cert_name);
-    issuedCertNameBlock.parse();
-    m_issuedCertName.wireDecode(issuedCertNameBlock.get(tlv::Name));
-  }
-}
-
-shared_ptr<Interest>
-ClientModule::generateDownloadInterest()
-{
-  Name interestName = m_ca.m_caPrefix;
-  interestName.append("CA").append("DOWNLOAD").append(m_requestId);
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  return interest;
-}
-
-shared_ptr<Interest>
-ClientModule::generateCertFetchInterest()
-{
-  Name interestName = m_issuedCertName;
-  auto interest = make_shared<Interest>(interestName);
-  interest->setMustBeFresh(true);
-  interest->setCanBePrefix(false);
-  return interest;
-}
-
-void
-ClientModule::onCertFetchResponse(const Data& reply)
-{
-  try {
-    security::v2::Certificate cert(reply.getContent().blockFromValue());
-    m_keyChain.addCertificate(m_key, cert);
-    _LOG_TRACE("Fetched and installed the cert " << cert.getName());
-  }
-  catch (const std::exception& e) {
-    _LOG_ERROR("Cannot add replied certificate into the keychain " << e.what());
-    return;
-  }
-}
-
-void
-ClientModule::endSession()
-{
-  if (getApplicationStatus() == Status::SUCCESS || getApplicationStatus() == Status::ENDED) {
-    return;
-  }
-  if (m_isNewlyCreatedIdentity) {
-    // put the identity into the if scope is because it may cause an error
-    // outside since when endSession is called, identity may not have been created yet.
-    auto identity = m_keyChain.getPib().getIdentity(m_identityName);
-    m_keyChain.deleteIdentity(identity);
-  }
-  else if (m_isNewlyCreatedKey) {
-    auto identity = m_keyChain.getPib().getIdentity(m_identityName);
-    m_keyChain.deleteKey(identity, m_key);
-  }
-  m_status = Status::ENDED;
-}
-
-void
-ClientModule::processIfError(const Data& data)
-{
-  auto contentTLV = data.getContent();
-  if (ErrorTLV::isErrorContent(contentTLV)) {
-  try {
-    auto error = ErrorTLV::decodefromDataContent(contentTLV);
-    _LOG_ERROR("Error data returned for " << data.getName() << ": " << std::endl <<
-               "Code: " << errorCodeToString(std::get<0>(error)) << std::endl <<
-               "Info: " << std::get<1>(error) << std::endl);
-    } catch (const std::exception& e) {
-      _LOG_ERROR("Cannot parse error data content for " << data.getName());
-      return;
-    }
-  }
-}
-
-}  // namespace ndncert
-}  // namespace ndn
diff --git a/src/client-module.hpp b/src/client-module.hpp
deleted file mode 100644
index b9c0f35..0000000
--- a/src/client-module.hpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2020, Regents of the University of California.
- *
- * This file is part of ndncert, a certificate management system based on NDN.
- *
- * ndncert is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndncert authors and contributors.
- */
-
-#ifndef NDNCERT_CLIENT_MODULE_HPP
-#define NDNCERT_CLIENT_MODULE_HPP
-
-#include "configuration.hpp"
-#include "request-state.hpp"
-#include "crypto-support/crypto-helper.hpp"
-
-namespace ndn {
-namespace ndncert {
-
-// TODO
-// For each CA item in Client.Conf, create a validator instance and initialize it with CA's cert
-// The validator instance should be in CaConfigItem
-
-class ClientModule : noncopyable
-{
-public:
-  /**
-   * @brief Error that can be thrown from ClientModule
-   */
-  class Error : public std::runtime_error
-  {
-  public:
-    using std::runtime_error::runtime_error;
-  };
-
-public:
-  ClientModule(security::v2::KeyChain& keyChain);
-
-  ~ClientModule();
-
-  ClientConfig&
-  getClientConf()
-  {
-    return m_config;
-  }
-
-  Status
-  getApplicationStatus() const
-  {
-    return m_status;
-  }
-
-  std::string
-  getChallengeStatus() const
-  {
-    return m_challengeStatus;
-  }
-
-  shared_ptr<Interest>
-  generateInfoInterest(const Name& caName);
-
-  bool
-  verifyInfoResponse(const Data& reply);
-
-  /**
-   * @brief Process the replied PROBE INFO Data packet
-   * Warning: this function will add a new trust anchor into the application.
-   * Please invoke this function only when reply can be fully trusted or the CA
-   * can be verified in later challenge phase.
-   */
-  void
-  addCaFromInfoResponse(const Data& reply);
-
-  shared_ptr<Interest>
-  generateProbeInterest(const CaConfigItem& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);
-
-  void
-  onProbeResponse(const Data& reply);
-
-  shared_ptr<Interest>
-  generateNewInterest(const time::system_clock::TimePoint& notBefore,
-                      const time::system_clock::TimePoint& notAfter,
-                      const Name& identityName = Name());
-
-  shared_ptr<Interest>
-  generateRevokeInterest(const security::v2::Certificate& certificate);
-
-  std::list<std::string>
-  onNewRenewRevokeResponse(const Data& reply);
-
-  shared_ptr<Interest>
-  generateChallengeInterest(const Block& paramTLV);
-
-  void
-  onChallengeResponse(const Data& reply);
-
-  shared_ptr<Interest>
-  generateDownloadInterest();
-
-  shared_ptr<Interest>
-  generateCertFetchInterest();
-
-  void
-  onCertFetchResponse(const Data& reply);
-
-  void
-  endSession();
-
-  static void
-  processIfError(const Data& data);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  ClientConfig m_config;
-  security::v2::KeyChain& m_keyChain;
-
-  CaConfigItem m_ca;
-  security::Key m_key;
-  Name m_identityName;
-
-  std::string m_requestId = "";
-  Status m_status = Status::NOT_STARTED;
-  std::string m_challengeStatus = "";
-  std::string m_challengeType = "";
-  Name m_issuedCertName;
-  std::list<std::string> m_challengeList;
-  bool m_isCertInstalled = false;
-  bool m_isNewlyCreatedIdentity = false;
-  bool m_isNewlyCreatedKey = false;
-
-  int m_remainingTries = 0;
-  time::system_clock::TimePoint m_freshBefore;
-
-  ECDHState m_ecdh;
-  uint8_t m_aesKey[16] = {0};
-};
-
-} // namespace ndncert
-} // namespace ndn
-
-#endif // NDNCERT_CLIENT_MODULE_HPP
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 8d1d397..10fe352 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -27,7 +27,7 @@
 namespace ndncert {
 
 void
-CaConfigItem::parse(const JsonSection& configJson)
+CaProfile::parse(const JsonSection& configJson)
 {
   // CA prefix
   m_caPrefix = Name(configJson.get(CONFIG_CA_PREFIX, ""));
@@ -79,7 +79,7 @@
 }
 
 JsonSection
-CaConfigItem::toJson() const
+CaProfile::toJson() const
 {
   JsonSection caItem;
   caItem.put(CONFIG_CA_PREFIX, m_caPrefix.toUri());
@@ -150,7 +150,7 @@
 }
 
 void
-ClientConfig::load(const std::string& fileName)
+RequesterCaCache::load(const std::string& fileName)
 {
   JsonSection configJson;
   try {
@@ -166,12 +166,12 @@
 }
 
 void
-ClientConfig::load(const JsonSection& configSection)
+RequesterCaCache::load(const JsonSection& configSection)
 {
   m_caItems.clear();
   auto caList = configSection.get_child("ca-list");
   for (auto item : caList) {
-    CaConfigItem caItem;
+    CaProfile caItem;
     caItem.parse(item.second);
     if (caItem.m_cert == nullptr) {
       BOOST_THROW_EXCEPTION(std::runtime_error("No CA certificate is loaded from JSON configuration."));
@@ -181,7 +181,7 @@
 }
 
 void
-ClientConfig::save(const std::string& fileName) const
+RequesterCaCache::save(const std::string& fileName) const
 {
   JsonSection configJson;
   for (const auto& caItem : m_caItems) {
@@ -196,9 +196,21 @@
 }
 
 void
-ClientConfig::removeCaItem(const Name& caName)
+RequesterCaCache::removeCaProfile(const Name& caName)
 {
-  m_caItems.remove_if([&](const CaConfigItem& item) { return item.m_caPrefix == caName; });
+  m_caItems.remove_if([&](const CaProfile& item) { return item.m_caPrefix == caName; });
+}
+
+void
+RequesterCaCache::addCaProfile(const CaProfile& profile)
+{
+  for (auto& item : m_caItems) {
+    if (item.m_caPrefix == profile.m_caPrefix) {
+      item = profile;
+      return;
+    }
+  }
+  m_caItems.push_back(profile);
 }
 
 }  // namespace ndncert
diff --git a/src/configuration.hpp b/src/configuration.hpp
index 892c056..6b9edeb 100644
--- a/src/configuration.hpp
+++ b/src/configuration.hpp
@@ -26,7 +26,7 @@
 namespace ndn {
 namespace ndncert {
 
-struct CaConfigItem {
+struct CaProfile {
   /**
    * CA Name prefix (without /CA suffix).
    */
@@ -131,7 +131,7 @@
   void
   load(const std::string& fileName);
 
-  CaConfigItem m_caItem;
+  CaProfile m_caItem;
   /**
    * Used for CA redirection as specified in
    * https://github.com/named-data/ndncert/wiki/NDNCERT-Protocol-0.3-PROBE-Extensions#probe-extension-for-redirection
@@ -153,7 +153,7 @@
  * For Client configuration format, please refer to:
  *   https://github.com/named-data/ndncert/wiki/Client-Configuration-Sample
  */
-class ClientConfig {
+class RequesterCaCache {
 public:
   /**
    * @throw std::runtime_error when config file cannot be correctly parsed.
@@ -171,9 +171,15 @@
   save(const std::string& fileName) const;
 
   void
-  removeCaItem(const Name& caName);
+  removeCaProfile(const Name& caName);
 
-  std::list<CaConfigItem> m_caItems;
+  /**
+   * Be cautious. This will add a new trust anchor for requesters.
+   */
+  void
+  addCaProfile(const CaProfile& profile);
+
+  std::list<CaProfile> m_caItems;
 };
 
 }  // namespace ndncert
diff --git a/src/protocol-detail/challenge.cpp b/src/protocol-detail/challenge.cpp
index 61a3519..85875fd 100644
--- a/src/protocol-detail/challenge.cpp
+++ b/src/protocol-detail/challenge.cpp
@@ -19,8 +19,6 @@
  */
 
 #include "challenge.hpp"
-#include "../ndncert-common.hpp"
-#include "../request-state.hpp"
 
 namespace ndn {
 namespace ndncert {
diff --git a/src/protocol-detail/error.cpp b/src/protocol-detail/error.cpp
index b74180b..dabfa6a 100644
--- a/src/protocol-detail/error.cpp
+++ b/src/protocol-detail/error.cpp
@@ -37,16 +37,11 @@
 ErrorTLV::decodefromDataContent(const Block& block)
 {
   block.parse();
+  if (block.find(tlv_error_code) == block.elements_end()) {
+    return std::make_tuple(ErrorCode::NO_ERROR, "");
+  }
   ErrorCode error = static_cast<ErrorCode>(readNonNegativeInteger(block.get(tlv_error_code)));
-  auto description = readString(block.get(tlv_error_info));
-  return std::make_tuple(error, description);
-}
-
-bool
-ErrorTLV::isErrorContent(const Block& block)
-{
-  block.parse();
-  return block.find(tlv_error_code) != block.elements_end();
+  return std::make_tuple(error, readString(block.get(tlv_error_info)));
 }
 
 }  // namespace ndncert
diff --git a/src/protocol-detail/error.hpp b/src/protocol-detail/error.hpp
index d39fe1a..8a2cda0 100644
--- a/src/protocol-detail/error.hpp
+++ b/src/protocol-detail/error.hpp
@@ -39,9 +39,6 @@
    */
   static std::tuple<ErrorCode, std::string>
   decodefromDataContent(const Block& block);
-
-  static bool
-  isErrorContent(const Block& block);
 };
 
 }  // namespace ndncert
diff --git a/src/protocol-detail/info.cpp b/src/protocol-detail/info.cpp
index 06eba0e..7c0e449 100644
--- a/src/protocol-detail/info.cpp
+++ b/src/protocol-detail/info.cpp
@@ -24,7 +24,7 @@
 namespace ndncert {
 
 Block
-INFO::encodeDataContent(const CaConfigItem& caConfig, const security::v2::Certificate& certificate)
+INFO::encodeDataContent(const CaProfile& caConfig, const security::v2::Certificate& certificate)
 {
   auto content = makeEmptyBlock(tlv::Content);
   content.push_back(makeNestedBlock(tlv_ca_prefix, caConfig.m_caPrefix));
@@ -48,10 +48,10 @@
   return content;
 }
 
-CaConfigItem
+CaProfile
 INFO::decodeDataContent(const Block& block)
 {
-  CaConfigItem result;
+  CaProfile result;
   block.parse();
   for (auto const& item : block.elements()) {
     switch (item.type()) {
diff --git a/src/protocol-detail/info.hpp b/src/protocol-detail/info.hpp
index 03f0d61..571d120 100644
--- a/src/protocol-detail/info.hpp
+++ b/src/protocol-detail/info.hpp
@@ -32,12 +32,12 @@
    * Encode CA configuration and its certificate into a TLV block as INFO Data packet content.
    */
   static Block
-  encodeDataContent(const CaConfigItem& caConfig, const security::v2::Certificate& certificate);
+  encodeDataContent(const CaProfile& caConfig, const security::v2::Certificate& certificate);
 
   /**
    * Decode CA configuration from the TLV block of INFO Data packet content.
    */
-  static CaConfigItem
+  static CaProfile
   decodeDataContent(const Block& block);
 };
 
diff --git a/src/requester.cpp b/src/requester.cpp
new file mode 100644
index 0000000..7bf9594
--- /dev/null
+++ b/src/requester.cpp
@@ -0,0 +1,327 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2020, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#include "requester.hpp"
+#include "challenge-module.hpp"
+#include "crypto-support/enc-tlv.hpp"
+#include "protocol-detail/challenge.hpp"
+#include "protocol-detail/error.hpp"
+#include "protocol-detail/info.hpp"
+#include "protocol-detail/new-renew-revoke.hpp"
+#include "protocol-detail/probe.hpp"
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/security/transform/base64-encode.hpp>
+#include <ndn-cxx/security/transform/buffer-source.hpp>
+#include <ndn-cxx/security/transform/stream-sink.hpp>
+#include <ndn-cxx/security/verification-helpers.hpp>
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/random.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+_LOG_INIT(ndncert.client);
+
+RequesterState::RequesterState(security::v2::KeyChain& keyChain, const CaProfile& caItem, RequestType requestType)
+  : m_caItem(caItem)
+  , m_keyChain(keyChain)
+  , m_type(requestType)
+{
+}
+
+shared_ptr<Interest>
+Requester::genCaProfileInterest(const Name& caName)
+{
+  Name interestName = caName;
+  if (readString(caName.at(-1)) != "CA")
+    interestName.append("CA");
+  interestName.append("INFO");
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(true);
+  interest->setCanBePrefix(false);
+  return interest;
+}
+
+boost::optional<CaProfile>
+Requester::onCaProfileResponse(const Data& reply)
+{
+  auto caItem = INFO::decodeDataContent(reply.getContent());
+  if (!security::verifySignature(reply, *caItem.m_cert)) {
+    _LOG_ERROR("Cannot verify replied Data packet signature.");
+    return boost::none;
+  }
+  return caItem;
+}
+
+shared_ptr<Interest>
+Requester::genProbeInterest(const CaProfile& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo)
+{
+  Name interestName = ca.m_caPrefix;
+  interestName.append("CA").append("PROBE");
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(true);
+  interest->setCanBePrefix(false);
+  interest->setApplicationParameters(PROBE::encodeApplicationParameters(std::move(probeInfo)));
+  return interest;
+}
+
+void
+Requester::onProbeResponse(const Data& reply, const CaProfile& ca,
+                           std::vector<Name>& identityNames, std::vector<Name>& otherCas)
+{
+  if (!security::verifySignature(reply, *ca.m_cert)) {
+    _LOG_ERROR("Cannot verify replied Data packet signature.");
+    return;
+  }
+  processIfError(reply);
+  PROBE::decodeDataContent(reply.getContent(), identityNames, otherCas);
+}
+
+shared_ptr<Interest>
+Requester::genNewInterest(RequesterState& state, const Name& identityName,
+                          const time::system_clock::TimePoint& notBefore,
+                          const time::system_clock::TimePoint& notAfter)
+{
+  if (!state.m_caItem.m_caPrefix.isPrefixOf(identityName)) {
+    return nullptr;
+  }
+  if (identityName.empty()) {
+    NDN_LOG_TRACE("Randomly create a new name because identityName is empty and the param is empty.");
+    state.m_identityName = state.m_caItem.m_caPrefix;
+    state.m_identityName.append(std::to_string(random::generateSecureWord64()));
+  }
+  else {
+    state.m_identityName = identityName;
+  }
+
+  // generate a newly key pair or use an existing key
+  const auto& pib = state.m_keyChain.getPib();
+  security::pib::Identity identity;
+  try {
+    identity = pib.getIdentity(state.m_identityName);
+  }
+  catch (const security::Pib::Error& e) {
+    identity = state.m_keyChain.createIdentity(state.m_identityName);
+    state.m_isNewlyCreatedIdentity = true;
+    state.m_isNewlyCreatedKey = true;
+  }
+  try {
+    state.m_keyPair = identity.getDefaultKey();
+  }
+  catch (const security::Pib::Error& e) {
+    state.m_keyPair = state.m_keyChain.createKey(identity);
+    state.m_isNewlyCreatedKey = true;
+  }
+  auto& keyName = state.m_keyPair.getName();
+
+  // generate certificate request
+  security::v2::Certificate certRequest;
+  certRequest.setName(Name(keyName).append("cert-request").appendVersion());
+  certRequest.setContentType(tlv::ContentType_Key);
+  certRequest.setContent(state.m_keyPair.getPublicKey().data(), state.m_keyPair.getPublicKey().size());
+  SignatureInfo signatureInfo;
+  signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
+  state.m_keyChain.sign(certRequest, signingByKey(keyName).setSignatureInfo(signatureInfo));
+
+  // generate Interest packet
+  Name interestName = state.m_caItem.m_caPrefix;
+  interestName.append("CA").append("NEW");
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(true);
+  interest->setCanBePrefix(false);
+  interest->setApplicationParameters(
+      NEW_RENEW_REVOKE::encodeApplicationParameters(RequestType::NEW, state.m_ecdh.getBase64PubKey(), certRequest));
+
+  // sign the Interest packet
+  state.m_keyChain.sign(*interest, signingByKey(keyName));
+  return interest;
+}
+
+shared_ptr<Interest>
+Requester::genRevokeInterest(RequesterState& state, const security::v2::Certificate& certificate)
+{
+  if (!state.m_caItem.m_caPrefix.isPrefixOf(certificate.getName())) {
+    return nullptr;
+  }
+  // generate Interest packet
+  Name interestName = state.m_caItem.m_caPrefix;
+  interestName.append("CA").append("REVOKE");
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(true);
+  interest->setCanBePrefix(false);
+  interest->setApplicationParameters(
+      NEW_RENEW_REVOKE::encodeApplicationParameters(RequestType::REVOKE, state.m_ecdh.getBase64PubKey(), certificate));
+  return interest;
+}
+
+std::list<std::string>
+Requester::onNewRenewRevokeResponse(RequesterState& state, const Data& reply)
+{
+  if (!security::verifySignature(reply, *state.m_caItem.m_cert)) {
+    _LOG_ERROR("Cannot verify replied Data packet signature.");
+    return std::list<std::string>();
+  }
+  processIfError(reply);
+
+  auto contentTLV = reply.getContent();
+  contentTLV.parse();
+
+  // 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);
+
+  // 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;
+}
+
+std::vector<std::tuple<std::string, std::string>>
+Requester::selectOrContinueChallenge(RequesterState& state, const std::string& challengeSelected)
+{
+  auto challenge = ChallengeModule::createChallengeModule(challengeSelected);
+  if (challenge == nullptr) {
+    BOOST_THROW_EXCEPTION(std::runtime_error("The challenge selected is not supported by your current version of NDNCERT."));
+  }
+  state.m_challengeType = challengeSelected;
+  return challenge->getRequestedParameterList(state.m_status, state.m_challengeStatus);
+}
+
+shared_ptr<Interest>
+Requester::genChallengeInterest(const RequesterState& state,
+                                std::vector<std::tuple<std::string, std::string>>&& parameters)
+{
+  if (state.m_challengeType == "") {
+    BOOST_THROW_EXCEPTION(std::runtime_error("The challenge has not been selected."));
+  }
+  auto challenge = ChallengeModule::createChallengeModule(state.m_challengeType);
+  if (challenge == nullptr) {
+    BOOST_THROW_EXCEPTION(std::runtime_error("The challenge selected is not supported by your current version of NDNCERT."));
+  }
+  auto challengeParams = challenge->genChallengeRequestTLV(state.m_status, state.m_challengeStatus, std::move(parameters));
+
+  Name interestName = state.m_caItem.m_caPrefix;
+  interestName.append("CA").append("CHALLENGE").append(state.m_requestId);
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(true);
+  interest->setCanBePrefix(false);
+
+  // encrypt the Interest parameters
+  auto paramBlock = encodeBlockWithAesGcm128(tlv::ApplicationParameters, state.m_aesKey,
+                                             challengeParams.value(), challengeParams.value_size(),
+                                             (const uint8_t*)"test", strlen("test"));
+  interest->setApplicationParameters(paramBlock);
+  state.m_keyChain.sign(*interest, signingByKey(state.m_keyPair.getName()));
+  return interest;
+}
+
+void
+Requester::onChallengeResponse(RequesterState& state, const Data& reply)
+{
+  if (!security::verifySignature(reply, *state.m_caItem.m_cert)) {
+    _LOG_ERROR("Cannot verify replied Data packet signature.");
+    return;
+  }
+  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();
+
+  // 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)));
+
+  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));
+  }
+}
+
+shared_ptr<Interest>
+Requester::genCertFetchInterest(const RequesterState& state)
+{
+  Name interestName = state.m_issuedCertName;
+  auto interest = make_shared<Interest>(interestName);
+  interest->setMustBeFresh(false);
+  interest->setCanBePrefix(false);
+  return interest;
+}
+
+shared_ptr<security::v2::Certificate>
+Requester::onCertFetchResponse(const Data& reply)
+{
+  try {
+    return std::make_shared<security::v2::Certificate>(reply.getContent().blockFromValue());
+  }
+  catch (const std::exception& e) {
+    _LOG_ERROR("Cannot parse replied certificate ");
+    return nullptr;
+  }
+}
+
+void
+Requester::endSession(RequesterState& state)
+{
+  if (state.m_status == Status::SUCCESS || state.m_status == Status::ENDED) {
+    return;
+  }
+  if (state.m_isNewlyCreatedIdentity) {
+    // put the identity into the if scope is because it may cause an error
+    // outside since when endSession is called, identity may not have been created yet.
+    auto identity = state.m_keyChain.getPib().getIdentity(state.m_identityName);
+    state.m_keyChain.deleteIdentity(identity);
+  }
+  else if (state.m_isNewlyCreatedKey) {
+    auto identity = state.m_keyChain.getPib().getIdentity(state.m_identityName);
+    state.m_keyChain.deleteKey(identity, state.m_keyPair);
+  }
+  state.m_status = Status::ENDED;
+}
+
+void
+Requester::processIfError(const Data& data)
+{
+  auto errorInfo = ErrorTLV::decodefromDataContent(data.getContent());
+  if (std::get<0>(errorInfo) == ErrorCode::NO_ERROR) {
+    return;
+  }
+  BOOST_THROW_EXCEPTION(std::runtime_error("Error info replied from the CA with Error code: " +
+                                           errorCodeToString(std::get<0>(errorInfo)) +
+                                           " and Error Info: " + std::get<1>(errorInfo)));
+}
+
+}  // namespace ndncert
+}  // namespace ndn
diff --git a/src/requester.hpp b/src/requester.hpp
new file mode 100644
index 0000000..44dd7ee
--- /dev/null
+++ b/src/requester.hpp
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2020, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#ifndef NDNCERT_CLIENT_MODULE_HPP
+#define NDNCERT_CLIENT_MODULE_HPP
+
+#include "configuration.hpp"
+#include "request-state.hpp"
+#include "crypto-support/crypto-helper.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+// TODO
+// For each RequesterState, create a validator instance and initialize it with CA's cert
+// The validator instance should be in CaProfile
+
+struct RequesterState {
+  explicit
+  RequesterState(security::v2::KeyChain& keyChain, const CaProfile& caItem, RequestType requestType);
+
+  CaProfile m_caItem;
+  security::v2::KeyChain& m_keyChain;
+  RequestType m_type;
+
+  Name m_identityName;
+  security::Key m_keyPair;
+  std::string m_requestId;
+  Status m_status = Status::NOT_STARTED;
+  std::string m_challengeType;
+  std::string m_challengeStatus;
+  int m_remainingTries = 0;
+  time::system_clock::TimePoint m_freshBefore;
+  Name m_issuedCertName;
+
+  ECDHState m_ecdh;
+  uint8_t m_aesKey[16] = {0};
+
+  bool m_isCertInstalled = false;
+  bool m_isNewlyCreatedIdentity = false;
+  bool m_isNewlyCreatedKey = false;
+};
+
+class Requester : noncopyable
+{
+public:
+  // INFO related helpers
+  static shared_ptr<Interest>
+  genCaProfileInterest(const Name& caName);
+
+  /**
+   * 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.
+   */
+  static boost::optional<CaProfile>
+  onCaProfileResponse(const Data& reply);
+
+  // PROBE related helpers
+  static shared_ptr<Interest>
+  genProbeInterest(const CaProfile& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);
+
+  static void
+  onProbeResponse(const Data& reply, const CaProfile& ca,
+                  std::vector<Name>& identityNames, std::vector<Name>& otherCas);
+
+  // NEW/REVOKE/RENEW related helpers
+  static shared_ptr<Interest>
+  genNewInterest(RequesterState& state, const Name& identityName,
+                      const time::system_clock::TimePoint& notBefore,
+                      const time::system_clock::TimePoint& notAfter);
+
+  static shared_ptr<Interest>
+  genRevokeInterest(RequesterState& state, const security::v2::Certificate& certificate);
+
+  static std::list<std::string>
+  onNewRenewRevokeResponse(RequesterState& state, const Data& reply);
+
+  // CHALLENGE helpers
+  static std::vector<std::tuple<std::string, std::string>>
+  selectOrContinueChallenge(RequesterState& state, const std::string& challengeSelected);
+
+  static shared_ptr<Interest>
+  genChallengeInterest(const RequesterState& state,
+                       std::vector<std::tuple<std::string, std::string>>&& parameters);
+
+  static void
+  onChallengeResponse(RequesterState& state, const Data& reply);
+
+  static shared_ptr<Interest>
+  genCertFetchInterest(const RequesterState& state);
+
+  shared_ptr<security::v2::Certificate>
+  onCertFetchResponse(const Data& reply);
+
+  void
+  endSession(RequesterState& state);
+
+private:
+  static void
+  processIfError(const Data& data);
+};
+
+} // namespace ndncert
+} // namespace ndn
+
+#endif // NDNCERT_CLIENT_MODULE_HPP
