Update the NDNCERT library to version NDNCERT v2

spec:[https://github.com/named-data/ndncert/wiki/NDNCERT-Protocol-new]

Change-Id: Ia480a8e70c4b38ca170dfe2fcf50d1265ab65f46
diff --git a/tests/boost-test.hpp b/tests/boost-test.hpp
index 220a481..bb32232 100644
--- a/tests/boost-test.hpp
+++ b/tests/boost-test.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -25,15 +25,16 @@
  * See AUTHORS.md for complete list of ndncert authors and contributors.
  */
 
-#ifndef CERT_TESTS_BOOST_TEST_HPP
-#define CERT_TESTS_BOOST_TEST_HPP
+#ifndef NDNCERT_TESTS_BOOST_TEST_HPP
+#define NDNCERT_TESTS_BOOST_TEST_HPP
 
 // suppress warnings from Boost.Test
 #pragma GCC system_header
 #pragma clang system_header
 
+#define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 #include <boost/concept_check.hpp>
 #include <boost/test/output_test_stream.hpp>
 
-#endif // CERT_TESTS_BOOST_TEST_HPP
+#endif // NDNCERT_TESTS_BOOST_TEST_HPP
diff --git a/tests/database-fixture.hpp b/tests/database-fixture.hpp
index fc9da55..ffe00b0 100644
--- a/tests/database-fixture.hpp
+++ b/tests/database-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -36,7 +36,7 @@
 namespace ndncert {
 namespace tests {
 
-class DatabaseFixture : public IdentityManagementV2TimeFixture
+class DatabaseFixture : public IdentityManagementTimeFixture
 {
 public:
   DatabaseFixture()
diff --git a/tests/global-configuration.cpp b/tests/global-configuration.cpp
deleted file mode 100644
index 76de542..0000000
--- a/tests/global-configuration.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017-2018, 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 "boost-test.hpp"
-
-#include <boost/filesystem.hpp>
-#include <fstream>
-#include <stdlib.h>
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-class GlobalConfiguration
-{
-public:
-  GlobalConfiguration()
-  {
-    const char* envHome = ::getenv("HOME");
-    if (envHome)
-      m_home = envHome;
-
-    boost::filesystem::path dir{TMP_TESTS_PATH};
-    dir /= "test-home";
-    ::setenv("HOME", dir.c_str(), 1);
-
-    boost::filesystem::create_directories(dir);
-    std::ofstream clientConf((dir / ".ndn" / "client.conf").c_str());
-    clientConf << "pib=pib-sqlite3" << std::endl
-               << "tpm=tpm-file" << std::endl;
-  }
-
-  ~GlobalConfiguration()
-  {
-    if (!m_home.empty())
-      ::setenv("HOME", m_home.data(), 1);
-  }
-
-private:
-  std::string m_home;
-};
-
-#if BOOST_VERSION >= 106500
-BOOST_TEST_GLOBAL_CONFIGURATION(GlobalConfiguration);
-#elif BOOST_VERSION >= 105900
-BOOST_GLOBAL_FIXTURE(GlobalConfiguration);
-#else
-BOOST_GLOBAL_FIXTURE(GlobalConfiguration)
-#endif
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/identity-management-fixture.cpp b/tests/identity-management-fixture.cpp
index aeaab40..a152f73 100644
--- a/tests/identity-management-fixture.cpp
+++ b/tests/identity-management-fixture.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -34,13 +34,36 @@
 namespace ndncert {
 namespace tests {
 
-IdentityManagementV2Fixture::IdentityManagementV2Fixture()
+namespace v2 = security::v2;
+
+IdentityManagementBaseFixture::~IdentityManagementBaseFixture()
+{
+  boost::system::error_code ec;
+  for (const auto& certFile : m_certFiles) {
+    boost::filesystem::remove(certFile, ec); // ignore error
+  }
+}
+
+bool
+IdentityManagementBaseFixture::saveCertToFile(const Data& obj, const std::string& filename)
+{
+  m_certFiles.insert(filename);
+  try {
+    io::save(obj, filename);
+    return true;
+  }
+  catch (const io::Error&) {
+    return false;
+  }
+}
+
+IdentityManagementFixture::IdentityManagementFixture()
   : m_keyChain("pib-memory:", "tpm-memory:")
 {
 }
 
 security::Identity
-IdentityManagementV2Fixture::addIdentity(const Name& identityName, const KeyParams& params)
+IdentityManagementFixture::addIdentity(const Name& identityName, const KeyParams& params)
 {
   auto identity = m_keyChain.createIdentity(identityName, params);
   m_identities.insert(identityName);
@@ -48,8 +71,7 @@
 }
 
 bool
-IdentityManagementV2Fixture::saveIdentityCertificate(const security::Identity& identity,
-                                                     const std::string& filename)
+IdentityManagementFixture::saveCertificate(const security::Identity& identity, const std::string& filename)
 {
   try {
     auto cert = identity.getDefaultKey().getDefaultCertificate();
@@ -61,20 +83,20 @@
 }
 
 security::Identity
-IdentityManagementV2Fixture::addSubCertificate(const Name& subIdentityName,
-                                               const security::Identity& issuer, const KeyParams& params)
+IdentityManagementFixture::addSubCertificate(const Name& subIdentityName,
+                                             const security::Identity& issuer, const KeyParams& params)
 {
   auto subIdentity = addIdentity(subIdentityName, params);
 
-  security::v2::Certificate request = subIdentity.getDefaultKey().getDefaultCertificate();
+  v2::Certificate request = subIdentity.getDefaultKey().getDefaultCertificate();
 
   request.setName(request.getKeyName().append("parent").appendVersion());
 
   SignatureInfo info;
-  info.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(7300)));
+  auto now = time::system_clock::now();
+  info.setValidityPeriod(security::ValidityPeriod(now, now + 7300_days));
 
-  security::v2::AdditionalDescription description;
+  v2::AdditionalDescription description;
   description.set("type", "sub-certificate");
   info.appendTypeSpecificTlv(description.wireEncode());
 
@@ -84,45 +106,32 @@
   return subIdentity;
 }
 
-security::v2::Certificate
-IdentityManagementV2Fixture::addCertificate(const security::Key& key, const std::string& issuer)
+v2::Certificate
+IdentityManagementFixture::addCertificate(const security::Key& key, const std::string& issuer)
 {
   Name certificateName = key.getName();
   certificateName
     .append(issuer)
     .appendVersion();
-  security::v2::Certificate certificate;
+  v2::Certificate certificate;
   certificate.setName(certificateName);
 
   // set metainfo
   certificate.setContentType(tlv::ContentType_Key);
-  certificate.setFreshnessPeriod(time::hours(1));
+  certificate.setFreshnessPeriod(1_h);
 
   // set content
   certificate.setContent(key.getPublicKey().data(), key.getPublicKey().size());
 
   // set signature-info
   SignatureInfo info;
-  info.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
-                                                  time::system_clock::now() + time::days(10)));
+  auto now = time::system_clock::now();
+  info.setValidityPeriod(security::ValidityPeriod(now, now + 10_days));
 
   m_keyChain.sign(certificate, signingByKey(key).setSignatureInfo(info));
   return certificate;
 }
 
-bool
-IdentityManagementV2Fixture::saveCertToFile(const Data& obj, const std::string& filename)
-{
-  m_certFiles.insert(filename);
-  try {
-    io::save(obj, filename);
-    return true;
-  }
-  catch (const io::Error&) {
-    return false;
-  }
-}
-
 } // namespace tests
 } // namespace ndncert
 } // namespace ndn
diff --git a/tests/identity-management-fixture.hpp b/tests/identity-management-fixture.hpp
index 68a6d14..d287fc9 100644
--- a/tests/identity-management-fixture.hpp
+++ b/tests/identity-management-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -29,6 +29,7 @@
 #define NDNCERT_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
 
 #include "test-common.hpp"
+#include "test-home-fixture.hpp"
 #include <ndn-cxx/security/v2/key-chain.hpp>
 #include <ndn-cxx/security/v2/additional-description.hpp>
 #include <ndn-cxx/security/signing-helpers.hpp>
@@ -37,23 +38,38 @@
 namespace ndncert {
 namespace tests {
 
+class IdentityManagementBaseFixture : public TestHomeFixture<DefaultPibDir>
+{
+public:
+  ~IdentityManagementBaseFixture();
+
+  bool
+  saveCertToFile(const Data& obj, const std::string& filename);
+
+protected:
+  std::set<Name> m_identities;
+  std::set<std::string> m_certFiles;
+};
+
+
 /**
  * @brief A test suite level fixture to help with identity management
  *
  * Test cases in the suite can use this fixture to create identities.  Identities,
  * certificates, and saved certificates are automatically removed during test teardown.
  */
-class IdentityManagementV2Fixture
+class IdentityManagementFixture : public IdentityManagementBaseFixture
 {
 public:
-  IdentityManagementV2Fixture();
+  IdentityManagementFixture();
 
   /**
    * @brief Add identity @p identityName
    * @return name of the created self-signed certificate
    */
   security::Identity
-  addIdentity(const Name& identityName, const KeyParams& params = security::v2::KeyChain::getDefaultKeyParams());
+  addIdentity(const Name& identityName,
+              const KeyParams& params = security::v2::KeyChain::getDefaultKeyParams());
 
   /**
    *  @brief Save identity certificate to a file
@@ -62,7 +78,7 @@
    *  @return whether successful
    */
   bool
-  saveIdentityCertificate(const security::Identity& identity, const std::string& filename);
+  saveCertificate(const security::Identity& identity, const std::string& filename);
 
   /**
    * @brief Issue a certificate for \p subIdentityName signed by \p issuer
@@ -83,20 +99,15 @@
   security::v2::Certificate
   addCertificate(const security::Key& key, const std::string& issuer);
 
-  bool
-  saveCertToFile(const Data& obj, const std::string& filename);
-
 protected:
-  std::set<Name> m_identities;
-  std::set<std::string> m_certFiles;
-  security::v2::KeyChain m_keyChain;
+  KeyChain m_keyChain;
 };
 
 /** \brief convenience base class for inheriting from both UnitTestTimeFixture
  *         and IdentityManagementV2Fixture
  */
-class IdentityManagementV2TimeFixture : public UnitTestTimeFixture
-                                      , public IdentityManagementV2Fixture
+class IdentityManagementTimeFixture : public UnitTestTimeFixture
+                                    , public IdentityManagementFixture
 {
 };
 
diff --git a/tests/main.cpp b/tests/main.cpp
index d6380c6..96026e9 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -114,4 +114,4 @@
   return ::boost::unit_test::unit_test_main(&init_tests, argc, argv);
 }
 
-#endif // BOOST_VERSION >= 106200
+#endif // BOOST_VERSION >= 106200
\ No newline at end of file
diff --git a/tests/test-common.cpp b/tests/test-common.cpp
deleted file mode 100644
index 42cbf37..0000000
--- a/tests/test-common.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
- *                          Arizona Board of Regents,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University,
- *                          Washington University in St. Louis,
- *                          Beijing Institute of Technology,
- *                          The University of Memphis.
- *
- * This file, originally written as part of NFD (Named Data Networking Forwarding Daemon),
- * is a 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 "test-common.hpp"
-
-#include <ndn-cxx/util/sha256.hpp>
-#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-UnitTestTimeFixture::UnitTestTimeFixture()
-  : steadyClock(make_shared<time::UnitTestSteadyClock>())
-  , systemClock(make_shared<time::UnitTestSystemClock>())
-{
-  time::setCustomClocks(steadyClock, systemClock);
-}
-
-UnitTestTimeFixture::~UnitTestTimeFixture()
-{
-  time::setCustomClocks(nullptr, nullptr);
-}
-
-void
-UnitTestTimeFixture::advanceClocks(const time::nanoseconds& tick, size_t nTicks)
-{
-  this->advanceClocks(tick, tick * nTicks);
-}
-
-void
-UnitTestTimeFixture::advanceClocks(const time::nanoseconds& tick, const time::nanoseconds& total)
-{
-  BOOST_ASSERT(tick > time::nanoseconds::zero());
-  BOOST_ASSERT(total >= time::nanoseconds::zero());
-
-  time::nanoseconds remaining = total;
-  while (remaining > time::nanoseconds::zero()) {
-    if (remaining >= tick) {
-      steadyClock->advance(tick);
-      systemClock->advance(tick);
-      remaining -= tick;
-    }
-    else {
-      steadyClock->advance(remaining);
-      systemClock->advance(remaining);
-      remaining = time::nanoseconds::zero();
-    }
-
-    if (m_io.stopped())
-      m_io.reset();
-    m_io.poll();
-  }
-}
-
-shared_ptr<Interest>
-makeInterest(const Name& name, uint32_t nonce)
-{
-  auto interest = make_shared<Interest>(name);
-  if (nonce != 0) {
-    interest->setNonce(nonce);
-  }
-  return interest;
-}
-
-shared_ptr<Data>
-makeData(const Name& name)
-{
-  auto data = make_shared<Data>(name);
-  return signData(data);
-}
-
-Data&
-signData(Data& data)
-{
-  ndn::SignatureSha256WithRsa fakeSignature;
-  fakeSignature.setValue(ndn::encoding::makeEmptyBlock(tlv::SignatureValue));
-  data.setSignature(fakeSignature);
-  data.wireEncode();
-
-  return data;
-}
-
-shared_ptr<Link>
-makeLink(const Name& name, std::initializer_list<Delegation> delegations)
-{
-  auto link = make_shared<Link>(name, delegations);
-  signData(link);
-  return link;
-}
-
-lp::Nack
-makeNack(const Name& name, uint32_t nonce, lp::NackReason reason)
-{
-  Interest interest(name);
-  interest.setNonce(nonce);
-  lp::Nack nack(std::move(interest));
-  nack.setReason(reason);
-  return nack;
-}
-
-ConstBufferPtr
-digestFromFile(const boost::filesystem::path& filename)
-{
-  boost::filesystem::ifstream iff(filename, std::ios::in | std::ios::binary);
-  util::Sha256 digest(iff);
-  return digest.computeDigest();
-}
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index 3d5dec1..11d7feb 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2019, Regents of the University of California,
  *                          Arizona Board of Regents,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University,
@@ -28,150 +28,85 @@
 #ifndef NDNCERT_TESTS_TEST_COMMON_HPP
 #define NDNCERT_TESTS_TEST_COMMON_HPP
 
-#include "logging.hpp"
-
 #include "boost-test.hpp"
-
 #include <boost/asio/io_service.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-
-#include <ndn-cxx/link.hpp>
-#include <ndn-cxx/name.hpp>
-#include <ndn-cxx/data.hpp>
-#include <ndn-cxx/lp/nack.hpp>
 #include <ndn-cxx/util/time-unit-test-clock.hpp>
-#include <ndn-cxx/util/string-helper.hpp>
 
 namespace ndn {
 namespace ndncert {
 namespace tests {
 
-/** \brief base test fixture
- *
- *  Every test case should be based on this fixture,
- *  to have per test case io_service initialization.
+/** \brief a test fixture that overrides steady clock and system clock
  */
-class BaseFixture
+class UnitTestTimeFixture
 {
-protected:
-  /** \brief reference to global io_service
-   */
-  boost::asio::io_service m_io;
-};
+public:
+  UnitTestTimeFixture()
+    : steadyClock(make_shared<time::UnitTestSteadyClock>())
+    , systemClock(make_shared<time::UnitTestSystemClock>())
+  {
+    time::setCustomClocks(steadyClock, systemClock);
+  }
 
-/** \brief a base test fixture that overrides steady clock and system clock
- */
-class UnitTestTimeFixture : public virtual BaseFixture
-{
-protected:
-  UnitTestTimeFixture();
-
-  ~UnitTestTimeFixture();
+  ~UnitTestTimeFixture()
+  {
+    time::setCustomClocks(nullptr, nullptr);
+  }
 
   /** \brief advance steady and system clocks
    *
    *  Clocks are advanced in increments of \p tick for \p nTicks ticks.
-   *  After each tick, global io_service is polled to process pending I/O events.
+   *  After each tick, io_service is polled to process pending I/O events.
    *
    *  Exceptions thrown during I/O events are propagated to the caller.
    *  Clock advancing would stop in case of an exception.
    */
   void
-  advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1);
+  advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1)
+  {
+    this->advanceClocks(tick, tick * nTicks);
+  }
 
   /** \brief advance steady and system clocks
    *
    *  Clocks are advanced in increments of \p tick for \p total time.
    *  The last increment might be shorter than \p tick.
-   *  After each tick, global io_service is polled to process pending I/O events.
+   *  After each tick, io_service is polled to process pending I/O events.
    *
    *  Exceptions thrown during I/O events are propagated to the caller.
    *  Clock advancing would stop in case of an exception.
    */
   void
-  advanceClocks(const time::nanoseconds& tick, const time::nanoseconds& total);
+  advanceClocks(const time::nanoseconds& tick, const time::nanoseconds& total)
+  {
+    BOOST_ASSERT(tick > time::nanoseconds::zero());
+    BOOST_ASSERT(total >= time::nanoseconds::zero());
 
-protected:
+    time::nanoseconds remaining = total;
+    while (remaining > time::nanoseconds::zero()) {
+      if (remaining >= tick) {
+        steadyClock->advance(tick);
+        systemClock->advance(tick);
+        remaining -= tick;
+      }
+      else {
+        steadyClock->advance(remaining);
+        systemClock->advance(remaining);
+        remaining = time::nanoseconds::zero();
+      }
+
+      if (m_io.stopped())
+        m_io.reset();
+      m_io.poll();
+    }
+  }
+
+public:
   shared_ptr<time::UnitTestSteadyClock> steadyClock;
   shared_ptr<time::UnitTestSystemClock> systemClock;
-
-  friend class LimitedIo;
+  boost::asio::io_service m_io;
 };
 
-/** \brief create an Interest
- *  \param name Interest name
- *  \param nonce if non-zero, set Nonce to this value
- *               (useful for creating Nack with same Nonce)
- */
-shared_ptr<Interest>
-makeInterest(const Name& name, uint32_t nonce = 0);
-
-/** \brief create a Data with fake signature
- *  \note Data may be modified afterwards without losing the fake signature.
- *        If a real signature is desired, sign again with KeyChain.
- */
-shared_ptr<Data>
-makeData(const Name& name);
-
-/** \brief add a fake signature to Data
- */
-Data&
-signData(Data& data);
-
-/** \brief add a fake signature to Data
- */
-inline shared_ptr<Data>
-signData(shared_ptr<Data> data)
-{
-  signData(*data);
-  return data;
-}
-
-/** \brief create a Link object with fake signature
- *  \note Link may be modified afterwards without losing the fake signature.
- *        If a real signature is desired, sign again with KeyChain.
- */
-shared_ptr<Link>
-makeLink(const Name& name, std::initializer_list<Delegation> delegations);
-
-/** \brief create a Nack
- *  \param name Interest name
- *  \param nonce Interest nonce
- *  \param reason Nack reason
- */
-lp::Nack
-makeNack(const Name& name, uint32_t nonce, lp::NackReason reason);
-
-/** \brief replace a name component
- *  \param[inout] name name
- *  \param index name component index
- *  \param a arguments to name::Component constructor
- */
-template<typename...A>
-void
-setNameComponent(Name& name, ssize_t index, const A& ...a)
-{
-  Name name2 = name.getPrefix(index);
-  name2.append(name::Component(a...));
-  name2.append(name.getSubName(name2.size()));
-  name = name2;
-}
-
-template<typename Packet, typename...A>
-void
-setNameComponent(Packet& packet, ssize_t index, const A& ...a)
-{
-  Name name = packet.getName();
-  setNameComponent(name, index, a...);
-  packet.setName(name);
-}
-
-/** \brief convert file to digest
- */
-ndn::ConstBufferPtr
-digestFromFile(const boost::filesystem::path& filename);
-
 } // namespace tests
 } // namespace ndncert
 } // namespace ndn
diff --git a/tests/test-home-fixture.hpp b/tests/test-home-fixture.hpp
new file mode 100644
index 0000000..775e38a
--- /dev/null
+++ b/tests/test-home-fixture.hpp
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2019 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_TESTS_TEST_HOME_FIXTURE_HPP
+#define NDN_TESTS_TEST_HOME_FIXTURE_HPP
+
+#include "ndn-cxx/security/v2/key-chain.hpp"
+
+#include <cstdlib>
+#include <fstream>
+#include <initializer_list>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+/**
+ * @brief Fixture to adjust/restore NDN_CLIENT_PIB and NDN_CLIENT_TPM paths
+ *
+ * Note that the specified PATH will be removed after fixture is destroyed.
+ * **Do not specify non-temporary paths.**
+ */
+template<class Path>
+class PibDirFixture
+{
+public:
+  PibDirFixture()
+    : m_pibDir(Path().PATH)
+  {
+    if (std::getenv("NDN_CLIENT_PIB") != nullptr) {
+      m_oldPib = std::getenv("NDN_CLIENT_PIB");
+    }
+    if (std::getenv("NDN_CLIENT_TPM") != nullptr) {
+      m_oldTpm = std::getenv("NDN_CLIENT_TPM");
+    }
+
+    /// @todo Consider change to an in-memory PIB/TPM
+    setenv("NDN_CLIENT_PIB", ("pib-sqlite3:" + m_pibDir).c_str(), true);
+    setenv("NDN_CLIENT_TPM", ("tpm-file:" + m_pibDir).c_str(), true);
+  }
+
+  ~PibDirFixture()
+  {
+    if (!m_oldPib.empty()) {
+      setenv("NDN_CLIENT_PIB", m_oldPib.data(), true);
+    }
+    else {
+      unsetenv("NDN_CLIENT_PIB");
+    }
+
+    if (!m_oldTpm.empty()) {
+      setenv("NDN_CLIENT_TPM", m_oldTpm.data(), true);
+    }
+    else {
+      unsetenv("NDN_CLIENT_TPM");
+    }
+
+    boost::filesystem::remove_all(m_pibDir);
+    // const_cast<std::string&>(security::v2::KeyChain::getDefaultPibLocator()).clear();
+    // const_cast<std::string&>(security::v2::KeyChain::getDefaultTpmLocator()).clear();
+  }
+
+protected:
+  const std::string m_pibDir;
+
+private:
+  std::string m_oldPib;
+  std::string m_oldTpm;
+};
+
+/**
+ * @brief Extension of PibDirFixture to set TEST_HOME variable and allow config file creation
+ */
+template<class Path>
+class TestHomeFixture : public PibDirFixture<Path>
+{
+public:
+  TestHomeFixture()
+  {
+    setenv("TEST_HOME", this->m_pibDir.c_str(), true);
+  }
+
+  ~TestHomeFixture()
+  {
+    unsetenv("TEST_HOME");
+  }
+
+  void
+  createClientConf(std::initializer_list<std::string> lines) const
+  {
+    boost::filesystem::create_directories(boost::filesystem::path(this->m_pibDir) / ".ndn");
+    std::ofstream of((boost::filesystem::path(this->m_pibDir) / ".ndn" / "client.conf").c_str());
+    for (auto line : lines) {
+      boost::replace_all(line, "%PATH%", this->m_pibDir);
+      of << line << std::endl;
+    }
+  }
+};
+
+struct DefaultPibDir
+{
+  const std::string PATH = "build/keys";
+};
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn
+
+#endif // NDN_TESTS_TEST_HOME_FIXTURE_HPP
diff --git a/tests/unit-tests/ca-config.t.cpp b/tests/unit-tests/ca-config.t.cpp
index 1039e97..78aa9da 100644
--- a/tests/unit-tests/ca-config.t.cpp
+++ b/tests/unit-tests/ca-config.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -29,51 +29,17 @@
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestCaConfig, IdentityManagementV2Fixture)
+BOOST_FIXTURE_TEST_SUITE(TestCaConfig, IdentityManagementFixture)
 
 BOOST_AUTO_TEST_CASE(ReadConfigFileWithFileAnchor)
 {
   CaConfig config;
   config.load("tests/unit-tests/ca.conf.test");
-
-  int count = 0;
-  for (auto item : config.m_caItems) {
-    if (item.m_caName.toUri() == "/ndn") {
-      BOOST_CHECK_EQUAL(item.m_freshnessPeriod, time::seconds(720));
-      BOOST_CHECK_EQUAL(item.m_validityPeriod, time::days(360));
-      BOOST_CHECK_EQUAL(item.m_probe, "input email address");
-      BOOST_CHECK_EQUAL(item.m_caInfo, "ndn testbed ca");
-      BOOST_CHECK_EQUAL(item.m_targetedList,
-                        "Use your email address (edu preferred) as input");
-      BOOST_CHECK_EQUAL(item.m_relatedCaList.size(), 2);
-
-      // check related ca
-      auto relatedCaA = item.m_relatedCaList.front();
-      BOOST_CHECK_EQUAL(relatedCaA.toUri(), "/ndn/edu/arizona");
-      auto relatedCaB = item.m_relatedCaList.back();
-      BOOST_CHECK_EQUAL(relatedCaB.toUri(), "/ndn/edu/memphis");
-
-      BOOST_CHECK_EQUAL(count, 0);
-      count++;
-    }
-    else if (item.m_caName.toUri() == "/ndn/edu/ucla/cs/zhiyi") {
-      BOOST_CHECK_EQUAL(item.m_probe, "");
-      BOOST_CHECK_EQUAL(item.m_freshnessPeriod, time::seconds(720));
-      BOOST_CHECK_EQUAL(item.m_validityPeriod, time::days(360));
-      BOOST_CHECK_EQUAL(item.m_supportedChallenges.size(), 1);
-
-      BOOST_CHECK_EQUAL(count, 1);
-      count++;
-    }
-    else if (item.m_caName.toUri() == "/ndn/site1") {
-      BOOST_CHECK(item.m_probe != "");
-      BOOST_CHECK_EQUAL(item.m_freshnessPeriod, time::seconds(720));
-      BOOST_CHECK_EQUAL(item.m_validityPeriod, time::days(360));
-      BOOST_CHECK_EQUAL(item.m_supportedChallenges.size(), 1);
-
-      BOOST_CHECK_EQUAL(count, 2);
-    }
-  }
+  BOOST_CHECK_EQUAL(config.m_caName.toUri(), "/ndn");
+  BOOST_CHECK_EQUAL(config.m_freshnessPeriod, time::seconds(720));
+  BOOST_CHECK_EQUAL(config.m_validityPeriod, time::days(360));
+  BOOST_CHECK_EQUAL(config.m_probe, "input email address");
+  BOOST_CHECK_EQUAL(config.m_caInfo, "ndn testbed ca");
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestCaConfig
diff --git a/tests/unit-tests/ca-memory.t.cpp b/tests/unit-tests/ca-memory.t.cpp
index a717e31..3a9c2c4 100644
--- a/tests/unit-tests/ca-memory.t.cpp
+++ b/tests/unit-tests/ca-memory.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -18,15 +18,15 @@
  * See AUTHORS.md for complete list of ndncert authors and contributors.
  */
 
-#include "identity-management-fixture.hpp"
 #include "ca-detail/ca-memory.hpp"
+#include "identity-management-fixture.hpp"
 #include "ca-detail/ca-sqlite.hpp"
 
 namespace ndn {
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestCaMemory, IdentityManagementV2TimeFixture)
+BOOST_FIXTURE_TEST_SUITE(TestCaMemory, IdentityManagementFixture)
 
 BOOST_AUTO_TEST_CASE(Initialization)
 {
@@ -82,31 +82,31 @@
   auto cert1 = key1.getDefaultCertificate();
 
   // add operation
-  CertificateRequest request1(Name("/ndn/site1"), "123", cert1);
+  CertificateRequest request1(Name("/ndn/site1"), "123", STATUS_BEFORE_CHALLENGE, cert1);
   BOOST_CHECK_NO_THROW(storage.addRequest(request1));
 
   // get operation
   auto result = storage.getRequest("123");
-  BOOST_CHECK_EQUAL(request1.getCert(), result.getCert());
-  BOOST_CHECK_EQUAL(request1.getStatus(), result.getStatus());
-  BOOST_CHECK_EQUAL(request1.getCaName(), result.getCaName());
+  BOOST_CHECK_EQUAL(request1.m_cert, result.m_cert);
+  BOOST_CHECK_EQUAL(request1.m_status, result.m_status);
+  BOOST_CHECK_EQUAL(request1.m_caName, result.m_caName);
 
   JsonSection json;
   json.put("code", "1234");
 
   // update operation
-  CertificateRequest request2(Name("/ndn/site1"), "123", "need-verify", "EMAIL",
-                              CaSqlite::convertJson2String(json), cert1);
+  CertificateRequest request2(Name("/ndn/site1"), "123", STATUS_CHALLENGE, CHALLENGE_STATUS_SUCCESS,
+                             "Email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert1);
   storage.updateRequest(request2);
   result = storage.getRequest("123");
-  BOOST_CHECK_EQUAL(request2.getCert(), result.getCert());
-  BOOST_CHECK_EQUAL(request2.getStatus(), result.getStatus());
-  BOOST_CHECK_EQUAL(request2.getCaName(), result.getCaName());
+  BOOST_CHECK_EQUAL(request2.m_cert, result.m_cert);
+  BOOST_CHECK_EQUAL(request2.m_status, result.m_status);
+  BOOST_CHECK_EQUAL(request2.m_caName, result.m_caName);
 
   auto identity2 = addIdentity(Name("/ndn/site2"));
   auto key2 = identity2.getDefaultKey();
   auto cert2 = key2.getDefaultCertificate();
-  CertificateRequest request3(Name("/ndn/site2"), "456", cert2);
+  CertificateRequest request3(Name("/ndn/site2"), "456", STATUS_BEFORE_CHALLENGE, cert2);
   storage.addRequest(request3);
 
   // list operation
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index 5d23a9f..34e2721 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -19,15 +19,16 @@
  */
 
 #include "ca-module.hpp"
-
 #include "database-fixture.hpp"
 #include "client-module.hpp"
 #include "challenge-module.hpp"
-
+#include "challenge-module/challenge-pin.hpp"
+#include "challenge-module/challenge-email.hpp"
 #include <ndn-cxx/util/dummy-client-face.hpp>
 #include <ndn-cxx/security/signing-helpers.hpp>
 #include <ndn-cxx/security/transform/public-key.hpp>
 #include <ndn-cxx/security/verification-helpers.hpp>
+#include <iostream>
 
 namespace ndn {
 namespace ndncert {
@@ -39,8 +40,7 @@
 {
   util::DummyClientFace face(m_io, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-  BOOST_CHECK_EQUAL(ca.getCaConf().m_caItems.front().m_caName.toUri(), "/ndn");
-  BOOST_CHECK_EQUAL(ca.getCaConf().m_caItems.back().m_caName.toUri(), "/ndn/site1");
+  BOOST_CHECK_EQUAL(ca.getCaConf().m_caName.toUri(), "/ndn");
 
   auto identity = addIdentity(Name("/ndn/site2"));
   auto key = identity.getDefaultKey();
@@ -49,34 +49,68 @@
   BOOST_CHECK_EQUAL(ca.getCaStorage()->getCertificate("111").getIdentity(), Name("/ndn/site2"));
 
   advanceClocks(time::milliseconds(20), 60);
-  BOOST_CHECK_EQUAL(ca.m_registeredPrefixIds.size(), 4);
-  BOOST_CHECK_EQUAL(ca.m_interestFilterIds.size(), 18);
+  BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 2);
+  BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 4);
 }
 
 BOOST_AUTO_TEST_CASE(HandleProbe)
 {
-  auto identity = addIdentity(Name("/ndn/site1"));
+  auto identity = addIdentity(Name("/ndn"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
 
   util::DummyClientFace face(m_io, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-  ca.setProbeHandler(Name("/ndn/site1"), [&] (const std::string& probeInfo) {
+  ca.setProbeHandler([&] (const std::string& probeInfo) {
       return probeInfo + "example";
     });
-
   advanceClocks(time::milliseconds(20), 60);
 
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_PROBE").append("zhiyi");
-  Interest interest(interestName);
+  Interest interest("/ndn/CA/_PROBE");
+  interest.setCanBePrefix(false);
+  JsonSection paramJson;
+  paramJson.add(JSON_CLIENT_PROBE_INFO, "zhiyi");
+  interest.setApplicationParameters(ClientModule::paramFromJson(paramJson));
 
   int count = 0;
   face.onSendData.connect([&] (const Data& response) {
       count++;
       BOOST_CHECK(security::verifySignature(response, cert));
-      JsonSection contentJson = ClientModule::getJsonFromData(response);
-      BOOST_CHECK_EQUAL(contentJson.get(JSON_IDNENTIFIER, ""), "/ndn/site1/zhiyiexample");
+      auto contentJson = ClientModule::getJsonFromData(response);
+      BOOST_CHECK_EQUAL(contentJson.get<std::string>(JSON_CA_NAME), "/ndn/zhiyiexample");
+    });
+  face.receive(interest);
+
+  advanceClocks(time::milliseconds(20), 60);
+  BOOST_CHECK_EQUAL(count, 1);
+}
+
+BOOST_AUTO_TEST_CASE(HandleProbeInfo)
+{
+  auto identity = addIdentity(Name("/ndn"));
+  auto key = identity.getDefaultKey();
+  auto cert = key.getDefaultCertificate();
+
+  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";
+    });
+  advanceClocks(time::milliseconds(20), 60);
+
+  Interest interest("/ndn/CA/_PROBE/INFO");
+  interest.setCanBePrefix(false);
+
+  int count = 0;
+  face.onSendData.connect([&] (const Data& response) {
+      count++;
+      BOOST_CHECK(security::verifySignature(response, cert));
+      auto contentJson = ClientModule::getJsonFromData(response);
+      auto caItem = ClientConfig::extractCaItem(contentJson);
+      BOOST_CHECK_EQUAL(caItem.m_caName.toUri(), "/ndn");
+      BOOST_CHECK_EQUAL(caItem.m_probe, "input email address");
+      BOOST_CHECK_EQUAL(caItem.m_anchor.wireEncode(), cert.wireEncode());
+      BOOST_CHECK_EQUAL(caItem.m_caInfo, "ndn testbed ca");
     });
   face.receive(interest);
 
@@ -86,25 +120,26 @@
 
 BOOST_AUTO_TEST_CASE(HandleProbeUsingDefaultHandler)
 {
-  auto identity = addIdentity(Name("/ndn/site1"));
+  auto identity = addIdentity(Name("/ndn"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
 
   util::DummyClientFace face(m_io, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-
   advanceClocks(time::milliseconds(20), 60);
 
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_PROBE").append("zhiyi");
-  Interest interest(interestName);
+  Interest interest("/ndn/CA/_PROBE");
+  interest.setCanBePrefix(false);
+  JsonSection paramJson;
+  paramJson.add(JSON_CLIENT_PROBE_INFO, "zhiyi");
+  interest.setApplicationParameters(ClientModule::paramFromJson(paramJson));
 
   int count = 0;
   face.onSendData.connect([&] (const Data& response) {
       count++;
       BOOST_CHECK(security::verifySignature(response, cert));
-      JsonSection contentJson = ClientModule::getJsonFromData(response);
-      BOOST_CHECK_EQUAL(contentJson.get(JSON_IDNENTIFIER, ""), "/ndn/site1/zhiyi");
+      auto contentJson = ClientModule::getJsonFromData(response);
+      BOOST_CHECK(contentJson.get<std::string>(JSON_CA_NAME) != "");
     });
   face.receive(interest);
 
@@ -114,140 +149,137 @@
 
 BOOST_AUTO_TEST_CASE(HandleNew)
 {
-  auto identity = addIdentity(Name("/ndn/site1"));
+  auto identity = addIdentity(Name("/ndn"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
 
   util::DummyClientFace face(m_io, {true, true});
-  util::DummyClientFace face2(m_io, {true, true});
-
   CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
   advanceClocks(time::milliseconds(20), 60);
 
-  Name identityName("/ndn/site1");
-  identityName.append("zhiyi");
-  ClientModule client(face2, m_keyChain);
+  ClientModule client(m_keyChain);
   ClientCaItem item;
-  item.m_caName = Name("/ndn/site1/CA");
+  item.m_caName = Name("/ndn");
   item.m_anchor = cert;
   client.getClientConf().m_caItems.push_back(item);
-
-  int nClientInterest = 0;
-  int nCaData = 0;
-  int nClientCallback = 0;
-
-  face.onSendData.connect([&] (const Data& data) {
-      nCaData++;
-      JsonSection contentJson = ClientModule::getJsonFromData(data);
-      BOOST_CHECK(!contentJson.get(JSON_REQUEST_ID, "").empty());
-      face2.receive(data);
-    });
-  face2.onSendInterest.connect([&] (const Interest& interest) {
-      nClientInterest++;
-      face.receive(interest);
-    });
-
-  client.sendNew(item, identityName,
-                 [&] (const shared_ptr<RequestState> state) {
-                   nClientCallback++;
-                   BOOST_CHECK(state->m_requestId != "");
-                 },
-                 [] (const std::string& s) { BOOST_CHECK(false); });
-
-  advanceClocks(time::milliseconds(20), 60);
-
-  BOOST_CHECK_EQUAL(nClientCallback, 1);
-  BOOST_CHECK_EQUAL(nCaData, 1);
-  BOOST_CHECK_EQUAL(nClientInterest, 1);
-}
-
-BOOST_AUTO_TEST_CASE(HandleLocalhostList)
-{
-  auto identity0 = addIdentity(Name("/ndn"));
-  auto identity1 = addIdentity(Name("/ndn/edu/ucla/cs/zhiyi"));
-  auto identity2 = addIdentity(Name("/ndn/site1"));
-  m_keyChain.setDefaultIdentity(identity0);
-
-  util::DummyClientFace face(m_io, {true, true});
-  CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-
-  advanceClocks(time::milliseconds(20), 60);
-  Interest interest(Name("/localhost/CA/_LIST"));
+  auto interest = client.generateNewInterest(time::system_clock::now(),
+                                             time::system_clock::now() + time::days(10), Name("/ndn/zhiyi"));
 
   int count = 0;
   face.onSendData.connect([&] (const Data& response) {
       count++;
-      JsonSection contentJson = ClientModule::getJsonFromData(response);
-      ClientConfig clientConf;
-      clientConf.load(contentJson);
-      BOOST_CHECK_EQUAL(clientConf.m_caItems.size(), 3);
+      BOOST_CHECK(security::verifySignature(response, cert));
+      auto contentJson = ClientModule::getJsonFromData(response);
+      BOOST_CHECK(contentJson.get<std::string>(JSON_CA_ECDH) != "");
+      BOOST_CHECK(contentJson.get<std::string>(JSON_CA_SALT) != "");
+      BOOST_CHECK(contentJson.get<std::string>(JSON_CA_EQUEST_ID) != "");
+      auto challengesJson = contentJson.get_child(JSON_CA_CHALLENGES);
+      BOOST_CHECK(challengesJson.size() != 0);
+
+      client.onNewResponse(response);
+      BOOST_CHECK_EQUAL_COLLECTIONS(client.m_aesKey, client.m_aesKey + 32, ca.m_aesKey, ca.m_aesKey + 32);
     });
-  face.receive(interest);
+  face.receive(*interest);
 
   advanceClocks(time::milliseconds(20), 60);
   BOOST_CHECK_EQUAL(count, 1);
 }
 
-BOOST_AUTO_TEST_CASE(HandleList)
+BOOST_AUTO_TEST_CASE(HandleChallenge)
 {
-  auto identity0 = addIdentity(Name("/ndn"));
+  auto identity = addIdentity(Name("/ndn"));
+  auto key = identity.getDefaultKey();
+  auto cert = key.getDefaultCertificate();
+
   util::DummyClientFace face(m_io, {true, true});
   CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-
   advanceClocks(time::milliseconds(20), 60);
-  Interest interest(Name("/ndn/CA/_LIST"));
+
+  // generate NEW Interest
+  ClientModule client(m_keyChain);
+  ClientCaItem item;
+  item.m_caName = Name("/ndn");
+  item.m_anchor = cert;
+  client.getClientConf().m_caItems.push_back(item);
+  auto newInterest = client.generateNewInterest(time::system_clock::now(),
+                                                time::system_clock::now() + time::days(10), Name("/ndn/zhiyi"));
+
+  // generate CHALLENGE Interest
+  ChallengePin pinChallenge;
+  shared_ptr<Interest> challengeInterest = nullptr;
+  shared_ptr<Interest> challengeInterest2 = nullptr;
+  shared_ptr<Interest> challengeInterest3 = nullptr;
 
   int count = 0;
   face.onSendData.connect([&] (const Data& response) {
-      count++;
-      JsonSection contentJson = ClientModule::getJsonFromData(response);
-      BOOST_CHECK_EQUAL(contentJson.get_child("ca-list").size(), 2);
-      std::string schemaDataName = contentJson.get<std::string>("trust-schema");
-      BOOST_CHECK_EQUAL(schemaDataName, "TODO: add trust schema");
-    });
-  face.receive(interest);
+    if (Name("/ndn/CA/_NEW").isPrefixOf(response.getName())) {
+      auto contentJson = ClientModule::getJsonFromData(response);
+      std::cout << "Request ID " << contentJson.get<std::string>(JSON_CA_EQUEST_ID) << std::endl;
+      client.onNewResponse(response);
 
-  advanceClocks(time::milliseconds(20), 60);
-  BOOST_CHECK_EQUAL(count, 1);
-}
-
-BOOST_AUTO_TEST_CASE(HandleTargetList)
-{
-  auto identity0 = addIdentity(Name("/ndn"));
-  util::DummyClientFace face(m_io, {true, true});
-  CaModule ca(face, m_keyChain, "tests/unit-tests/ca.conf.test");
-  ca.setRecommendCaHandler(Name("/ndn"),
-    [] (const std::string& input, const std::list<Name>& list) -> std::tuple<Name, std::string> {
-      Name recommendedCa;
-      std::string identity;
-      for (auto caName : list) {
-        std::string univName = readString(caName.get(-1));
-        if (input.find(univName) != std::string::npos) {
-          recommendedCa = caName;
-          identity = input.substr(0, input.find("@"));
-        }
+      auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+      for (auto& item : paramJson) {
+        std::cout << "JSON attribute" << item.first;
+        std::cout << " : " << item.second.get<std::string>("") << std::endl;
       }
-      return std::make_tuple(recommendedCa, identity);
-    });
-
-  advanceClocks(time::milliseconds(20), 60);
-  Interest interest(Name("/ndn/CA/_LIST/example@memphis.edu"));
-
-  int count = 0;
-  face.onSendData.connect([&] (const Data& response) {
+      challengeInterest = client.generateChallengeInterest(pinChallenge.genChallengeRequestJson(client.m_status,
+                                                                                                client.m_challengeStatus,
+                                                                                                paramJson));
+    }
+    else if (Name("/ndn/CA/_CHALLENGE").isPrefixOf(response.getName()) && count == 0) {
       count++;
-      JsonSection contentJson = ClientModule::getJsonFromData(response);
-      std::string recommendedCA = contentJson.get<std::string>("recommended-ca");
-      std::string recommendedIdentity = contentJson.get<std::string>("recommended-identity");
-      std::string schemaDataName = contentJson.get<std::string>("trust-schema");
-      BOOST_CHECK_EQUAL(recommendedCA, "/ndn/edu/memphis");
-      BOOST_CHECK_EQUAL(recommendedIdentity, "example");
-      BOOST_CHECK_EQUAL(schemaDataName, "TODO: add trust schema");
-    });
-  face.receive(interest);
+      BOOST_CHECK(security::verifySignature(response, cert));
 
+      client.onChallengeResponse(response);
+      BOOST_CHECK_EQUAL(client.m_status, STATUS_CHALLENGE);
+      BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::NEED_CODE);
+      auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+      for (auto& item : paramJson) {
+        std::cout << "JSON attribute" << item.first;
+        std::cout << " : " << item.second.get<std::string>("") << std::endl;
+      }
+      challengeInterest2 = client.generateChallengeInterest(pinChallenge.genChallengeRequestJson(client.m_status,
+                                                                                                 client.m_challengeStatus,
+                                                                                                 paramJson));
+    }
+    else if (Name("/ndn/CA/_CHALLENGE").isPrefixOf(response.getName()) && count == 1) {
+      count++;
+      BOOST_CHECK(security::verifySignature(response, cert));
+
+      client.onChallengeResponse(response);
+      BOOST_CHECK_EQUAL(client.m_status, STATUS_CHALLENGE);
+      BOOST_CHECK_EQUAL(client.m_challengeStatus, ChallengePin::WRONG_CODE);
+      auto paramJson = pinChallenge.getRequirementForChallenge(client.m_status, client.m_challengeStatus);
+      auto request = ca.getCertificateRequest(*challengeInterest2);
+      auto secret = request.m_challengeSecrets.get(ChallengePin::JSON_PIN_CODE, "");
+      for (auto& item : paramJson) {
+        std::cout << "JSON attribute" << item.first;
+        std::cout << " : " << item.second.get<std::string>("") << std::endl;
+        if (item.first == ChallengePin::JSON_PIN_CODE)
+          item.second.put("", secret);
+      }
+      challengeInterest3 = client.generateChallengeInterest(pinChallenge.genChallengeRequestJson(client.m_status,
+                                                                                                 client.m_challengeStatus,
+                                                                                                 paramJson));
+    }
+    else if (Name("/ndn/CA/_CHALLENGE").isPrefixOf(response.getName()) && count == 2) {
+      count++;
+      BOOST_CHECK(security::verifySignature(response, cert));
+
+      client.onChallengeResponse(response);
+      BOOST_CHECK_EQUAL(client.m_status, STATUS_SUCCESS);
+      BOOST_CHECK_EQUAL(client.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
+    }
+    });
+  face.receive(*newInterest);
   advanceClocks(time::milliseconds(20), 60);
-  BOOST_CHECK_EQUAL(count, 1);
+  face.receive(*challengeInterest);
+  advanceClocks(time::milliseconds(20), 60);
+  face.receive(*challengeInterest2);
+  advanceClocks(time::milliseconds(20), 60);
+  face.receive(*challengeInterest3);
+  advanceClocks(time::milliseconds(20), 60);
+  BOOST_CHECK_EQUAL(count, 3);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestCaModule
diff --git a/tests/unit-tests/ca-sqlite.t.cpp b/tests/unit-tests/ca-sqlite.t.cpp
index be4b54d..e1c8495 100644
--- a/tests/unit-tests/ca-sqlite.t.cpp
+++ b/tests/unit-tests/ca-sqlite.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -18,8 +18,8 @@
  * See AUTHORS.md for complete list of ndncert authors and contributors.
  */
 
-#include "database-fixture.hpp"
 #include "ca-detail/ca-sqlite.hpp"
+#include "database-fixture.hpp"
 
 namespace ndn {
 namespace ndncert {
@@ -81,31 +81,30 @@
   auto cert1 = key1.getDefaultCertificate();
 
   // add operation
-  CertificateRequest request1(Name("/ndn/site1"), "123", cert1);
+  CertificateRequest request1(Name("/ndn/site1"), "123", STATUS_BEFORE_CHALLENGE, cert1);
   BOOST_CHECK_NO_THROW(storage.addRequest(request1));
 
   // get operation
   auto result = storage.getRequest("123");
-  BOOST_CHECK_EQUAL(request1.getCert(), result.getCert());
-  BOOST_CHECK_EQUAL(request1.getStatus(), result.getStatus());
-  BOOST_CHECK_EQUAL(request1.getCaName(), result.getCaName());
-
-  JsonSection json;
-  json.put("code", "1234");
+  BOOST_CHECK_EQUAL(request1.m_cert, result.m_cert);
+  BOOST_CHECK_EQUAL(request1.m_status, result.m_status);
+  BOOST_CHECK_EQUAL(request1.m_caName, result.m_caName);
 
   // update operation
-  CertificateRequest request2(Name("/ndn/site1"), "123", "need-verify", "EMAIL",
-                              CaSqlite::convertJson2String(json), cert1);
+  JsonSection json;
+  json.put("test", "4567");
+  CertificateRequest request2(Name("/ndn/site1"), "123", STATUS_CHALLENGE, CHALLENGE_STATUS_SUCCESS,
+                             "Email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert1);
   storage.updateRequest(request2);
   result = storage.getRequest("123");
-  BOOST_CHECK_EQUAL(request2.getCert(), result.getCert());
-  BOOST_CHECK_EQUAL(request2.getStatus(), result.getStatus());
-  BOOST_CHECK_EQUAL(request2.getCaName(), result.getCaName());
+  BOOST_CHECK_EQUAL(request2.m_cert, result.m_cert);
+  BOOST_CHECK_EQUAL(request2.m_status, result.m_status);
+  BOOST_CHECK_EQUAL(request2.m_caName, result.m_caName);
 
   auto identity2 = addIdentity(Name("/ndn/site2"));
   auto key2 = identity2.getDefaultKey();
   auto cert2 = key2.getDefaultCertificate();
-  CertificateRequest request3(Name("/ndn/site2"), "456", cert2);
+  CertificateRequest request3(Name("/ndn/site2"), "456", STATUS_BEFORE_CHALLENGE, cert2);
   storage.addRequest(request3);
 
   // list operation
diff --git a/tests/unit-tests/ca.conf.test b/tests/unit-tests/ca.conf.test
index 5809613..15b497f 100644
--- a/tests/unit-tests/ca.conf.test
+++ b/tests/unit-tests/ca.conf.test
@@ -1,44 +1,12 @@
 {
-  "ca-list":
+  "ca-prefix": "/ndn",
+  "issuing-freshness": "720",
+  "validity-period": "360",
+  "ca-info": "ndn testbed ca",
+
+  "probe": "input email address",
+  "supported-challenges":
   [
-    {
-        "ca-prefix": "/ndn",
-        "issuing-freshness": "720",
-        "validity-period": "360",
-        "ca-info": "ndn testbed ca",
-
-        "probe": "input email address",
-
-        "targeted-list": "Use your email address (edu preferred) as input",
-        "related-ca-list":
-        [
-          { "ca-prefix": "/ndn/edu/arizona" },
-          { "ca-prefix": "/ndn/edu/memphis" }
-        ],
-
-        "supported-challenges":
-        [
-            { "type": "PIN" }
-        ]
-    },
-    {
-        "ca-prefix": "/ndn/edu/ucla/cs/zhiyi",
-        "issuing-freshness": "720",
-        "validity-period": "360",
-        "supported-challenges":
-        [
-            { "type": "PIN" }
-        ]
-    },
-    {
-        "ca-prefix": "/ndn/site1",
-        "probe": "input email address",
-        "issuing-freshness": "720",
-        "validity-period": "360",
-        "supported-challenges":
-        [
-            { "type": "PIN" }
-        ]
-    }
+      { "type": "PIN" }
   ]
 }
\ No newline at end of file
diff --git a/tests/unit-tests/certificate-request.t.cpp b/tests/unit-tests/certificate-request.t.cpp
deleted file mode 100644
index 3282ee9..0000000
--- a/tests/unit-tests/certificate-request.t.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017, 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 "identity-management-fixture.hpp"
-#include "certificate-request.hpp"
-#include <boost/lexical_cast.hpp>
-#include <ndn-cxx/util/io.hpp>
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(TestCertificateRequest, IdentityManagementV2Fixture)
-
-BOOST_AUTO_TEST_CASE(Constructor)
-{
-  auto identity = addIdentity(Name("/ndn/site1"));
-  auto key = identity.getDefaultKey();
-  auto cert = key.getDefaultCertificate();
-
-  CertificateRequest request1(Name("/ndn/site1"), "123", cert);
-  BOOST_CHECK_EQUAL(request1.getCaName().toUri(), "/ndn/site1");
-  BOOST_CHECK_EQUAL(request1.getRequestId(), "123");
-  BOOST_CHECK_EQUAL(request1.getStatus(), "");
-  BOOST_CHECK_EQUAL(request1.getChallengeSecrets().empty(), true);
-  BOOST_CHECK_EQUAL(request1.getCert(), cert);
-  BOOST_CHECK_EQUAL(request1.getCert(), cert);
-
-  JsonSection json;
-  json.put("code", "1234");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, json);
-  std::string jsonValue = ss.str();
-
-  CertificateRequest request2(Name("/ndn/site1"), "123", "need-verify", "EMAIL", jsonValue, cert);
-  BOOST_CHECK_EQUAL(request2.getCaName().toUri(), "/ndn/site1");
-  BOOST_CHECK_EQUAL(request2.getRequestId(), "123");
-  BOOST_CHECK_EQUAL(request2.getStatus(), "need-verify");
-  BOOST_CHECK_EQUAL(request2.getChallengeType(), "EMAIL");
-  BOOST_CHECK(request2.getChallengeSecrets() == json);
-  BOOST_CHECK_EQUAL(request2.getCert(), cert);
-}
-
-BOOST_AUTO_TEST_CASE(GetterSetter)
-{
-  auto identity = addIdentity(Name("/ndn/site1"));
-  auto key = identity.getDefaultKey();
-  auto cert = key.getDefaultCertificate();
-
-  JsonSection json;
-  json.put("code", "1234");
-
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-  request.setStatus("need-verify");
-  request.setChallengeType("EMAIL");
-  request.setChallengeSecrets(json);
-
-  BOOST_CHECK_EQUAL(request.getStatus(), "need-verify");
-  BOOST_CHECK_EQUAL(request.getChallengeType(), "EMAIL");
-  BOOST_CHECK(request.getChallengeSecrets() == json);
-}
-
-BOOST_AUTO_TEST_CASE(GetCertificateRequestOutput)
-{
-  const std::string certString = R"_CERT_(
-Bv0BuwczCANuZG4IBXNpdGUxCANLRVkIEWtzay0xNDE2NDI1Mzc3MDk0CAQwMTIz
-CAf9AAABScmLFAkYAQIZBAA27oAVoDCBnTANBgkqhkiG9w0BAQEFAAOBiwAwgYcC
-gYEAngY+R4WyNDeqhUesAySDtZyoBTokHuuJAbvpm7LDIqxo4/BsAs5opsTQpwaQ
-nKobCB2LQ5ozZ0RtIaMbiJqXXlnEFQvZLL1RB2GCrcG417+bz30kwmPzlxfr/mIl
-ultNisJ6vUOKj7jy8cVqMNNQjMia3+/tNed6Yup2fLsIJscCAREWVRsBARwmByQI
-A25kbggFc2l0ZTEIA0tFWQgRa3NrLTI1MTY0MjUzNzcwOTT9AP0m/QD+DzIwMTUw
-ODE0VDIyMzczOf0A/w8yMDE1MDgxOFQyMjM3MzgXgP//////////////////////
-////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////
-////////////////////)_CERT_";
-
-  const std::string expectedString = R"_REQUEST_(Request CA name:
-  /ndn/site1
-Request ID:
-  123
-Certificate:
-  Certificate name:
-    /ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B
-  Validity:
-    NotBefore: 20150814T223739
-    NotAfter: 20150818T223738
-  Public key bits:
-    MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCeBj5HhbI0N6qFR6wDJIO1nKgF
-    OiQe64kBu+mbssMirGjj8GwCzmimxNCnBpCcqhsIHYtDmjNnRG0hoxuImpdeWcQV
-    C9ksvVEHYYKtwbjXv5vPfSTCY/OXF+v+YiW6W02Kwnq9Q4qPuPLxxWow01CMyJrf
-    7+0153pi6nZ8uwgmxwIBEQ==
-  Signature Information:
-    Signature Type: SignatureSha256WithRsa
-    Key Locator: Name=/ndn/site1/KEY/ksk-2516425377094
-)_REQUEST_";
-
-  std::stringstream ss;
-  ss << certString;
-  auto cert = io::load<security::v2::Certificate>(ss);
-  CertificateRequest request(Name("/ndn/site1"), "123", *cert);
-
-  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(request), expectedString);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/unit-tests/challenge-credential.t.cpp b/tests/unit-tests/challenge-credential.t.cpp
index 772c57f..2455e73 100644
--- a/tests/unit-tests/challenge-credential.t.cpp
+++ b/tests/unit-tests/challenge-credential.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -18,8 +18,8 @@
  * See AUTHORS.md for complete list of ndncert authors and contributors.
  */
 
-#include "identity-management-fixture.hpp"
 #include "challenge-module/challenge-credential.hpp"
+#include "identity-management-fixture.hpp"
 #include <ndn-cxx/security/signing-helpers.hpp>
 #include <ndn-cxx/util/io.hpp>
 
@@ -27,7 +27,7 @@
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestChallengeCredential, IdentityManagementV2Fixture)
+BOOST_FIXTURE_TEST_SUITE(TestChallengeCredential, IdentityManagementFixture)
 
 BOOST_AUTO_TEST_CASE(LoadConfig)
 {
@@ -41,7 +41,7 @@
                     "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5");
 }
 
-BOOST_AUTO_TEST_CASE(HandleSelect)
+BOOST_AUTO_TEST_CASE(HandleChallengeRequest)
 {
   // create trust anchor
   ChallengeCredential challenge("./tests/unit-tests/challenge-credential.conf.test");
@@ -55,7 +55,7 @@
   auto identityA = addIdentity(Name("/example"));
   auto keyA = identityA.getDefaultKey();
   auto certA = key.getDefaultCertificate();
-  CertificateRequest request(Name("/example"), "123", certA);
+  CertificateRequest request(Name("/example"), "123", STATUS_BEFORE_CHALLENGE, certA);
 
   // create requester's existing cert
   auto identityB = addIdentity(Name("/trust/cert"));
@@ -65,43 +65,35 @@
   // using trust anchor to sign cert request to get credential
   Name credentialName = certB.getKeyName();
   credentialName.append("Credential").appendVersion();
-  security::v2::Certificate credential = certB;
-  credential.setName(credentialName);
-  credential.setContent(certB.getContent());
-  m_keyChain.sign(credential, signingByCertificate(trustAnchor));
+  security::v2::Certificate selfSigned;
+  selfSigned.setName(credentialName);
+  selfSigned.setContent(makeStringBlock(tlv::Content, "123"));
+  m_keyChain.sign(selfSigned, signingByCertificate(trustAnchor));
 
   // generate SELECT interest
   std::stringstream ss;
-  io::save<security::v2::Certificate>(credential, ss);
+  io::save<security::v2::Certificate>(selfSigned, ss);
   auto checkCert = *(io::load<security::v2::Certificate>(ss));
-  BOOST_CHECK_EQUAL(checkCert, credential);
+  BOOST_CHECK_EQUAL(checkCert, selfSigned);
   ss.str("");
   ss.clear();
 
-  std::list<std::string> paramList;
-  io::save<security::v2::Certificate>(credential, ss);
-  std::string paramString = ss.str();
-  paramList.push_back(paramString);
+  JsonSection params;
+  io::save<security::v2::Certificate>(selfSigned, ss);
+  std::string selfSignedStr = ss.str();
+  params.add(ChallengeCredential::JSON_CREDENTIAL_SELF, selfSignedStr);
   ss.str("");
   ss.clear();
 
   io::save<security::v2::Certificate>(certB, ss);
-  paramString = ss.str();
-  paramList.push_back(paramString);
+  std::string credentialStr = ss.str();
+  params.add(ChallengeCredential::JSON_CREDENTIAL_CERT, credentialStr);
   ss.str("");
   ss.clear();
-  JsonSection credentialJson = challenge.genSelectParamsJson(ChallengeModule::WAIT_SELECTION, paramList);
 
-  boost::property_tree::write_json(ss, credentialJson);
-  Block jsonContent = makeStringBlock(ndn::tlv::NameComponent, ss.str());
-
-  Name interestName("/example/CA");
-  interestName.append("_SELECT").append("Fake-Request-ID").append("CREDENTIAL").append(jsonContent);
-  Interest interest(interestName);
-
-  challenge.processSelectInterest(interest, request);
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeModule::SUCCESS);
-  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), true);
+  challenge.handleChallengeRequest(params, request);
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_PENDING);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit-tests/challenge-email.t.cpp b/tests/unit-tests/challenge-email.t.cpp
index f723f6a..3b9850c 100644
--- a/tests/unit-tests/challenge-email.t.cpp
+++ b/tests/unit-tests/challenge-email.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017-2018, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -25,7 +25,7 @@
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestChallengeEmail, IdentityManagementV2Fixture)
+BOOST_FIXTURE_TEST_SUITE(TestChallengeEmail, IdentityManagementFixture)
 
 BOOST_AUTO_TEST_CASE(TestChallengeType)
 {
@@ -33,20 +33,6 @@
   BOOST_CHECK_EQUAL(challenge.CHALLENGE_TYPE, "Email");
 }
 
-BOOST_AUTO_TEST_CASE(ParseStoredSecret)
-{
-  time::system_clock::TimePoint tp = time::fromIsoString("20170207T120000");
-  JsonSection json;
-  json.put(ChallengeEmail::JSON_CODE_TP, time::toIsoString(tp));
-  json.put(ChallengeEmail::JSON_CODE, "1234");
-  json.put(ChallengeEmail::JSON_ATTEMPT_TIMES, std::to_string(3));
-
-  auto result = ChallengeEmail::parseStoredSecrets(json);
-  BOOST_CHECK_EQUAL(std::get<0>(result), tp);
-  BOOST_CHECK_EQUAL(std::get<1>(result), "1234");
-  BOOST_CHECK_EQUAL(std::get<2>(result), 3);
-}
-
 BOOST_AUTO_TEST_CASE(EmailAddressChecker)
 {
   BOOST_CHECK_EQUAL(ChallengeEmail::isValidEmailAddress("zhiyi@cs.ucla.edu"), true);
@@ -54,28 +40,26 @@
   BOOST_CHECK_EQUAL(ChallengeEmail::isValidEmailAddress("zhiyi.ucla.edu"), false);
 }
 
-BOOST_AUTO_TEST_CASE(OnSelectInterestComingWithEmail)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithEmail)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_BEFORE_CHALLENGE, cert);
 
   JsonSection emailJson;
   emailJson.put(ChallengeEmail::JSON_EMAIL, "zhiyi@cs.ucla.edu");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, emailJson);
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_SELECT").append("Fake-Request-ID").append("EMAIL").append(jsonContent);
-  Interest interest(interestName);
 
   ChallengeEmail challenge("./tests/unit-tests/test-send-email.sh");
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(emailJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeEmail::NEED_CODE);
-  BOOST_CHECK_EQUAL(request.getChallengeType(), "Email");
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_CHALLENGE);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengeEmail::NEED_CODE);
+  BOOST_CHECK(request.m_challengeSecrets.get<std::string>(ChallengeEmail::JSON_CODE) != "");
+  BOOST_CHECK(request.m_remainingTime != 0);
+  BOOST_CHECK(request.m_remainingTries != 0);
+  BOOST_CHECK(request.m_challengeTp != "");
+  BOOST_CHECK_EQUAL(request.m_challengeType, "Email");
 
   std::string line = "";
   std::string delimiter = " ";
@@ -89,68 +73,47 @@
   std::string secret = line.substr(line.find(delimiter) + 1);
 
   BOOST_CHECK_EQUAL(recipientEmail, "zhiyi@cs.ucla.edu");
-  auto stored_secret = request.getChallengeSecrets().get<std::string>(ChallengeEmail::JSON_CODE);
+  auto stored_secret = request.m_challengeSecrets.get<std::string>(ChallengeEmail::JSON_CODE);
   BOOST_CHECK_EQUAL(secret, stored_secret);
-
   std::remove("tmp.txt");
 }
 
-BOOST_AUTO_TEST_CASE(OnSelectInterestComingWithInvalidEmail)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithInvalidEmail)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_BEFORE_CHALLENGE, cert);
 
   JsonSection emailJson;
   emailJson.put(ChallengeEmail::JSON_EMAIL, "zhiyi@cs");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, emailJson);
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_SELECT").append("Fake-Request-ID").append("EMAIL").append(jsonContent);
-  Interest interest(interestName);
 
   ChallengeEmail challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(emailJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeEmail::FAILURE_INVALID_EMAIL);
-  BOOST_CHECK_EQUAL(request.getChallengeType(), "Email");
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengeEmail::FAILURE_INVALID_EMAIL);
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_FAILURE);
 }
 
-BOOST_AUTO_TEST_CASE(OnValidateInterestComingWithCode)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithCode)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-  request.setChallengeType("EMAIL");
-  request.setStatus(ChallengeEmail::NEED_CODE);
-
-  time::system_clock::TimePoint tp = time::system_clock::now();
   JsonSection json;
-  json.put(ChallengeEmail::JSON_CODE_TP, time::toIsoString(tp));
   json.put(ChallengeEmail::JSON_CODE, "4567");
-  json.put(ChallengeEmail::JSON_ATTEMPT_TIMES, std::to_string(3));
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_CHALLENGE, ChallengeEmail::NEED_CODE,
+                             "Email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert);
 
-  request.setChallengeSecrets(json);
-
-  JsonSection infoJson;
-  infoJson.put(ChallengeEmail::JSON_CODE, "4567");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, infoJson);
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_VALIDATE").append("Fake-Request-ID").append("EMAIL").append(jsonContent);
-  Interest interest(interestName);
+  JsonSection requestJson;
+  requestJson.put(ChallengeEmail::JSON_CODE, "4567");
 
   ChallengeEmail challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(requestJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeModule::SUCCESS);
-  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), true);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_PENDING);
+  BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), true);
 }
 
 BOOST_AUTO_TEST_CASE(OnValidateInterestComingWithWrongCode)
@@ -158,61 +121,20 @@
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-  request.setChallengeType("EMAIL");
-  request.setStatus(ChallengeEmail::NEED_CODE);
-
-  time::system_clock::TimePoint tp = time::system_clock::now();
   JsonSection json;
-  json.put(ChallengeEmail::JSON_CODE_TP, time::toIsoString(tp));
   json.put(ChallengeEmail::JSON_CODE, "4567");
-  json.put(ChallengeEmail::JSON_ATTEMPT_TIMES, std::to_string(3));
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_CHALLENGE, ChallengeEmail::NEED_CODE,
+                             "Email", time::toIsoString(time::system_clock::now()), 3600, 3, json, cert);
 
-  request.setChallengeSecrets(json);
-
-  JsonSection infoJson;
-  infoJson.put(ChallengeEmail::JSON_CODE, "1234");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, infoJson);
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_VALIDATE").append("Fake-Request-ID").append("EMAIL").append(jsonContent);
-  Interest interest(interestName);
+  JsonSection requestJson;
+  requestJson.put(ChallengeEmail::JSON_CODE, "7890");
 
   ChallengeEmail challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(requestJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeEmail::WRONG_CODE);
-  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), false);
-}
-
-BOOST_AUTO_TEST_CASE(ClientSendSelect)
-{
-  ChallengeEmail challenge;
-  auto requirementList = challenge.getSelectRequirements();
-  BOOST_CHECK_EQUAL(requirementList.size(), 1);
-
-  requirementList.clear();
-  requirementList.push_back("zhiyi@cs.ucla.edu");
-
-  auto json = challenge.genSelectParamsJson(ChallengeModule::WAIT_SELECTION, requirementList);
-  BOOST_CHECK_EQUAL(json.empty(), false);
-  BOOST_CHECK_EQUAL(json.get<std::string>(ChallengeEmail::JSON_EMAIL), "zhiyi@cs.ucla.edu");
-}
-
-BOOST_AUTO_TEST_CASE(ClientSendValidate)
-{
-  ChallengeEmail challenge;
-  auto requirementList = challenge.getValidateRequirements(ChallengeEmail::NEED_CODE);
-  BOOST_CHECK_EQUAL(requirementList.size(), 1);
-
-  requirementList.clear();
-  requirementList.push_back("123");
-
-  auto json = challenge.genValidateParamsJson(ChallengeEmail::NEED_CODE, requirementList);
-  BOOST_CHECK_EQUAL(json.empty(), false);
-  BOOST_CHECK_EQUAL(json.get<std::string>(ChallengeEmail::JSON_CODE), "123");
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengeEmail::WRONG_CODE);
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_CHALLENGE);
+  BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), false);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit-tests/challenge-module.t.cpp b/tests/unit-tests/challenge-module.t.cpp
deleted file mode 100644
index 570aab1..0000000
--- a/tests/unit-tests/challenge-module.t.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017, 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 "boost-test.hpp"
-#include "challenge-module.hpp"
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(TestChallengeModule)
-
-BOOST_AUTO_TEST_CASE(GetJsonFromNameComponent)
-{
-  JsonSection json;
-  json.put("test", "123");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, json);
-  std::string jsonString = ss.str();
-  Block jsonContent = makeStringBlock(ndn::tlv::NameComponent, ss.str());
-
-  Name name("ndn");
-  name.append(jsonContent);
-  BOOST_CHECK(ChallengeModule::getJsonFromNameComponent(name, 1) == json);
-}
-
-BOOST_AUTO_TEST_CASE(GenDownloadName)
-{
-  Name interestName = ChallengeModule::genDownloadName(Name("ca"), "123");
-  BOOST_CHECK_EQUAL(interestName.getSubName(0, 1), Name("ca"));
-  BOOST_CHECK_EQUAL(interestName.getSubName(1, 1), Name("_DOWNLOAD"));
-
-  JsonSection json;
-  json.put(JSON_REQUEST_ID, "123");
-  BOOST_CHECK(ChallengeModule::getJsonFromNameComponent(interestName, 2) == json);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn
diff --git a/tests/unit-tests/challenge-pin.t.cpp b/tests/unit-tests/challenge-pin.t.cpp
index 2b7e377..95c7259 100644
--- a/tests/unit-tests/challenge-pin.t.cpp
+++ b/tests/unit-tests/challenge-pin.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017-2018, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -25,7 +25,7 @@
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestChallengePin, IdentityManagementV2Fixture)
+BOOST_FIXTURE_TEST_SUITE(TestChallengePin, IdentityManagementFixture)
 
 BOOST_AUTO_TEST_CASE(TestGetInitInfo)
 {
@@ -33,130 +33,61 @@
   BOOST_CHECK_EQUAL(challenge.CHALLENGE_TYPE, "PIN");
 }
 
-BOOST_AUTO_TEST_CASE(ParseStoredSecret)
-{
-  time::system_clock::TimePoint tp = time::fromIsoString("20170207T120000");
-  JsonSection json;
-  json.put(ChallengePin::JSON_CODE_TP, time::toIsoString(tp));
-  json.put(ChallengePin::JSON_PIN_CODE, "1234");
-  json.put(ChallengePin::JSON_ATTEMPT_TIMES, std::to_string(3));
-
-  auto result = ChallengePin::parseStoredSecrets(json);
-  BOOST_CHECK_EQUAL(std::get<0>(result), tp);
-  BOOST_CHECK_EQUAL(std::get<1>(result), "1234");
-  BOOST_CHECK_EQUAL(std::get<2>(result), 3);
-}
-
-BOOST_AUTO_TEST_CASE(OnSelectInterestComingWithEmptyInfo)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithEmptyInfo)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_SELECT").append("Fake-Request-ID").append("PIN");
-  Interest interest(interestName);
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_BEFORE_CHALLENGE, cert);
 
   ChallengePin challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(JsonSection(), request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengePin::NEED_CODE);
-  BOOST_CHECK_EQUAL(request.getChallengeType(), "PIN");
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_CHALLENGE);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengePin::NEED_CODE);
+  BOOST_CHECK_EQUAL(request.m_challengeType, "PIN");
 }
 
-BOOST_AUTO_TEST_CASE(OnValidateInterestComingWithCode)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithCode)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-  request.setChallengeType("PIN");
-  request.setStatus(ChallengePin::NEED_CODE);
+  JsonSection secret;
+  secret.add(ChallengePin::JSON_PIN_CODE, "12345");
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_CHALLENGE, ChallengePin::NEED_CODE, "PIN",
+                             time::toIsoString(time::system_clock::now()), 3600, 3, secret, cert);
 
-  time::system_clock::TimePoint tp = time::system_clock::now();
-  JsonSection json;
-  json.put(ChallengePin::JSON_CODE_TP, time::toIsoString(tp));
-  json.put(ChallengePin::JSON_PIN_CODE, "1234");
-  json.put(ChallengePin::JSON_ATTEMPT_TIMES, std::to_string(3));
-
-  request.setChallengeSecrets(json);
-
-  JsonSection infoJson;
-  infoJson.put(ChallengePin::JSON_PIN_CODE, "1234");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, infoJson);
-  std::string jsonString = ss.str();
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_VALIDATE").append("Fake-Request-ID").append("PIN").append(jsonContent);
-  Interest interest(interestName);
+  JsonSection paramJson;
+  paramJson.put(ChallengePin::JSON_PIN_CODE, "12345");
 
   ChallengePin challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(paramJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeModule::SUCCESS);
-  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), true);
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_PENDING);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, CHALLENGE_STATUS_SUCCESS);
+  BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), true);
 }
 
-BOOST_AUTO_TEST_CASE(OnValidateInterestComingWithWrongCode)
+BOOST_AUTO_TEST_CASE(OnChallengeRequestWithWrongCode)
 {
   auto identity = addIdentity(Name("/ndn/site1"));
   auto key = identity.getDefaultKey();
   auto cert = key.getDefaultCertificate();
-  CertificateRequest request(Name("/ndn/site1"), "123", cert);
-  request.setChallengeType("PIN");
-  request.setStatus(ChallengePin::NEED_CODE);
+  JsonSection secret;
+  secret.add(ChallengePin::JSON_PIN_CODE, "12345");
+  CertificateRequest request(Name("/ndn/site1"), "123", STATUS_CHALLENGE, ChallengePin::NEED_CODE, "PIN",
+                             time::toIsoString(time::system_clock::now()), 3600, 3, secret, cert);
 
-  time::system_clock::TimePoint tp = time::system_clock::now();
-  JsonSection json;
-  json.put(ChallengePin::JSON_CODE_TP, time::toIsoString(tp));
-  json.put(ChallengePin::JSON_PIN_CODE, "1234");
-  json.put(ChallengePin::JSON_ATTEMPT_TIMES, std::to_string(3));
-
-  request.setChallengeSecrets(json);
-
-  JsonSection infoJson;
-  infoJson.put(ChallengePin::JSON_PIN_CODE, "4567");
-  std::stringstream ss;
-  boost::property_tree::write_json(ss, infoJson);
-  std::string jsonString = ss.str();
-  Block jsonContent = makeStringBlock(ndn::tlv::GenericNameComponent, ss.str());
-
-  Name interestName("/ndn/site1/CA");
-  interestName.append("_VALIDATE").append("Fake-Request-ID").append("PIN").append(jsonContent);
-  Interest interest(interestName);
+  JsonSection paramJson;
+  paramJson.put(ChallengePin::JSON_PIN_CODE, "45678");
 
   ChallengePin challenge;
-  challenge.handleChallengeRequest(interest, request);
+  challenge.handleChallengeRequest(paramJson, request);
 
-  BOOST_CHECK_EQUAL(request.getStatus(), ChallengePin::WRONG_CODE);
-  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), false);
-}
-
-BOOST_AUTO_TEST_CASE(ClientSendSelect)
-{
-  ChallengePin challenge;
-  auto requirementList = challenge.getSelectRequirements();
-  BOOST_CHECK_EQUAL(requirementList.size(), 0);
-
-  auto json = challenge.doGenSelectParamsJson(ChallengeModule::WAIT_SELECTION, requirementList);
-  BOOST_CHECK_EQUAL(json.empty(), true);
-}
-
-BOOST_AUTO_TEST_CASE(ClientSendValidate)
-{
-  ChallengePin challenge;
-  auto requirementList = challenge.getValidateRequirements(ChallengePin::NEED_CODE);
-  BOOST_CHECK_EQUAL(requirementList.size(), 1);
-
-  requirementList.clear();
-  requirementList.push_back("123");
-
-  auto json = challenge.doGenValidateParamsJson(ChallengePin::NEED_CODE, requirementList);
-  BOOST_CHECK_EQUAL(json.empty(), false);
-  BOOST_CHECK_EQUAL(json.get<std::string>(ChallengePin::JSON_PIN_CODE), "123");
+  BOOST_CHECK_EQUAL(request.m_status, STATUS_CHALLENGE);
+  BOOST_CHECK_EQUAL(request.m_challengeStatus, ChallengePin::WRONG_CODE);
+  BOOST_CHECK_EQUAL(request.m_challengeSecrets.empty(), false);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit-tests/client-config.t.cpp b/tests/unit-tests/client-config.t.cpp
index c057023..5f7c3a5 100644
--- a/tests/unit-tests/client-config.t.cpp
+++ b/tests/unit-tests/client-config.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017-2018, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -38,8 +38,6 @@
   BOOST_CHECK_EQUAL(item.m_caName.toUri(), "/ndn/edu/ucla/CA");
   BOOST_CHECK_EQUAL(item.m_caInfo, "UCLA's ceritificate authority, located in BH4805.");
   BOOST_CHECK_EQUAL(item.m_probe, "Please use your email address to apply a namespace first. UCLA email is preferred.");
-  BOOST_CHECK_EQUAL(item.m_targetedList, "Use your email address (edu preferred) as input");
-  BOOST_CHECK_EQUAL(item.m_isListEnabled, true);
   BOOST_CHECK_EQUAL(item.m_anchor.getName().toUri(),
                     "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5");
 
@@ -55,7 +53,6 @@
   item.m_caName = Name("/test");
   item.m_caInfo = "test";
   item.m_probe = "test";
-  item.m_isListEnabled = false;
 
   config.m_caItems.push_back(item);
   BOOST_CHECK_EQUAL(config.m_caItems.size(), 3);
diff --git a/tests/unit-tests/client-module.t.cpp b/tests/unit-tests/client-module.t.cpp
index b65b09b..da08d9b 100644
--- a/tests/unit-tests/client-module.t.cpp
+++ b/tests/unit-tests/client-module.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017-2018, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -21,6 +21,7 @@
 #include "client-module.hpp"
 #include "identity-management-fixture.hpp"
 #include "challenge-module.hpp"
+#include "ca-module.hpp"
 #include <ndn-cxx/util/dummy-client-face.hpp>
 #include <ndn-cxx/security/signing-helpers.hpp>
 #include <ndn-cxx/security/transform/public-key.hpp>
@@ -30,20 +31,18 @@
 namespace ndncert {
 namespace tests {
 
-BOOST_FIXTURE_TEST_SUITE(TestClientModule, IdentityManagementV2TimeFixture)
+BOOST_FIXTURE_TEST_SUITE(TestClientModule, IdentityManagementTimeFixture)
 
 BOOST_AUTO_TEST_CASE(ClientModuleInitialize)
 {
-  util::DummyClientFace face(m_io, {true, true});
-  ClientModule client(face, m_keyChain);
+  ClientModule client(m_keyChain);
   client.getClientConf().load("tests/unit-tests/client.conf.test");
   BOOST_CHECK_EQUAL(client.getClientConf().m_caItems.size(), 2);
 }
 
-BOOST_AUTO_TEST_CASE(ProbeAndNew)
+BOOST_AUTO_TEST_CASE(Probe)
 {
-  util::DummyClientFace face(m_io, {true, true});
-  ClientModule client(face, m_keyChain);
+  ClientModule client(m_keyChain);
   client.getClientConf().load("tests/unit-tests/client.conf.test");
 
   auto identity = addIdentity(Name("/site"));
@@ -51,71 +50,14 @@
   auto cert = key.getDefaultCertificate();
 
   ClientCaItem item;
-  item.m_caName = Name("/site/CA");
+  item.m_caName = Name("/site");
   item.m_anchor = cert;
   client.getClientConf().m_caItems.push_back(item);
 
-  int nInterest = 0;
-  auto processInterest = [&] (const Interest& interest) {
-    nInterest++;
-    if (nInterest == 1) {
-      // PROBE interest and return identifier
-      BOOST_CHECK_EQUAL(interest.getName().toUri(), "/site/CA/_PROBE/zhiyi%40cs.ucla.edu");
-      BOOST_CHECK_EQUAL(interest.getMustBeFresh(), 1);
-
-      auto data = make_shared<Data>();
-      data->setName(interest.getName());
-      JsonSection json = genResponseProbeJson(Name("/site/ucla-cs-zhiyi"), Name(""));
-      std::stringstream ss;
-      boost::property_tree::write_json(ss, json);
-      Block dataContent = makeStringBlock(ndn::tlv::Content, ss.str());
-      data->setContent(dataContent);
-      m_keyChain.sign(*data, signingByCertificate(cert));
-      face.receive(*data);
-    }
-    else {
-      // NEW interest and return challenge list, request ID
-      BOOST_CHECK_EQUAL(interest.getName().getPrefix(3).toUri(), "/site/CA/_NEW");
-      BOOST_CHECK_EQUAL(interest.getName().size(), 6);
-
-      auto data = make_shared<Data>();
-      data->setName(interest.getName());
-      std::list<std::string> challenges;
-      challenges.push_back("EMAIL");
-      challenges.push_back("PIN");
-      JsonSection json = genResponseNewJson("1234", ChallengeModule::WAIT_SELECTION, challenges);
-      std::stringstream ss;
-      boost::property_tree::write_json(ss, json);
-      Block dataContent = makeStringBlock(ndn::tlv::Content, ss.str());
-      data->setContent(dataContent);
-      m_keyChain.sign(*data, signingByCertificate(cert));
-
-      face.receive(*data);
-    }
-  };
-  face.onSendInterest.connect([=] (const Interest& interest) { m_io.post([=] { processInterest(interest); }); });
-
-  int nCallback = 0;
-  shared_ptr<RequestState> requestState = nullptr;
-  ClientModule::RequestCallback requestCallback = [&] (shared_ptr<RequestState> state) {
-    nCallback++;
-    BOOST_CHECK_EQUAL(state->m_requestId, "1234");
-    BOOST_CHECK_EQUAL(state->m_challengeList.size(), 2);
-    requestState = state;
-  };
-  client.sendProbe(item, "zhiyi@cs.ucla.edu", requestCallback, ClientModule::ErrorCallback());
-
-  advanceClocks(time::milliseconds(200), 20);
-
-  BOOST_CHECK_EQUAL(nInterest, 2);
-  BOOST_CHECK_EQUAL(nCallback, 1);
-  BOOST_CHECK_EQUAL(requestState->m_ca.m_caName.toUri(), "/site/CA");
-  BOOST_CHECK_EQUAL(requestState->m_key.getName().getPrefix(3).toUri(), "/site/ucla-cs-zhiyi/KEY");
-
-  // make sure the client did not generate duplicated new keys
-  auto clientIdentity = m_keyChain.getPib().getIdentity(Name("/site/ucla-cs-zhiyi"));
-  const auto& clientKeys = clientIdentity.getKeys();
-  BOOST_CHECK_EQUAL(clientKeys.size(), 1);
+  auto firstInterest = client.generateProbeInterest(item, "zhiyi@cs.ucla.edu");
+  BOOST_CHECK_EQUAL(firstInterest->getName().toUri(), "/site/CA/_PROBE");
+  BOOST_CHECK_EQUAL(CaModule::jsonFromBlock(firstInterest->getApplicationParameters()).get<std::string>(JSON_CLIENT_PROBE_INFO),
+                    "zhiyi@cs.ucla.edu");
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestClientModule
diff --git a/tests/unit-tests/client.conf.test b/tests/unit-tests/client.conf.test
index 7cd85e8..c75d4d1 100644
--- a/tests/unit-tests/client.conf.test
+++ b/tests/unit-tests/client.conf.test
@@ -1,20 +1,18 @@
 {
   "ca-list":
   [
-    {
+    {   
         "ca-prefix": "/ndn/edu/ucla/CA",
         "ca-info": "UCLA's ceritificate authority, located in BH4805.",
-        "target-list": "Use your email address (edu preferred) as input",
         "probe": "Please use your email address to apply a namespace first. UCLA email is preferred.",
-        "is-list-enabled": "true",
         "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
-    },
-    {
+    },  
+        {   
         "ca-prefix": "/ndn/edu/ucla/zhiyi/CA",
         "ca-info": "Zhiyi's own ceritificate authority",
-        "is-list-enabled": "false",
+        "probe": "true",
         "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F"
-    }
+    }   
   ],
   "local-ndncert-anchor": "/usr/local/etc/ndncert/anchor.key"
 }
\ No newline at end of file
diff --git a/tests/unit-tests/crypto-helper.t.cpp b/tests/unit-tests/crypto-helper.t.cpp
new file mode 100644
index 0000000..4576942
--- /dev/null
+++ b/tests/unit-tests/crypto-helper.t.cpp
@@ -0,0 +1,217 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2019, 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 "crypto-support/crypto-helper.hpp"
+#include "test-common.hpp"
+#include <iostream>
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestCryptoHelper)
+
+BOOST_AUTO_TEST_CASE(Test0)
+{
+  ECDHState aliceState;
+  auto alicePub = aliceState.getRawSelfPubKey();
+  BOOST_CHECK(aliceState.context->publicKeyLen != 0);
+
+  ECDHState bobState;
+  auto bobPub = bobState.getRawSelfPubKey();
+  BOOST_CHECK(bobState.context->publicKeyLen != 0);
+
+  auto aliceResult = aliceState.deriveSecret(
+        bobPub, bobState.context->publicKeyLen);
+
+  BOOST_CHECK(aliceState.context->sharedSecretLen != 0);
+
+  auto bobResult = bobState.deriveSecret(
+        alicePub, aliceState.context->publicKeyLen);
+
+  BOOST_CHECK(bobState.context->sharedSecretLen != 0);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult, aliceResult + 32,
+                                bobResult, bobResult + 32);
+}
+
+BOOST_AUTO_TEST_CASE(Test1)
+{
+  ECDHState aliceState;
+  auto alicePub = aliceState.getBase64PubKey();
+  BOOST_CHECK(alicePub != "");
+
+  ECDHState bobState;
+  auto bobPub = bobState.getBase64PubKey();
+  BOOST_CHECK(bobPub != "");
+
+  auto aliceResult = aliceState.deriveSecret(bobPub);
+  BOOST_CHECK(aliceState.context->sharedSecretLen != 0);
+
+  auto bobResult = bobState.deriveSecret(alicePub);
+  BOOST_CHECK(bobState.context->sharedSecretLen != 0);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult, aliceResult + 32,
+                                bobResult, bobResult + 32);
+}
+
+
+BOOST_AUTO_TEST_CASE(NDN_COMPUTE_HMAC_SHA256_TEST1)
+{
+  uint8_t secret[] = {0x00,0x01,0x02,0x03,0x04,0x05,
+                 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c};
+
+  uint8_t salt[] = {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b};
+
+  uint8_t result[32];
+
+  uint8_t expected[] = {0x07,0x77,0x09,0x36,0x2c,0x2e,0x32,
+                        0xdf,0x0d,0xdc,0x3f,0x0d,0xc4,0x7b,
+                        0xba,0x63,0x90,0xb6,0xc7,0x3b,0xb5,
+                        0x0f,0x9c,0x31,0x22,0xec,0x84,0x4a,
+                        0xd7,0xc2,0xb3,0xe5};
+
+  ndn_compute_hmac_sha256(salt, sizeof(salt), secret, sizeof(secret), result);
+  BOOST_CHECK(memcmp(expected, result, sizeof(result)) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(IETF_TEST_1)
+{
+  uint8_t secret[] = {0x00,0x01,0x02,0x03,0x04,0x05,
+                      0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c};
+
+  uint8_t salt[] = {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b};
+
+  uint8_t info[] = {0xf0,0xf1,0xf2,0xf3,0xf4,
+                    0xf5,0xf6,0xf7,0xf8,0xf9};
+
+  uint8_t result[42];
+  uint8_t expected[] = {0x3c,0xb2,0x5f,0x25,0xfa,0xac,0xd5,0x7a,0x90,0x43,
+                        0x4f,0x64,0xd0,0x36,0x2f,0x2a,0x2d,0x2d,0x0a,0x90,
+                        0xcf,0x1a,0x5a,0x4c,0x5d,0xb0,0x2d,0x56,0xec,0xc4,
+                        0xc5,0xbf,0x34,0x00,0x72,0x08,0xd5,0xb8,0x87,0x18,
+                        0x58,0x65};
+
+  auto resultLen = hkdf(secret, sizeof(secret),
+                        salt,sizeof(salt),
+                        result, sizeof(result),
+                        info, sizeof(info));
+
+  BOOST_CHECK(resultLen != 0);
+  BOOST_CHECK(memcmp(expected, result, sizeof(result)) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(IETF_TEST_2)
+{
+  uint8_t secret[] = {0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
+                      0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+                      0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
+                      0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+                      0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+                      0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+                      0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+                      0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+                      0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+                      0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf};
+
+  uint8_t salt[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+                    0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+                    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+                    0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+                    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+                    0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+                    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
+                    0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+                    0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+                    0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
+
+  uint8_t info[] = {0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
+                    0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+                    0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
+                    0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+                    0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,
+                    0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+                    0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,
+                    0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+                    0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,
+                    0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff};
+
+  uint8_t result[82];
+  uint8_t expected[] = {0xb1,0x1e,0x39,0x8d,0xc8,0x03,0x27,
+                        0xa1,0xc8,0xe7,0xf7,0x8c,0x59,0x6a,
+                        0x49,0x34,0x4f,0x01,0x2e,0xda,0x2d,
+                        0x4e,0xfa,0xd8,0xa0,0x50,0xcc,0x4c,
+                        0x19,0xaf,0xa9,0x7c,0x59,0x04,0x5a,
+                        0x99,0xca,0xc7,0x82,0x72,0x71,0xcb,
+                        0x41,0xc6,0x5e,0x59,0x0e,0x09,0xda,
+                        0x32,0x75,0x60,0x0c,0x2f,0x09,0xb8,
+                        0x36,0x77,0x93,0xa9,0xac,0xa3,0xdb,
+                        0x71,0xcc,0x30,0xc5,0x81,0x79,0xec,
+                        0x3e,0x87,0xc1,0x4c,0x01,0xd5,0xc1,
+                        0xf3,0x43,0x4f,0x1d,0x87};
+
+  auto resultLen = hkdf(secret, sizeof(secret),
+                        salt,sizeof(salt),
+                        result, sizeof(result),
+                        info, sizeof(info));
+
+  BOOST_CHECK(resultLen != 0);
+  BOOST_CHECK(memcmp(expected, result, 42) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(IETF_TEST_3)
+{
+  //uint8_t secret[] = {}; secret is empty in this test
+
+  uint8_t salt[] = {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
+                    0x0b,0x0b,0x0b,0x0b,0x0b,0x0b};
+
+  //uint8_t info[] = {}; info is empty in this test
+
+  uint8_t result[42];
+  uint8_t expected[] = {0x8d,0xa4,0xe7,0x75,0xa5,0x63,0xc1,0x8f,
+                        0x71,0x5f,0x80,0x2a,0x06,0x3c,0x5a,0x31,
+                        0xb8,0xa1,0x1f,0x5c,0x5e,0xe1,0x87,0x9e,
+                        0xc3,0x45,0x4e,0x5f,0x3c,0x73,0x8d,0x2d,
+                        0x9d,0x20,0x13,0x95,0xfa,0xa4,0xb6,0x1a,
+                        0x96,0xc8};
+
+  auto resultLen = hkdf(nullptr, 0,
+                        salt,sizeof(salt),
+                        result, sizeof(result),
+                        nullptr, 0);
+
+  BOOST_CHECK(resultLen != 0);
+  BOOST_CHECK(memcmp(expected, result, sizeof(result)) == 0);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn
diff --git a/tests/unit-tests/dummy-test.t.cpp b/tests/unit-tests/dummy-test.t.cpp
index d6ccd1f..70d3f50 100644
--- a/tests/unit-tests/dummy-test.t.cpp
+++ b/tests/unit-tests/dummy-test.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017, Regents of the University of California.
+ * Copyright (c) 2017-2019, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -24,7 +24,7 @@
 namespace ndncert {
 namespace tests {
 
-// See http://redmine.named-data.net/projects/nfd/wiki/UnitTesting on how to name a test suite.
+// See https://redmine.named-data.net/projects/nfd/wiki/UnitTesting on how to name a test suite.
 BOOST_AUTO_TEST_SUITE(TestSkeleton)
 
 BOOST_AUTO_TEST_CASE(Test1)
diff --git a/tests/unit-tests/enc-tlv.t.cpp b/tests/unit-tests/enc-tlv.t.cpp
new file mode 100644
index 0000000..9ba62e7
--- /dev/null
+++ b/tests/unit-tests/enc-tlv.t.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2019, 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 "crypto-support/enc-tlv.hpp"
+#include "crypto-support/crypto-helper.hpp"
+#include "test-common.hpp"
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestEncTlv)
+
+BOOST_AUTO_TEST_CASE(Test0)
+{
+  ECDHState aliceState;
+  auto alicePub = aliceState.getRawSelfPubKey();
+  BOOST_CHECK(aliceState.context->publicKeyLen != 0);
+
+  ECDHState bobState;
+  auto bobPub = bobState.getRawSelfPubKey();
+  BOOST_CHECK(bobState.context->publicKeyLen != 0);
+
+  auto aliceResult = aliceState.deriveSecret(bobPub, bobState.context->publicKeyLen);
+  BOOST_CHECK(aliceState.context->sharedSecretLen != 0);
+
+  auto bobResult = bobState.deriveSecret(alicePub, aliceState.context->publicKeyLen);
+  BOOST_CHECK(bobState.context->sharedSecretLen != 0);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(aliceResult, aliceResult + 32,
+                                bobResult, bobResult + 32);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn
diff --git a/tests/unit-tests/json-helper.t.cpp b/tests/unit-tests/json-helper.t.cpp
deleted file mode 100644
index b089e4e..0000000
--- a/tests/unit-tests/json-helper.t.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2017, 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 "boost-test.hpp"
-#include "json-helper.hpp"
-
-namespace ndn {
-namespace ndncert {
-namespace tests {
-
-BOOST_AUTO_TEST_SUITE(TestJsonHelper)
-
-BOOST_AUTO_TEST_CASE(GenerateProbeJson)
-{
-  auto result = genResponseProbeJson(Name("/ndn/edu/ucla/cs/zhiyi/macbook"),
-                                     Name("/ndn/edu/ucla/cs/zhiyi/ca-info"));
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_IDNENTIFIER), "/ndn/edu/ucla/cs/zhiyi/macbook");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_CA_INFO), "/ndn/edu/ucla/cs/zhiyi/ca-info");
-}
-
-BOOST_AUTO_TEST_CASE(GenerateNewResponseJson)
-{
-  std::list<std::string> challenges;
-  challenges.push_back("PIN");
-  challenges.push_back("EMAIL");
-  auto result = genResponseNewJson("598234759", "wait-selection", challenges);
-
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_REQUEST_ID), "598234759");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_STATUS), "wait-selection");
-  auto child = result.get_child(JSON_CHALLENGES);
-  auto it = child.begin();
-  BOOST_CHECK_EQUAL(it->second.get<std::string>(JSON_CHALLENGE_TYPE), "PIN");
-  it++;
-  BOOST_CHECK_EQUAL(it->second.get<std::string>(JSON_CHALLENGE_TYPE), "EMAIL");
-}
-
-BOOST_AUTO_TEST_CASE(GenerateChallengeResponseJson)
-{
-  auto result = genResponseChallengeJson("598234759", "EMAIL", "need-code");
-
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_REQUEST_ID), "598234759");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_CHALLENGE_TYPE), "EMAIL");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_STATUS), "need-code");
-
-  result = genResponseChallengeJson("598234759", "EMAIL", "need-code", Name("/ndn/test"));
-
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_REQUEST_ID), "598234759");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_CHALLENGE_TYPE), "EMAIL");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_STATUS), "need-code");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_CERTIFICATE), "/ndn/test");
-}
-
-BOOST_AUTO_TEST_CASE(GenerateFailureJson)
-{
-  auto result = genFailureJson("598234759", "EMAIL", "failure",
-                               "The certificate name already exists");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_STATUS), "failure");
-  BOOST_CHECK_EQUAL(result.get<std::string>(JSON_FAILURE_INFO),
-                    "The certificate name already exists");
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestJsonHelper
-
-} // namespace tests
-} // namespace ndncert
-} // namespace ndn