diff --git a/src/challenge-module.cpp b/src/challenge-module.cpp
new file mode 100644
index 0000000..2170c5f
--- /dev/null
+++ b/src/challenge-module.cpp
@@ -0,0 +1,125 @@
+/* -*- 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 "challenge-module.hpp"
+#include <random>
+
+namespace ndn {
+namespace ndncert {
+
+const std::string ChallengeModule::WAIT_SELECTION = "wait-selection";
+const std::string ChallengeModule::SUCCESS = "success";
+const std::string ChallengeModule::PENDING = "pending";
+
+ChallengeModule::ChallengeModule(const std::string& uniqueType)
+  : CHALLENGE_TYPE(uniqueType)
+{
+}
+
+unique_ptr<ChallengeModule>
+ChallengeModule::createChallengeModule(const std::string& canonicalName)
+{
+  ChallengeFactory& factory = getFactory();
+  auto i = factory.find(canonicalName);
+  return i == factory.end() ? nullptr : i->second();
+}
+
+JsonSection
+ChallengeModule::handleChallengeRequest(const Interest& interest, CertificateRequest& request)
+{
+  int pos = request.getCaName().size();
+  const Name& interestName = interest.getName();
+  std::string interestType = interestName.get(pos).toUri();
+  if (interestType == "_SELECT") {
+    return processSelectInterest(interest, request);
+  }
+  else if (interestType == "_VALIDATE"){
+    return processValidateInterest(interest, request);
+  }
+  else {
+    return processStatusInterest(interest, request);
+  }
+}
+
+std::list<std::string>
+ChallengeModule::getRequirementForSelect()
+{
+  return getSelectRequirements();
+}
+
+std::list<std::string>
+ChallengeModule::getRequirementForValidate(const std::string& status)
+{
+  return getValidateRequirements(status);
+}
+
+JsonSection
+ChallengeModule::genRequestChallengeInfo(const std::string& interestType, const std::string& status,
+                                         const std::list<std::string>& paramList)
+{
+  return genChallengeInfo(interestType, status, paramList);
+}
+
+JsonSection
+ChallengeModule::processStatusInterest(const Interest& interest, const CertificateRequest& request)
+{
+  // interest format: /CA/_STATUS/{"request-id":"id"}/<signature>
+  if (request.getStatus() == SUCCESS) {
+    Name downloadName = genDownloadName(request.getCaName(), request.getStatus());
+    return genResponseChallengeJson(request.getRequestId(), request.getChallengeType(),
+                                    SUCCESS, downloadName);
+  }
+  else
+    return genResponseChallengeJson(request.getRequestId(), request.getChallengeType(),
+                                    request.getStatus());
+}
+
+JsonSection
+ChallengeModule::getJsonFromNameComponent(const Name& name, int pos)
+{
+  std::string jsonString = encoding::readString(name.get(pos));
+  std::istringstream ss(jsonString);
+  JsonSection json;
+  boost::property_tree::json_parser::read_json(ss, json);
+  return json;
+}
+
+Name
+ChallengeModule::genDownloadName(const Name& caName, const std::string& requestId)
+{
+  JsonSection json;
+  json.put(JSON_REQUEST_ID, requestId);
+  std::stringstream ss;
+  boost::property_tree::write_json(ss, json);
+  Block jsonBlock = makeStringBlock(ndn::tlv::NameComponent, ss.str());
+  Name name = caName;
+  name.append("_DOWNLOAD").append(jsonBlock);
+  return name;
+}
+
+ChallengeModule::ChallengeFactory&
+ChallengeModule::getFactory()
+{
+  static ChallengeModule::ChallengeFactory factory;
+  return factory;
+}
+
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/challenge-module.hpp b/src/challenge-module.hpp
new file mode 100644
index 0000000..603e2ff
--- /dev/null
+++ b/src/challenge-module.hpp
@@ -0,0 +1,176 @@
+/* -*- 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.
+ */
+
+#ifndef NDNCERT_CHALLENGE_MODULE_HPP
+#define NDNCERT_CHALLENGE_MODULE_HPP
+
+#include "ndncert-common.hpp"
+#include "certificate-request.hpp"
+#include "json-helper.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+class ChallengeModule : noncopyable
+{
+public:
+  /**
+   * @brief Error that can be thrown from ChallengeModule
+   *
+   * ChallengeModule should throw Error to notice CA there's an Error. In this case, CA will
+   * generate an Error JSON file back to end entity.
+   */
+  class Error : public std::runtime_error
+  {
+  public:
+    using std::runtime_error::runtime_error;
+  };
+
+public:
+  ChallengeModule(const std::string& uniqueType);
+
+  template<class ChallengeType>
+  static void
+  registerChallengeModule(const std::string& typeName)
+  {
+    ChallengeFactory& factory = getFactory();
+    BOOST_ASSERT(factory.count(typeName) == 0);
+    factory[typeName] = [] { return make_unique<ChallengeType>(); };
+  }
+
+  static unique_ptr<ChallengeModule>
+  createChallengeModule(const std::string& ChallengeType);
+
+  /**
+   * @brief Handle the challenge related interest and update certificate request.
+   * @note Should be used by CA Module
+   * @note Signature of interest should already be validated by CA Module
+   *
+   * When CA receives a SELECT or a VALIDATE or a STATUS interest, CA should invoke the function
+   * to enable selected challenge to go on the verification process.
+   *
+   * @param interest The request interest packet
+   * @param request The CertificateRequest instance
+   * @return the JSON file as the response data content
+   */
+  JsonSection
+  handleChallengeRequest(const Interest& interest, CertificateRequest& request);
+
+  /**
+   * @brief Get requirements for requester before sending SELECT interest.
+   * @note Should be used by Client Module
+   *
+   * Before requester sends a USE interest, client should invoke the function to
+   * get input instruction and expose the instruction to requester.
+   *
+   * Every item in the return list requires a input from requester. The item itself is
+   * an instruction for requester.
+   *
+   * @return the input instruction for requester
+   */
+  std::list<std::string>
+  getRequirementForSelect();
+
+  /**
+   * @brief Get requirements for requester before sending VALIDATE interest.
+   * @note Should be used by Client Module
+   *
+   * Before requester sends a POLL interest, client should invoke the function to
+   * get input instruction and expose the instruction to requester.
+   *
+   * Every item in the return list requires a input from requester. The item itself is
+   * an instruction for requester.
+   *
+   * @param status of the challenge
+   * @return the input instruction for requester
+   */
+  std::list<std::string>
+  getRequirementForValidate(const std::string& status);
+
+  /**
+   * @brief Generate ChallengeInfo part for SELECT and VALIDATE interest.
+   * @note Should be used by Client Module
+   *
+   * After requester provides required information, client should invoke the function to
+   * generate the ChallengeInfo part of the interest.
+   *
+   * @param interestType of the request
+   * @param status of the challenge
+   * @param paramList contains all the input from requester
+   * @return the JSON file of ChallengeInfo
+   */
+  JsonSection
+  genRequestChallengeInfo(const std::string& interestType, const std::string& status,
+                          const std::list<std::string>& paramList);
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  virtual JsonSection
+  processSelectInterest(const Interest& interest, CertificateRequest& request) = 0;
+
+  virtual JsonSection
+  processValidateInterest(const Interest& interest, CertificateRequest& request) = 0;
+
+  virtual std::list<std::string>
+  getSelectRequirements() = 0;
+
+  virtual std::list<std::string>
+  getValidateRequirements(const std::string& status) = 0;
+
+  virtual JsonSection
+  genChallengeInfo(const std::string& interestType, const std::string& status,
+                   const std::list<std::string>& paramList) = 0;
+
+  virtual JsonSection
+  processStatusInterest(const Interest& interest, const CertificateRequest& request);
+
+  static JsonSection
+  getJsonFromNameComponent(const Name& name, int pos);
+
+  static Name
+  genDownloadName(const Name& caName, const std::string& requestId);
+
+public:
+  const std::string CHALLENGE_TYPE;
+  static const std::string WAIT_SELECTION;
+  static const std::string SUCCESS;
+  static const std::string PENDING;
+
+private:
+  typedef function<unique_ptr<ChallengeModule> ()> ChallengeCreateFunc;
+  typedef std::map<std::string, ChallengeCreateFunc> ChallengeFactory;
+
+  static ChallengeFactory&
+  getFactory();
+};
+
+#define NDNCERT_REGISTER_CHALLENGE(C, T)                           \
+static class NdnCert ## C ## ChallengeRegistrationClass            \
+{                                                                  \
+public:                                                            \
+  NdnCert ## C ## ChallengeRegistrationClass()                     \
+  {                                                                \
+    ::ndn::ndncert::ChallengeModule::registerChallengeModule<C>(T);\
+  }                                                                \
+} g_NdnCert ## C ## ChallengeRegistrationVariable
+
+} // namespace ndncert
+} // namespace ndn
+
+#endif // NDNCERT_CHALLENGE_MODULE_HPP
diff --git a/src/challenge-module/challenge-pin.cpp b/src/challenge-module/challenge-pin.cpp
new file mode 100644
index 0000000..8c19c97
--- /dev/null
+++ b/src/challenge-module/challenge-pin.cpp
@@ -0,0 +1,169 @@
+/* -*- 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 "challenge-pin.hpp"
+#include "json-helper.hpp"
+#include <ndn-cxx/util/random.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+NDNCERT_REGISTER_CHALLENGE(ChallengePin, "PIN");
+
+const std::string ChallengePin::NEED_CODE = "need-code";
+const std::string ChallengePin::WRONG_CODE = "wrong-code";
+const std::string ChallengePin::FAILURE_TIMEOUT = "failure-timeout";
+const std::string ChallengePin::FAILURE_MAXRETRY = "failure-max-retry";
+
+const std::string ChallengePin::JSON_CODE_TP = "code-timepoint";
+const std::string ChallengePin::JSON_PIN_CODE = "code";
+const std::string ChallengePin::JSON_ATTEMPT_TIMES = "attempt-times";
+
+ChallengePin::ChallengePin(const size_t& maxAttemptTimes, const time::seconds& secretLifetime)
+  : ChallengeModule("PIN")
+  , m_secretLifetime(secretLifetime)
+  , m_maxAttemptTimes(maxAttemptTimes)
+{
+}
+
+JsonSection
+ChallengePin::processSelectInterest(const Interest& interest, CertificateRequest& request)
+{
+  // interest format: /CA/_SELECT/{"request-id":"id"}/PIN/<signature>
+  request.setStatus(NEED_CODE);
+  request.setChallengeType(CHALLENGE_TYPE);
+  request.setChallengeSecrets(generateStoredSecrets(time::system_clock::now(),
+                                                    generateSecureSecretCode(),
+                                                    m_maxAttemptTimes));
+  return genResponseChallengeJson(request.getRequestId(), CHALLENGE_TYPE, NEED_CODE);
+}
+
+JsonSection
+ChallengePin::processValidateInterest(const Interest& interest, CertificateRequest& request)
+{
+  // interest format: /CA/_VALIDATION/{"request-id":"id"}/PIN/{"code":"code"}/<signature>
+  JsonSection infoJson = getJsonFromNameComponent(interest.getName(), request.getCaName().size() + 3);
+  std::string givenCode = infoJson.get<std::string>(JSON_PIN_CODE);
+
+  const auto parsedSecret = parseStoredSecrets(request.getChallengeSecrets());
+  if (time::system_clock::now() - std::get<0>(parsedSecret) >= m_secretLifetime) {
+    // secret expires
+    request.setStatus(FAILURE_TIMEOUT);
+    request.setChallengeSecrets(JsonSection());
+    return genResponseChallengeJson(request.getRequestId(), CHALLENGE_TYPE, FAILURE_TIMEOUT);
+  }
+  else if (givenCode == std::get<1>(parsedSecret)) {
+    request.setStatus(SUCCESS);
+    request.setChallengeSecrets(JsonSection());
+    Name downloadName = genDownloadName(request.getCaName(), request.getRequestId());
+    return genResponseChallengeJson(request.getRequestId(), CHALLENGE_TYPE, SUCCESS, downloadName);
+  }
+  else {
+    // check rest attempt times
+    if (std::get<2>(parsedSecret) > 1) {
+      int restAttemptTimes = std::get<2>(parsedSecret) - 1;
+      request.setChallengeSecrets(generateStoredSecrets(std::get<0>(parsedSecret),
+                                                        std::get<1>(parsedSecret),
+                                                        restAttemptTimes));
+      return genResponseChallengeJson(request.getRequestId(), CHALLENGE_TYPE, WRONG_CODE);
+    }
+    else {
+      // run out times
+      request.setStatus(FAILURE_MAXRETRY);
+      request.setChallengeSecrets(JsonSection());
+      return genResponseChallengeJson(request.getRequestId(), CHALLENGE_TYPE, FAILURE_MAXRETRY);
+    }
+  }
+}
+
+std::list<std::string>
+ChallengePin::getSelectRequirements()
+{
+  std::list<std::string> result;
+  return result;
+}
+
+std::list<std::string>
+ChallengePin::getValidateRequirements(const std::string& status)
+{
+  std::list<std::string> result;
+  if (status == NEED_CODE) {
+    result.push_back("Please input your verification code:");
+  }
+  else if (status == WRONG_CODE) {
+    result.push_back("Incorrect PIN code, please input your verification code:");
+  }
+  return result;
+}
+
+JsonSection
+ChallengePin::genChallengeInfo(const std::string& interestType, const std::string& status,
+                               const std::list<std::string>& paramList)
+{
+  JsonSection result;
+  if (interestType == "_SELECT") {
+    BOOST_ASSERT(paramList.size() == 0);
+  }
+  else if (interestType == "_VALIDATE") {
+    BOOST_ASSERT(paramList.size() == 1);
+    result.put(JSON_PIN_CODE, paramList.front());
+  }
+  return result;
+}
+
+std::tuple<time::system_clock::TimePoint, std::string, int>
+ChallengePin::parseStoredSecrets(const JsonSection& storedSecrets)
+{
+  auto tp = time::fromIsoString(storedSecrets.get<std::string>(JSON_CODE_TP));
+  std::string rightCode= storedSecrets.get<std::string>(JSON_PIN_CODE);
+  int attemptTimes = std::stoi(storedSecrets.get<std::string>(JSON_ATTEMPT_TIMES));
+
+  return std::make_tuple(tp, rightCode, attemptTimes);
+}
+
+JsonSection
+ChallengePin::generateStoredSecrets(const time::system_clock::TimePoint& tp,
+                                    const std::string& secretCode, int attempTimes)
+{
+  JsonSection json;
+  json.put(JSON_CODE_TP, time::toIsoString(tp));
+  json.put(JSON_PIN_CODE, secretCode);
+  json.put(JSON_ATTEMPT_TIMES, std::to_string(attempTimes));
+  return json;
+}
+
+std::string
+ChallengePin::generateSecureSecretCode()
+{
+  uint32_t securityCode = 0;
+  do {
+    securityCode = random::generateSecureWord32();
+  }
+  while (securityCode >= 4294000000);
+  securityCode /= 4294;
+  std::string result = std::to_string(securityCode);
+  while (result.length() < 6) {
+    result = "0" + result;
+  }
+  return result;
+}
+
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/challenge-module/challenge-pin.hpp b/src/challenge-module/challenge-pin.hpp
new file mode 100644
index 0000000..b3e9e2e
--- /dev/null
+++ b/src/challenge-module/challenge-pin.hpp
@@ -0,0 +1,98 @@
+/* -*- 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.
+ */
+
+#ifndef NDNCERT_CHALLENGE_PIN_HPP
+#define NDNCERT_CHALLENGE_PIN_HPP
+
+#include "../challenge-module.hpp"
+#include <ndn-cxx/util/time.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+/**
+ * @brief Provide PIN code based challenge
+ *
+ * @sa https://github.com/named-data/ndncert/wiki/NDN-Certificate-Management-Protocol
+ *
+ * The main process of this challenge module is:
+ *   1. End entity provides empty string. The first POLL is only for selection.
+ *   2. The challenge module will generate a PIN code in ChallengeDefinedField.
+ *   3. End entity provides the verification code from some way to challenge module.
+ *
+ * There are four specific status defined in this challenge:
+ *   NEED_CODE: When selection is made.
+ *   WRONG_CODE: Get wrong verification code but still with secret lifetime and max retry times.
+ *   FAILURE_TIMEOUT: When secret is out-dated.
+ *   FAILURE_MAXRETRY: When requester tries too many times.
+ */
+class ChallengePin : public ChallengeModule
+{
+public:
+  ChallengePin(const size_t& maxAttemptTimes = 3,
+               const time::seconds& secretLifetime = time::seconds(3600));
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  JsonSection
+  processSelectInterest(const Interest& interest, CertificateRequest& request) override;
+
+  JsonSection
+  processValidateInterest(const Interest& interest, CertificateRequest& request) override;
+
+  std::list<std::string>
+  getSelectRequirements() override;
+
+  std::list<std::string>
+  getValidateRequirements(const std::string& status) override;
+
+  JsonSection
+  genChallengeInfo(const std::string& interestType, const std::string& status,
+                   const std::list<std::string>& paramList) override;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static std::tuple<time::system_clock::TimePoint, std::string, int>
+  parseStoredSecrets(const JsonSection& storedSecret);
+
+  static JsonSection
+  generateStoredSecrets(const time::system_clock::TimePoint& tp, const std::string& secretCode,
+                        int attempTimes);
+
+  static std::string
+  generateSecureSecretCode();
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static const std::string NEED_CODE;
+  static const std::string WRONG_CODE;
+  static const std::string FAILURE_TIMEOUT;
+  static const std::string FAILURE_MAXRETRY;
+
+  static const std::string JSON_CODE_TP;
+  static const std::string JSON_PIN_CODE;
+  static const std::string JSON_ATTEMPT_TIMES;
+
+private:
+  time::seconds m_secretLifetime;
+  int m_maxAttemptTimes;
+};
+
+} // namespace ndncert
+} // namespace ndn
+
+#endif // NDNCERT_CHALLENGE_PIN_HPP
diff --git a/tests/unit-tests/challenge-module.t.cpp b/tests/unit-tests/challenge-module.t.cpp
new file mode 100644
index 0000000..570aab1
--- /dev/null
+++ b/tests/unit-tests/challenge-module.t.cpp
@@ -0,0 +1,59 @@
+/* -*- 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
new file mode 100644
index 0000000..9911b1a
--- /dev/null
+++ b/tests/unit-tests/challenge-pin.t.cpp
@@ -0,0 +1,131 @@
+/* -*- 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 "challenge-module/challenge-pin.hpp"
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(TestChallengePin, IdentityManagementV2Fixture)
+
+BOOST_AUTO_TEST_CASE(TestGetInitInfo)
+{
+  ChallengePin challenge;
+  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)
+{
+  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");
+  interestName.append("_SELECT").append("Fake-Request-ID").append("PIN");
+  Interest interest(interestName);
+
+  ChallengePin challenge;
+  challenge.handleChallengeRequest(interest, request);
+
+  BOOST_CHECK_EQUAL(request.getStatus(), ChallengePin::NEED_CODE);
+  BOOST_CHECK_EQUAL(request.getChallengeType(), "PIN");
+}
+
+BOOST_AUTO_TEST_CASE(OnValidateInterestComingWithCode)
+{
+  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);
+
+  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, "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 interestName("/ndn/site1");
+  interestName.append("_VALIDATE").append("Fake-Request-ID").append("PIN").append(jsonContent);
+  Interest interest(interestName);
+
+  ChallengePin challenge;
+  challenge.handleChallengeRequest(interest, request);
+
+  BOOST_CHECK_EQUAL(request.getStatus(), ChallengeModule::SUCCESS);
+  BOOST_CHECK_EQUAL(request.getChallengeSecrets().empty(), true);
+}
+
+BOOST_AUTO_TEST_CASE(ClientSendSelect)
+{
+  ChallengePin challenge;
+  auto requirementList = challenge.getSelectRequirements();
+  BOOST_CHECK_EQUAL(requirementList.size(), 0);
+
+  auto json = challenge.genChallengeInfo("_SELECT", 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.genChallengeInfo("_VALIDATE", ChallengePin::NEED_CODE, requirementList);
+  BOOST_CHECK_EQUAL(json.empty(), false);
+  BOOST_CHECK_EQUAL(json.get<std::string>(ChallengePin::JSON_PIN_CODE), "123");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn
diff --git a/wscript b/wscript
index 2219b6e..2403d30 100644
--- a/wscript
+++ b/wscript
@@ -47,7 +47,7 @@
     conf.load('coverage')
 
     conf.load('sanitizers')
-    
+
     conf.write_config_header('src/ndncert-config.hpp')
 
 def build(bld):
