diff --git a/src/security/certificate-cache-ttl.cpp b/src/security/certificate-cache-ttl.cpp
deleted file mode 100644
index c1ad631..0000000
--- a/src/security/certificate-cache-ttl.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#include "certificate-cache-ttl.hpp"
-
-namespace ndn {
-namespace security {
-
-CertificateCacheTtl::CertificateCacheTtl(boost::asio::io_service& io,
-                                         const time::seconds& defaultTtl/* = time::seconds(3600)*/)
-  : m_defaultTtl(defaultTtl)
-  , m_io(io)
-  , m_scheduler(m_io)
-{
-}
-
-CertificateCacheTtl::~CertificateCacheTtl()
-{
-}
-
-void
-CertificateCacheTtl::insertCertificate(shared_ptr<const v1::IdentityCertificate> certificate)
-{
-  m_io.dispatch([this, certificate] { this->insert(certificate); });
-}
-
-shared_ptr<const v1::IdentityCertificate>
-CertificateCacheTtl::getCertificate(const Name& certificateName)
-{
-  Cache::iterator it = m_cache.find(certificateName);
-  if (it != m_cache.end())
-    return it->second.first;
-  else
-    return shared_ptr<v1::IdentityCertificate>();
-}
-
-void
-CertificateCacheTtl::reset()
-{
-  m_io.dispatch([this] { this->removeAll(); });
-}
-
-size_t
-CertificateCacheTtl::getSize()
-{
-  return m_cache.size();
-}
-
-void
-CertificateCacheTtl::insert(shared_ptr<const v1::IdentityCertificate> certificate)
-{
-  time::milliseconds expire = (certificate->getFreshnessPeriod() >= time::seconds::zero() ?
-                               certificate->getFreshnessPeriod() : m_defaultTtl);
-
-  Name index = certificate->getName().getPrefix(-1);
-
-  Cache::iterator it = m_cache.find(index);
-  if (it != m_cache.end())
-    m_scheduler.cancelEvent(it->second.second);
-
-  EventId eventId = m_scheduler.scheduleEvent(expire,
-                                              bind(&CertificateCacheTtl::remove,
-                                                   this, certificate->getName()));
-
-  m_cache[index] = std::make_pair(certificate, eventId);
-}
-
-void
-CertificateCacheTtl::remove(const Name& certificateName)
-{
-  Name name = certificateName.getPrefix(-1);
-  Cache::iterator it = m_cache.find(name);
-  if (it != m_cache.end())
-    m_cache.erase(it);
-}
-
-void
-CertificateCacheTtl::removeAll()
-{
-  for(Cache::iterator it = m_cache.begin(); it != m_cache.end(); it++)
-    m_scheduler.cancelEvent(it->second.second);
-
-  m_cache.clear();
-}
-
-} // namespace security
-} // namespace ndn
diff --git a/src/security/certificate-cache-ttl.hpp b/src/security/certificate-cache-ttl.hpp
deleted file mode 100644
index e0ef837..0000000
--- a/src/security/certificate-cache-ttl.hpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_CERTIFICATE_CACHE_TTL_HPP
-#define NDN_SECURITY_CERTIFICATE_CACHE_TTL_HPP
-
-#include "../common.hpp"
-#include "certificate-cache.hpp"
-#include "../util/scheduler.hpp"
-
-namespace ndn {
-namespace security {
-
-/**
- * @brief Cache of validated certificates with freshness-based eviction policy
- *
- * Validated certificates will stay in cache for the duration of their freshness period.
- * The lifetime of the certificate in cache can be extended by "re-inserting" it in the cache.
- */
-class CertificateCacheTtl : public CertificateCache
-{
-public:
-  explicit
-  CertificateCacheTtl(boost::asio::io_service& io,
-                      const time::seconds& defaultTtl = time::seconds(3600));
-
-  virtual
-  ~CertificateCacheTtl();
-
-  virtual void
-  insertCertificate(shared_ptr<const v1::IdentityCertificate> certificate);
-
-  virtual shared_ptr<const v1::IdentityCertificate>
-  getCertificate(const Name& certificateNameWithoutVersion);
-
-  virtual void
-  reset();
-
-  virtual size_t
-  getSize();
-
-private:
-  void
-  insert(shared_ptr<const v1::IdentityCertificate> certificate);
-
-  void
-  remove(const Name& certificateName);
-
-  void
-  removeAll();
-
-protected:
-  typedef std::map<Name, std::pair<shared_ptr<const v1::IdentityCertificate>, EventId> > Cache;
-
-  time::seconds m_defaultTtl;
-  Cache m_cache;
-  boost::asio::io_service& m_io;
-  Scheduler m_scheduler;
-};
-
-} // namespace security
-
-using security::CertificateCacheTtl;
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_CERTIFICATE_CACHE_TTL_HPP
diff --git a/src/security/certificate-cache.hpp b/src/security/certificate-cache.hpp
deleted file mode 100644
index fa6cb79..0000000
--- a/src/security/certificate-cache.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_CERTIFICATE_CACHE_HPP
-#define NDN_SECURITY_CERTIFICATE_CACHE_HPP
-
-#include "../name.hpp"
-#include "v1/identity-certificate.hpp"
-
-namespace ndn {
-namespace security {
-
-/**
- * @brief Interface for the cache of validated certificates
- */
-class CertificateCache : noncopyable
-{
-public:
-  virtual
-  ~CertificateCache()
-  {
-  }
-
-  virtual void
-  insertCertificate(shared_ptr<const v1::IdentityCertificate> certificate) = 0;
-
-  virtual shared_ptr<const v1::IdentityCertificate>
-  getCertificate(const Name& certificateNameWithoutVersion) = 0;
-
-  virtual void
-  reset() = 0;
-
-  virtual size_t
-  getSize() = 0;
-
-  bool
-  isEmpty()
-  {
-    return (getSize() == 0);
-  }
-};
-
-} // namespace security
-
-using security::CertificateCache;
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_CERTIFICATE_CACHE_HPP
diff --git a/src/security/command-interest-validator.cpp b/src/security/command-interest-validator.cpp
deleted file mode 100644
index 57c9c82..0000000
--- a/src/security/command-interest-validator.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-#include "command-interest-validator.hpp"
-#include <boost/lexical_cast.hpp>
-
-namespace ndn {
-namespace security {
-
-std::ostream&
-operator<<(std::ostream& os, CommandInterestValidator::ErrorCode error)
-{
-  switch (error) {
-    case CommandInterestValidator::ErrorCode::NONE:
-      return os << "OK";
-    case CommandInterestValidator::ErrorCode::NAME_TOO_SHORT:
-      return os << "command Interest name is too short";
-    case CommandInterestValidator::ErrorCode::BAD_TIMESTAMP:
-      return os << "cannot parse timestamp";
-    case CommandInterestValidator::ErrorCode::BAD_SIG_INFO:
-      return os << "cannot parse SignatureInfo";
-    case CommandInterestValidator::ErrorCode::MISSING_KEY_LOCATOR:
-      return os << "KeyLocator is missing";
-    case CommandInterestValidator::ErrorCode::BAD_KEY_LOCATOR_TYPE:
-      return os << "KeyLocator type is not Name";
-    case CommandInterestValidator::ErrorCode::BAD_CERT_NAME:
-      return os << "cannot parse certificate name";
-    case CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE:
-      return os << "timestamp is out of grace period";
-    case CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER:
-      return os << "timestamp is less than or equal to last timestamp";
-  }
-  return os;
-}
-
-static void
-invokeReject(const OnInterestValidationFailed& reject, const Interest& interest,
-             CommandInterestValidator::ErrorCode error)
-{
-  reject(interest.shared_from_this(), boost::lexical_cast<std::string>(error));
-}
-
-CommandInterestValidator::CommandInterestValidator(unique_ptr<Validator> inner,
-                                                   const Options& options)
-  : m_inner(std::move(inner))
-  , m_options(options)
-  , m_index(m_container.get<0>())
-  , m_queue(m_container.get<1>())
-{
-  if (m_inner == nullptr) {
-    BOOST_THROW_EXCEPTION(std::invalid_argument("inner validator is nullptr"));
-  }
-
-  m_options.gracePeriod = std::max(m_options.gracePeriod, time::nanoseconds::zero());
-}
-
-void
-CommandInterestValidator::checkPolicy(const Interest& interest, int nSteps,
-                                      const OnInterestValidated& accept,
-                                      const OnInterestValidationFailed& reject,
-                                      std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  BOOST_ASSERT(nSteps == 0);
-  this->cleanup();
-
-  Name keyName;
-  uint64_t timestamp;
-  ErrorCode res = this->parseCommandInterest(interest, keyName, timestamp);
-  if (res != ErrorCode::NONE) {
-    return invokeReject(reject, interest, res);
-  }
-
-  time::system_clock::TimePoint receiveTime = time::system_clock::now();
-
-  m_inner->validate(interest,
-    [=] (const shared_ptr<const Interest>& interest) {
-      ErrorCode res = this->checkTimestamp(keyName, timestamp, receiveTime);
-      if (res != ErrorCode::NONE) {
-        return invokeReject(reject, *interest, res);
-      }
-      accept(interest);
-    }, reject);
-}
-
-void
-CommandInterestValidator::cleanup()
-{
-  time::steady_clock::TimePoint expiring = time::steady_clock::now() - m_options.timestampTtl;
-
-  while ((!m_queue.empty() && m_queue.front().lastRefreshed <= expiring) ||
-         (m_options.maxTimestamps >= 0 &&
-          m_queue.size() > static_cast<size_t>(m_options.maxTimestamps))) {
-    m_queue.pop_front();
-  }
-}
-
-CommandInterestValidator::ErrorCode
-CommandInterestValidator::parseCommandInterest(const Interest& interest, Name& keyName,
-                                               uint64_t& timestamp) const
-{
-  const Name& name = interest.getName();
-  if (name.size() < command_interest::MIN_SIZE) {
-    return ErrorCode::NAME_TOO_SHORT;
-  }
-
-  const name::Component& timestampComp = name.at(command_interest::POS_TIMESTAMP);
-  if (!timestampComp.isNumber()) {
-    return ErrorCode::BAD_TIMESTAMP;
-  }
-  timestamp = timestampComp.toNumber();
-
-  SignatureInfo sig;
-  try {
-    sig.wireDecode(name[signed_interest::POS_SIG_INFO].blockFromValue());
-  }
-  catch (const tlv::Error&) {
-    return ErrorCode::BAD_SIG_INFO;
-  }
-
-  if (!sig.hasKeyLocator()) {
-    return ErrorCode::MISSING_KEY_LOCATOR;
-  }
-
-  const KeyLocator& keyLocator = sig.getKeyLocator();
-  if (keyLocator.getType() != KeyLocator::KeyLocator_Name) {
-    return ErrorCode::BAD_KEY_LOCATOR_TYPE;
-  }
-
-  try {
-    v2::extractIdentityFromKeyName(keyLocator.getName());
-  }
-  catch (const std::invalid_argument&) {
-    return ErrorCode::BAD_CERT_NAME;
-  }
-
-  keyName = keyLocator.getName();
-
-  return ErrorCode::NONE;
-}
-
-CommandInterestValidator::ErrorCode
-CommandInterestValidator::checkTimestamp(const Name& keyName, uint64_t timestamp,
-                                         time::system_clock::TimePoint receiveTime)
-{
-  time::steady_clock::TimePoint now = time::steady_clock::now();
-
-  // try to insert new record
-  Queue::iterator i = m_queue.end();
-  bool isNew = false;
-  std::tie(i, isNew) = m_queue.push_back({keyName, timestamp, now});
-
-  if (isNew) {
-    // check grace period
-    time::system_clock::TimePoint sigTime = time::fromUnixTimestamp(time::milliseconds(timestamp));
-    if (time::abs(sigTime - receiveTime) > m_options.gracePeriod) {
-      // out of grace period, delete new record
-      m_queue.erase(i);
-      return ErrorCode::TIMESTAMP_OUT_OF_GRACE;
-    }
-  }
-  else {
-    BOOST_ASSERT(i->keyName == keyName);
-
-    // compare timestamp with last timestamp
-    if (timestamp <= i->timestamp) {
-      return ErrorCode::TIMESTAMP_REORDER;
-    }
-
-    // set lastRefreshed field, and move to queue tail
-    m_queue.erase(i);
-    isNew = m_queue.push_back({keyName, timestamp, now}).second;
-    BOOST_ASSERT(isNew);
-  }
-
-  return ErrorCode::NONE;
-}
-
-void
-CommandInterestValidator::checkPolicy(const Data& data, int nSteps,
-                                      const OnDataValidated& accept,
-                                      const OnDataValidationFailed& reject,
-                                      std::vector<shared_ptr<ValidationRequest>>& nextSteps)
-{
-  BOOST_ASSERT(nSteps == 0);
-  m_inner->validate(data, accept, reject);
-}
-
-} // namespace security
-} // namespace ndn
diff --git a/src/security/command-interest-validator.hpp b/src/security/command-interest-validator.hpp
deleted file mode 100644
index c377142..0000000
--- a/src/security/command-interest-validator.hpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
-#define NDN_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
-
-#include "validator.hpp"
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/key_extractors.hpp>
-
-namespace ndn {
-namespace security {
-
-/** \brief a validator for stop-and-wait command Interests
- *  \sa https://redmine.named-data.net/projects/ndn-cxx/wiki/CommandInterest
- *
- *  This validator checks timestamp field of a stop-and-wait command Interest.
- *  Signed Interest validation and Data validation requests are delegated to an inner validator.
- */
-class CommandInterestValidator : public Validator
-{
-public:
-  class Options
-  {
-  public:
-    Options()
-    {
-    }
-
-  public:
-    /** \brief tolerance of initial timestamp
-     *
-     *  A stop-and-wait command Interest is considered "initial" if the validator
-     *  has not recorded the last timestamp from the same public key, or when
-     *  such knowledge has been erased.
-     *  For an initial command Interest, its timestamp is compared to the current
-     *  system clock, and the command Interest is rejected if the absolute difference
-     *  is greater than the grace interval.
-     *
-     *  This should be positive.
-     *  Setting this option to 0 or negative causes the validator to require exactly same
-     *  timestamp as the system clock, which most likely rejects all command Interests.
-     */
-    time::nanoseconds gracePeriod = time::seconds(120);
-
-    /** \brief max number of distinct public keys to record last timestamp
-     *
-     *  The validator records last timestamps for every public key.
-     *  For a subsequent command Interest using the same public key,
-     *  its timestamp is compared to the last timestamp from that public key,
-     *  and the command Interest is rejected if its timestamp is
-     *  less than or equal to the recorded timestamp.
-     *
-     *  This option limits the number of distinct public keys being tracked.
-     *  If the limit is exceeded, the oldest record is deleted.
-     *
-     *  Setting this option to -1 allows tracking unlimited public keys.
-     *  Setting this option to 0 disables last timestamp records and causes
-     *  every command Interest to be processed as initial.
-     */
-    ssize_t maxTimestamps = 1000;
-
-    /** \brief max lifetime of a last timestamp record
-     *
-     *  A last timestamp record expires and can be deleted if it has not been refreshed
-     *  within this duration.
-     *  Setting this option to 0 or negative makes last timestamp records expire immediately
-     *  and causes every command Interest to be processed as initial.
-     */
-    time::nanoseconds timestampTtl = time::hours(1);
-  };
-
-  /** \brief error codes
-   *  \todo #1872 assign numeric codes to these errors
-   */
-  enum class ErrorCode {
-    NONE = 0,
-    NAME_TOO_SHORT,
-    BAD_TIMESTAMP,
-    BAD_SIG_INFO,
-    MISSING_KEY_LOCATOR,
-    BAD_KEY_LOCATOR_TYPE,
-    BAD_CERT_NAME,
-    TIMESTAMP_OUT_OF_GRACE,
-    TIMESTAMP_REORDER
-  };
-
-  /** \brief constructor
-   *  \param inner a Validator for signed Interest signature validation and Data validation;
-   *               this must not be nullptr
-   *  \param options stop-and-wait command Interest validation options
-   *  \throw std::invalid inner is nullptr
-   */
-  explicit
-  CommandInterestValidator(unique_ptr<Validator> inner,
-                           const Options& options = Options());
-
-protected:
-  /** \brief validate command Interest
-   *
-   *  This function executes the following validation procedure:
-   *
-   *  1. parse the Interest as a command Interest, and extract the public key name
-   *  2. invoke inner validation to verify the signed Interest
-   *  3. classify the command Interest as either initial or subsequent,
-   *     and check the timestamp accordingly
-   *  4. record the timestamp as last timestamp of the public key name
-   *
-   *  The validation request is rejected if any step in this procedure fails.
-   */
-  void
-  checkPolicy(const Interest& interest, int nSteps,
-              const OnInterestValidated& accept,
-              const OnInterestValidationFailed& reject,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-  /** \brief validate Data
-   *
-   *  The validation request is redirected to the inner validator.
-   */
-  void
-  checkPolicy(const Data& data, int nSteps,
-              const OnDataValidated& accept,
-              const OnDataValidationFailed& reject,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
-
-private:
-  void
-  cleanup();
-
-  ErrorCode
-  parseCommandInterest(const Interest& interest, Name& keyName, uint64_t& timestamp) const;
-
-  ErrorCode
-  checkTimestamp(const Name& keyName, uint64_t timestamp,
-                 time::system_clock::TimePoint receiveTime);
-
-private:
-  unique_ptr<Validator> m_inner;
-  Options m_options;
-
-  struct LastTimestampRecord
-  {
-    Name keyName;
-    uint64_t timestamp;
-    time::steady_clock::TimePoint lastRefreshed;
-  };
-
-  typedef boost::multi_index_container<
-    LastTimestampRecord,
-    boost::multi_index::indexed_by<
-      boost::multi_index::ordered_unique<
-        boost::multi_index::member<LastTimestampRecord, Name, &LastTimestampRecord::keyName>
-      >,
-      boost::multi_index::sequenced<>
-    >
-  > Container;
-  typedef Container::nth_index<0>::type Index;
-  typedef Container::nth_index<1>::type Queue;
-
-  Container m_container;
-  Index& m_index;
-  Queue& m_queue;
-};
-
-std::ostream&
-operator<<(std::ostream& os, CommandInterestValidator::ErrorCode error);
-
-} // namespace security
-} // namespace ndn
-
-
-#endif // NDN_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
diff --git a/src/security/sec-public-info-sqlite3.hpp b/src/security/sec-public-info-sqlite3.hpp
deleted file mode 100644
index e5b061f..0000000
--- a/src/security/sec-public-info-sqlite3.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-/**
- * @file security/sec-public-info-sqlite3.hpp
- * @deprecated Use new PIB backed routines
- */
-
-#include "security-common.hpp"
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-#include "v1/sec-public-info-sqlite3.hpp"
-#else
-#error "Deprecated. Use the new PIB backed routines"
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
diff --git a/src/security/sec-public-info.hpp b/src/security/sec-public-info.hpp
deleted file mode 100644
index 5101df5..0000000
--- a/src/security/sec-public-info.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-/**
- * @file security/sec-public-info.hpp
- * @deprecated Use new PIB backed routines
- */
-
-#include "security-common.hpp"
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-#include "v1/sec-public-info.hpp"
-#else
-#error "Deprecated. Use the new PIB backed routines"
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
diff --git a/src/security/sec-tpm-file.hpp b/src/security/sec-tpm-file.hpp
deleted file mode 100644
index d30e492..0000000
--- a/src/security/sec-tpm-file.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-/**
- * @file security/sec-tpm-file.hpp
- * @deprecated Use new TPM backed routines
- */
-
-#include "security-common.hpp"
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-#include "v1/sec-tpm-file.hpp"
-#else
-#error "Deprecated. Use the new TPM backed routines"
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
diff --git a/src/security/sec-tpm-osx.hpp b/src/security/sec-tpm-osx.hpp
deleted file mode 100644
index 478e8cf..0000000
--- a/src/security/sec-tpm-osx.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-/**
- * @file security/sec-tpm-osx.hpp
- * @deprecated Use new TPM backed routines
- */
-
-#include "security-common.hpp"
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-#include "v1/sec-tpm-osx.hpp"
-#else
-#error "Deprecated. Use the new TPM backed routines"
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
diff --git a/src/security/sec-tpm.hpp b/src/security/sec-tpm.hpp
deleted file mode 100644
index a5fcb8b..0000000
--- a/src/security/sec-tpm.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-/**
- * @file security/sec-tpm.hpp
- * @deprecated Use new TPM backed routines
- */
-
-#include "security-common.hpp"
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-#include "v1/sec-tpm.hpp"
-#else
-#error "Deprecated. Use the new TPM backed routines"
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
diff --git a/src/security/v1/certificate-extension.cpp b/src/security/v1/certificate-extension.cpp
deleted file mode 100644
index d871eac..0000000
--- a/src/security/v1/certificate-extension.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "certificate-extension.hpp"
-#include "cryptopp.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-void
-CertificateExtension::encode(CryptoPP::BufferedTransformation& out) const
-{
-  using namespace CryptoPP;
-
-  // Extension ::= SEQUENCE {
-  //        extnID      OBJECT IDENTIFIER,
-  //        critical    BOOLEAN DEFAULT FALSE,
-  //        extnValue   OCTET STRING  }
-
-  DERSequenceEncoder extension(out);
-  {
-    m_extensionId.encode(extension);
-    DEREncodeUnsigned(extension, m_isCritical, BOOLEAN);
-    DEREncodeOctetString(extension, m_extensionValue.buf(), m_extensionValue.size());
-  }
-  extension.MessageEnd();
-}
-
-void
-CertificateExtension::decode(CryptoPP::BufferedTransformation& in)
-{
-  using namespace CryptoPP;
-
-  // Extension ::= SEQUENCE {
-  //        extnID      OBJECT IDENTIFIER,
-  //        critical    BOOLEAN DEFAULT FALSE,
-  //        extnValue   OCTET STRING  }
-
-  BERSequenceDecoder extension(in);
-  {
-    m_extensionId.decode(extension);
-    BERDecodeUnsigned(extension, m_isCritical, BOOLEAN);
-
-    // the extra copy operation can be optimized, but not trivial,
-    // since the length is not known in advance
-    SecByteBlock tmpBlock;
-    BERDecodeOctetString(extension, tmpBlock);
-    m_extensionValue.assign(tmpBlock.begin(), tmpBlock.end());
-  }
-  extension.MessageEnd();
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/certificate-extension.hpp b/src/security/v1/certificate-extension.hpp
deleted file mode 100644
index c898835..0000000
--- a/src/security/v1/certificate-extension.hpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
-#define NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
-
-#include "../../common.hpp"
-#include "../../encoding/buffer.hpp"
-#include "../../encoding/oid.hpp"
-
-namespace CryptoPP {
-class BufferedTransformation;
-} // namespace CryptoPP
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-/**
- * A CertificateExtension represents the Extension entry in a certificate.
- */
-class CertificateExtension
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  explicit
-  CertificateExtension(CryptoPP::BufferedTransformation& in)
-  {
-    decode(in);
-  }
-
-  /**
-   * Create a new CertificateExtension.
-   * @param oid The oid of subject description entry.
-   * @param isCritical If true, the extension must be handled.
-   * @param value The extension value.
-   */
-  CertificateExtension(const Oid& oid, const bool isCritical, const Buffer& value)
-    : m_extensionId(oid), m_isCritical(isCritical), m_extensionValue(value)
-  {
-  }
-
-  CertificateExtension(const Oid& oid, const bool isCritical,
-                       const uint8_t* value, size_t valueSize)
-    : m_extensionId(oid), m_isCritical(isCritical), m_extensionValue(value, valueSize)
-  {
-  }
-
-  /**
-   * The virtual destructor.
-   */
-  virtual
-  ~CertificateExtension()
-  {
-  }
-
-  void
-  encode(CryptoPP::BufferedTransformation& out) const;
-
-  void
-  decode(CryptoPP::BufferedTransformation& in);
-
-  inline const Oid&
-  getOid() const
-  {
-    return m_extensionId;
-  }
-
-  inline bool
-  getIsCritical() const
-  {
-    return m_isCritical;
-  }
-
-  inline const Buffer&
-  getValue() const
-  {
-    return m_extensionValue;
-  }
-
-protected:
-  Oid m_extensionId;
-  bool m_isCritical;
-  Buffer m_extensionValue;
-};
-
-} // namespace v1
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-/// @deprecated When needed, use explicit namespace
-using security::v1::CertificateExtension;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
diff --git a/src/security/v1/certificate-subject-description.cpp b/src/security/v1/certificate-subject-description.cpp
deleted file mode 100644
index 1e910c2..0000000
--- a/src/security/v1/certificate-subject-description.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "certificate-subject-description.hpp"
-
-#include "cryptopp.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-void
-CertificateSubjectDescription::encode(CryptoPP::BufferedTransformation& out) const
-{
-  using namespace CryptoPP;
-  // RelativeDistinguishedName ::=
-  //     SET OF AttributeTypeAndValue
-  //
-  // AttributeTypeAndValue ::= SEQUENCE {
-  //     type     AttributeType,
-  //     value    AttributeValue   }
-  //
-  // AttributeType ::= OBJECT IDENTIFIER
-  //
-  // AttributeValue ::= ANY DEFINED BY AttributeType
-  DERSequenceEncoder attributeTypeAndValue(out);
-  {
-    m_oid.encode(attributeTypeAndValue);
-    DEREncodeTextString(attributeTypeAndValue, m_value, PRINTABLE_STRING);
-  }
-  attributeTypeAndValue.MessageEnd();
-}
-
-void
-CertificateSubjectDescription::decode(CryptoPP::BufferedTransformation& in)
-{
-  using namespace CryptoPP;
-  // RelativeDistinguishedName ::=
-  //     SET OF AttributeTypeAndValue
-  //
-  // AttributeTypeAndValue ::= SEQUENCE {
-  //     type     AttributeType,
-  //     value    AttributeValue   }
-  //
-  // AttributeType ::= OBJECT IDENTIFIER
-  //
-  // AttributeValue ::= ANY DEFINED BY AttributeType
-
-  BERSequenceDecoder attributeTypeAndValue(in);
-  {
-    m_oid.decode(attributeTypeAndValue);
-
-    /// @todo May be add more intelligent processing, since the following
-    ///       may fail if somebody encoded attribute that uses non PRINTABLE_STRING as value
-    BERDecodeTextString(attributeTypeAndValue, m_value, PRINTABLE_STRING);
-  }
-  attributeTypeAndValue.MessageEnd();
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/certificate-subject-description.hpp b/src/security/v1/certificate-subject-description.hpp
deleted file mode 100644
index 00eab76..0000000
--- a/src/security/v1/certificate-subject-description.hpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
-#define NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
-
-#include "../../common.hpp"
-#include "../../encoding/oid.hpp"
-
-namespace CryptoPP {
-class BufferedTransformation;
-} // namespace CryptoPP
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-/**
- * A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
- */
-class CertificateSubjectDescription
-{
-public:
-  explicit
-  CertificateSubjectDescription(CryptoPP::BufferedTransformation& in)
-  {
-    decode(in);
-  }
-
-  /**
-   * Create a new CertificateSubjectDescription.
-   * @param oid The oid of the subject description entry.
-   * @param value The value of the subject description entry.
-   */
-  CertificateSubjectDescription(const Oid& oid, const std::string& value)
-  : m_oid(oid), m_value(value)
-  {
-  }
-
-  void
-  encode(CryptoPP::BufferedTransformation& out) const;
-
-  void
-  decode(CryptoPP::BufferedTransformation& in);
-
-  std::string
-  getOidString() const
-  {
-    return m_oid.toString();
-  }
-
-  const std::string&
-  getValue() const
-  {
-    return m_value;
-  }
-
-private:
-  Oid m_oid;
-  std::string m_value;
-};
-
-} // namespace v1
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-/// @deprecated When needed, use explicit namespace
-using security::v1::CertificateSubjectDescription;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
diff --git a/src/security/v1/certificate.cpp b/src/security/v1/certificate.cpp
deleted file mode 100644
index d686a50..0000000
--- a/src/security/v1/certificate.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "certificate.hpp"
-#include "../../util/time.hpp"
-#include "cryptopp.hpp"
-#include "../../encoding/cryptopp/asn_ext.hpp"
-#include "../../encoding/buffer-stream.hpp"
-#include "../../util/concepts.hpp"
-#include "../../util/indented-stream.hpp"
-
-#include <boost/algorithm/string/split.hpp>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
-BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
-static_assert(std::is_base_of<tlv::Error, Certificate::Error>::value,
-              "Certificate::Error must inherit from tlv::Error");
-
-Certificate::Certificate()
-  : m_notBefore(time::system_clock::TimePoint::max())
-  , m_notAfter(time::system_clock::TimePoint::min())
-{
-}
-
-Certificate::Certificate(const Data& data)
-  // Use the copy constructor.  It clones the signature object.
-  : Data(data)
-{
-  decode();
-}
-
-Certificate::Certificate(const Block& block)
-  : Data(block)
-{
-  decode();
-}
-
-Certificate::~Certificate()
-{
-}
-
-void
-Certificate::wireDecode(const Block& wire)
-{
-  Data::wireDecode(wire);
-  decode();
-}
-
-bool
-Certificate::isTooEarly()
-{
-  if (time::system_clock::now() < m_notBefore)
-    return true;
-  else
-    return false;
-}
-
-bool
-Certificate::isTooLate()
-{
-  if (time::system_clock::now() > m_notAfter)
-    return true;
-  else
-    return false;
-}
-
-void
-Certificate::encode()
-{
-  // Name
-  //    <key_name>/ID-CERT/<id#>
-  // Content
-  // DER encoded idCert:
-  //
-  //    idCert ::= SEQUENCE {
-  //        validity            Validity,
-  //        subject             Name,
-  //        subjectPubKeyInfo   SubjectPublicKeyInfo,
-  //        extension           Extensions OPTIONAL   }
-  //
-  //    Validity ::= SEQUENCE {
-  //        notBefore           Time,
-  //        notAfter            Time   }
-  //
-  //    Name ::= CHOICE {
-  //        RDNSequence   }
-  //
-  //    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-  //
-  //    RelativeDistinguishedName ::=
-  //        SET OF AttributeTypeAndValue
-  //
-  //    SubjectPublicKeyInfo ::= SEQUENCE {
-  //        algorithm           AlgorithmIdentifier
-  //        keybits             BIT STRING   }
-  //
-  //    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
-  //
-  // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
-  //
-  // KeyLocator
-  //    issuer’s certificate name
-  // Signature
-
-  using namespace CryptoPP;
-
-  OBufferStream os;
-  CryptoPP::FileSink sink(os);
-
-  // idCert ::= SEQUENCE {
-  //     validity            Validity,
-  //     subject             Name,
-  //     subjectPubKeyInfo   SubjectPublicKeyInfo,
-  //     extension           Extensions OPTIONAL   }
-  DERSequenceEncoder idCert(sink);
-  {
-    // Validity ::= SEQUENCE {
-    //       notBefore           Time,
-    //       notAfter            Time   }
-    DERSequenceEncoder validity(idCert);
-    {
-      DEREncodeGeneralTime(validity, m_notBefore);
-      DEREncodeGeneralTime(validity, m_notAfter);
-    }
-    validity.MessageEnd();
-
-    // Name ::= CHOICE {
-    //     RDNSequence   }
-    //
-    // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-    DERSequenceEncoder name(idCert);
-    {
-      for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
-           it != m_subjectDescriptionList.end(); ++it)
-        {
-          it->encode(name);
-        }
-    }
-    name.MessageEnd();
-
-    // SubjectPublicKeyInfo
-    m_key.encode(idCert);
-
-    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
-    //
-    // Extension ::= SEQUENCE {
-    //        extnID      OBJECT IDENTIFIER,
-    //        critical    BOOLEAN DEFAULT FALSE,
-    //        extnValue   OCTET STRING  }
-    if (!m_extensionList.empty())
-      {
-        DERSequenceEncoder extensions(idCert);
-        {
-          for (ExtensionList::iterator it = m_extensionList.begin();
-               it != m_extensionList.end(); ++it)
-            {
-              it->encode(extensions);
-            }
-        }
-        extensions.MessageEnd();
-      }
-  }
-
-  idCert.MessageEnd();
-
-  setContent(os.buf());
-  setContentType(tlv::ContentType_Key);
-}
-
-void
-Certificate::decode()
-{
-  using namespace CryptoPP;
-
-  try {
-    OBufferStream os;
-    StringSource source(getContent().value(), getContent().value_size(), true);
-
-    // idCert ::= SEQUENCE {
-    //     validity            Validity,
-    //     subject             Name,
-    //     subjectPubKeyInfo   SubjectPublicKeyInfo,
-    //     extension           Extensions OPTIONAL   }
-    BERSequenceDecoder idCert(source);
-    {
-      // Validity ::= SEQUENCE {
-      //       notBefore           Time,
-      //       notAfter            Time   }
-      BERSequenceDecoder validity(idCert);
-      {
-        BERDecodeTime(validity, m_notBefore);
-        BERDecodeTime(validity, m_notAfter);
-      }
-      validity.MessageEnd();
-
-      // Name ::= CHOICE {
-      //     RDNSequence   }
-      //
-      // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-      m_subjectDescriptionList.clear();
-      BERSequenceDecoder name(idCert);
-      {
-        while (!name.EndReached())
-          {
-            m_subjectDescriptionList.push_back(CertificateSubjectDescription(name));
-          }
-      }
-      name.MessageEnd();
-
-      // SubjectPublicKeyInfo ::= SEQUENCE {
-      //     algorithm           AlgorithmIdentifier
-      //     keybits             BIT STRING   }
-      m_key.decode(idCert);
-
-      // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
-      //
-      // Extension ::= SEQUENCE {
-      //        extnID      OBJECT IDENTIFIER,
-      //        critical    BOOLEAN DEFAULT FALSE,
-      //        extnValue   OCTET STRING  }
-      m_extensionList.clear();
-      if (!idCert.EndReached())
-        {
-          BERSequenceDecoder extensions(idCert);
-          {
-            while (!extensions.EndReached())
-              {
-                m_extensionList.push_back(CertificateExtension(extensions));
-              }
-          }
-          extensions.MessageEnd();
-        }
-    }
-
-    idCert.MessageEnd();
-  }
-  catch (CryptoPP::BERDecodeErr&) {
-    BOOST_THROW_EXCEPTION(Error("Certificate Decoding Error"));
-  }
-}
-
-void
-Certificate::printCertificate(std::ostream& oss, const std::string& indent) const
-{
-  util::IndentedStream os(oss, indent);
-
-  os << "Certificate name:\n";
-  os << "  " << getName() << "\n";
-  os << "Validity:\n";
-  {
-    os << "  NotBefore: " << time::toIsoString(m_notBefore) << "\n";
-    os << "  NotAfter: "  << time::toIsoString(m_notAfter)  << "\n";
-  }
-
-  os << "Subject Description:\n";
-  for (const auto& description : m_subjectDescriptionList)
-    os << "  " << description.getOidString() << ": " << description.getValue() << "\n";
-
-  os << "Public key bits: ";
-  switch (m_key.getKeyType()) {
-  case KeyType::RSA:
-    os << "(RSA)";
-    break;
-  case KeyType::EC:
-    os << "(EC)";
-    break;
-  default:
-    os << "(Unknown key type)";
-    break;
-  }
-  os << "\n";
-
-  {
-    util::IndentedStream os2(os, "  ");
-    CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os2), true, 64);
-    m_key.encode(encoder);
-  }
-
-  os << "Signature Information:\n";
-  {
-    os << "  Signature Type: ";
-    switch (getSignature().getType()) {
-    case tlv::SignatureTypeValue::DigestSha256:
-      os << "DigestSha256";
-      break;
-    case tlv::SignatureTypeValue::SignatureSha256WithRsa:
-      os << "SignatureSha256WithRsa";
-      break;
-    case tlv::SignatureTypeValue::SignatureSha256WithEcdsa:
-      os << "SignatureSha256WithEcdsa";
-      break;
-    default:
-      os << "Unknown Signature Type";
-    }
-    os << "\n";
-
-    if (getSignature().hasKeyLocator()) {
-      const KeyLocator& keyLocator = getSignature().getKeyLocator();
-      os << "  Key Locator: ";
-      switch (keyLocator.getType()) {
-      case KeyLocator::KeyLocator_Name:
-        {
-          const Name& signerName = keyLocator.getName();
-          if (signerName.isPrefixOf(getName()))
-            os << "(Self-Signed) " << keyLocator.getName();
-          else
-            os << "(Name) " << keyLocator.getName();
-          break;
-        }
-      case KeyLocator::KeyLocator_KeyDigest:
-        os << "(KeyDigest)";
-        break;
-      case KeyLocator::KeyLocator_None:
-        os << "None";
-        break;
-      default:
-        os << "Unknown";
-      }
-      os << "\n";
-    }
-  }
-}
-
-std::ostream&
-operator<<(std::ostream& os, const Certificate& cert)
-{
-  cert.printCertificate(os);
-  return os;
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/certificate.hpp b/src/security/v1/certificate.hpp
deleted file mode 100644
index f2f70bf..0000000
--- a/src/security/v1/certificate.hpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NDN_SECURITY_V1_CERTIFICATE_HPP
-#define NDN_SECURITY_V1_CERTIFICATE_HPP
-
-#include "../../common.hpp"
-#include "../../data.hpp"
-#include "certificate-subject-description.hpp"
-#include "certificate-extension.hpp"
-#include "public-key.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class Certificate : public Data
-{
-public:
-  class Error : public Data::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Data::Error(what)
-    {
-    }
-  };
-
-  typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
-  typedef std::vector<CertificateExtension> ExtensionList;
-
-  /**
-   * @brief The default constructor.
-   */
-  Certificate();
-
-  /**
-   * @brief Create a Certificate from the content in the data packet.
-   * @param data The data packet with the content to decode.
-   */
-  explicit
-  Certificate(const Data& data);
-
-  /**
-   * @brief Create a Certificate from the a block
-   * @param block The raw block of the certificate
-   */
-  explicit
-  Certificate(const Block& block);
-
-  virtual
-  ~Certificate();
-
-  void
-  wireDecode(const Block& wire);
-
-  /**
-   * @brief encode certificate info into content
-   */
-  void
-  encode();
-
-  /**
-   * @brief Add a subject description.
-   * @param description The description to be added.
-   */
-  void
-  addSubjectDescription(const CertificateSubjectDescription& description)
-  {
-    m_subjectDescriptionList.push_back(description);
-  }
-
-  const SubjectDescriptionList&
-  getSubjectDescriptionList() const
-  {
-    return m_subjectDescriptionList;
-  }
-
-  SubjectDescriptionList&
-  getSubjectDescriptionList()
-  {
-    return m_subjectDescriptionList;
-  }
-
-  /**
-   * @brief Add a certificate extension.
-   * @param extension the extension to be added
-   */
-  void
-  addExtension(const CertificateExtension& extension)
-  {
-    m_extensionList.push_back(extension);
-  }
-
-  const ExtensionList&
-  getExtensionList() const
-  {
-    return m_extensionList;
-  }
-
-  ExtensionList&
-  getExtensionList()
-  {
-    return m_extensionList;
-  }
-
-  void
-  setNotBefore(const time::system_clock::TimePoint& notBefore)
-  {
-    m_notBefore = notBefore;
-  }
-
-  time::system_clock::TimePoint&
-  getNotBefore()
-  {
-    return m_notBefore;
-  }
-
-  const time::system_clock::TimePoint&
-  getNotBefore() const
-  {
-    return m_notBefore;
-  }
-
-  void
-  setNotAfter(const time::system_clock::TimePoint& notAfter)
-  {
-    m_notAfter = notAfter;
-  }
-
-  time::system_clock::TimePoint&
-  getNotAfter()
-  {
-    return m_notAfter;
-  }
-
-  const time::system_clock::TimePoint&
-  getNotAfter() const
-  {
-    return m_notAfter;
-  }
-
-  void
-  setPublicKeyInfo(const PublicKey& key)
-  {
-    m_key = key;
-  }
-
-  PublicKey&
-  getPublicKeyInfo()
-  {
-    return m_key;
-  }
-
-  const PublicKey&
-  getPublicKeyInfo() const
-  {
-    return m_key;
-  }
-
-  /**
-   * @brief Check if the certificate is valid.
-   * @return True if the current time is earlier than notBefore.
-   */
-  bool
-  isTooEarly();
-
-  /**
-   * @brief Check if the certificate is valid.
-   * @return True if the current time is later than notAfter.
-   */
-  bool
-  isTooLate();
-
-  void
-  printCertificate(std::ostream& os, const std::string& indent = "") const;
-
-protected:
-  void
-  decode();
-
-protected:
-  SubjectDescriptionList m_subjectDescriptionList;
-  time::system_clock::TimePoint m_notBefore;
-  time::system_clock::TimePoint m_notAfter;
-  PublicKey m_key;
-  ExtensionList m_extensionList;
-};
-
-std::ostream&
-operator<<(std::ostream& os, const Certificate& cert);
-
-} // namespace v1
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-/// @deprecated When needed, use explicit namespace
-using security::v1::Certificate;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_CERTIFICATE_HPP
diff --git a/src/security/v1/cryptopp.hpp b/src/security/v1/cryptopp.hpp
deleted file mode 100644
index 4de66bb..0000000
--- a/src/security/v1/cryptopp.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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_SECURITY_V1_CRYPTOPP_HPP
-#define NDN_SECURITY_V1_CRYPTOPP_HPP
-
-// suppress CryptoPP warnings
-#pragma GCC system_header
-#pragma clang system_header
-
-#include <cryptopp/asn.h>
-#include <cryptopp/base64.h>
-#include <cryptopp/des.h>
-#include <cryptopp/files.h>
-#include <cryptopp/filters.h>
-#include <cryptopp/hex.h>
-#include <cryptopp/modes.h>
-#include <cryptopp/osrng.h>
-#include <cryptopp/pssr.h>
-#include <cryptopp/pwdbased.h>
-#include <cryptopp/rsa.h>
-#include <cryptopp/sha.h>
-#include <cryptopp/eccrypto.h>
-#include <cryptopp/oids.h>
-#include <cryptopp/dsa.h>
-
-#endif // NDN_SECURITY_V1_CRYPTOPP_HPP
diff --git a/src/security/v1/identity-certificate.cpp b/src/security/v1/identity-certificate.cpp
deleted file mode 100644
index ea8a946..0000000
--- a/src/security/v1/identity-certificate.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- */
-
-#include "identity-certificate.hpp"
-#include "../../util/concepts.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-using std::string;
-
-BOOST_CONCEPT_ASSERT((WireEncodable<IdentityCertificate>));
-BOOST_CONCEPT_ASSERT((WireDecodable<IdentityCertificate>));
-static_assert(std::is_base_of<Certificate::Error, IdentityCertificate::Error>::value,
-              "IdentityCertificate::Error must inherit from Certificate::Error");
-
-IdentityCertificate::IdentityCertificate()
-{
-  this->setFreshnessPeriod(time::hours(1));
-}
-
-IdentityCertificate::IdentityCertificate(const Data& data)
-  : Certificate(data)
-{
-  setPublicKeyName();
-}
-
-IdentityCertificate::IdentityCertificate(const Block& block)
-  : Certificate(block)
-{
-  setPublicKeyName();
-}
-
-void
-IdentityCertificate::wireDecode(const Block& wire)
-{
-  Certificate::wireDecode(wire);
-  setPublicKeyName();
-}
-
-void
-IdentityCertificate::setName(const Name& name)
-{
-  Certificate::setName(name);
-  setPublicKeyName();
-}
-
-bool
-IdentityCertificate::isCorrectName(const Name& name)
-{
-  string idString("ID-CERT");
-  ssize_t i = name.size() - 1;
-  for (; i >= 0; i--) {
-    if (name.get(i).toUri() == idString)
-      break;
-  }
-
-  if (i < 0)
-    return false;
-
-  string keyString("KEY");
-  size_t keyIndex = 0;
-  for (; keyIndex < name.size(); keyIndex++) {
-    if (name.get(keyIndex).toUri() == keyString)
-      break;
-  }
-
-  if (keyIndex >= name.size())
-    return false;
-
-  return true;
-}
-
-void
-IdentityCertificate::setPublicKeyName()
-{
-  if (!isCorrectName(getName()))
-    BOOST_THROW_EXCEPTION(Error("Wrong Identity Certificate Name"));
-
-  m_publicKeyName = certificateNameToPublicKeyName(getName());
-}
-
-bool
-IdentityCertificate::isIdentityCertificate(const Certificate& certificate)
-{
-  return dynamic_cast<const IdentityCertificate*>(&certificate);
-}
-
-Name
-IdentityCertificate::certificateNameToPublicKeyName(const Name& certificateName)
-{
-  string idString("ID-CERT");
-  bool foundIdString = false;
-  size_t idCertComponentIndex = certificateName.size() - 1;
-  for (; idCertComponentIndex + 1 > 0; --idCertComponentIndex) {
-    if (certificateName.get(idCertComponentIndex).toUri() == idString)
-      {
-        foundIdString = true;
-        break;
-      }
-  }
-
-  if (!foundIdString)
-    BOOST_THROW_EXCEPTION(Error("Incorrect identity certificate name " + certificateName.toUri()));
-
-  Name tmpName = certificateName.getSubName(0, idCertComponentIndex);
-  string keyString("KEY");
-  bool foundKeyString = false;
-  size_t keyComponentIndex = 0;
-  for (; keyComponentIndex < tmpName.size(); keyComponentIndex++) {
-    if (tmpName.get(keyComponentIndex).toUri() == keyString)
-      {
-        foundKeyString = true;
-        break;
-      }
-  }
-
-  if (!foundKeyString)
-    BOOST_THROW_EXCEPTION(Error("Incorrect identity certificate name " + certificateName.toUri()));
-
-  return tmpName
-           .getSubName(0, keyComponentIndex)
-           .append(tmpName.getSubName(keyComponentIndex + 1,
-                                      tmpName.size() - keyComponentIndex - 1));
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/identity-certificate.hpp b/src/security/v1/identity-certificate.hpp
deleted file mode 100644
index 7ea4fe4..0000000
--- a/src/security/v1/identity-certificate.hpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
-#define NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
-
-#include "../../common.hpp"
-#include "certificate.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class IdentityCertificate : public Certificate
-{
-public:
-  class Error : public Certificate::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : Certificate::Error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief The default constructor.
-   */
-  IdentityCertificate();
-
-  /**
-   * @brief Create an IdentityCertificate from the content in the data packet.
-   * @param data The data packet with the content to decode.
-   */
-  explicit
-  IdentityCertificate(const Data& data);
-
-  /**
-   * @brief Create an IdentityCertificate from a block.
-   * @param block The raw block of the certificate.
-   */
-  explicit
-  IdentityCertificate(const Block& block);
-
-  void
-  wireDecode(const Block& wire);
-
-  void
-  setName(const Name& name);
-
-  const Name&
-  getPublicKeyName() const
-  {
-    return m_publicKeyName;
-  }
-
-  static bool
-  isIdentityCertificate(const Certificate& certificate);
-
-  /**
-   * @brief Get the public key name from the full certificate name.
-   * @param certificateName The full certificate name.
-   * @return The related public key name.
-   */
-  static Name
-  certificateNameToPublicKeyName(const Name& certificateName);
-
-private:
-  static bool
-  isCorrectName(const Name& name);
-
-  void
-  setPublicKeyName();
-
-protected:
-  Name m_publicKeyName;
-};
-
-} // namespace v1
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-/// @deprecated When needed, use explicit namespace
-using security::v1::IdentityCertificate;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
diff --git a/src/security/v1/key-chain.cpp b/src/security/v1/key-chain.cpp
deleted file mode 100644
index 8c9a56a..0000000
--- a/src/security/v1/key-chain.cpp
+++ /dev/null
@@ -1,842 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#include "key-chain.hpp"
-#include "../signing-helpers.hpp"
-
-#include "../../util/config-file.hpp"
-#include "../../util/sha256.hpp"
-
-#include "sec-public-info-sqlite3.hpp"
-
-#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
-#include "sec-tpm-osx.hpp"
-#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
-
-#include "sec-tpm-file.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-// Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
-const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
-
-// Note: cannot use default constructor, as it depends on static variables which may or may not be
-// initialized at this point
-const SigningInfo KeyChain::DEFAULT_SIGNING_INFO(SigningInfo::SIGNER_TYPE_NULL, Name(), SignatureInfo());
-
-const RsaKeyParams KeyChain::DEFAULT_KEY_PARAMS;
-
-const std::string DEFAULT_PIB_SCHEME = "pib-sqlite3";
-
-#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
-const std::string DEFAULT_TPM_SCHEME = "tpm-osxkeychain";
-#else
-const std::string DEFAULT_TPM_SCHEME = "tpm-file";
-#endif // defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
-
-// When static library is used, not everything is compiled into the resulting binary.
-// Therefore, the following standard PIB and TPMs need to be registered here.
-// http://stackoverflow.com/q/9459980/2150331
-//
-// Also, cannot use Type::SCHEME, as its value may be uninitialized
-NDN_CXX_V1_KEYCHAIN_REGISTER_PIB(SecPublicInfoSqlite3, "pib-sqlite3", "sqlite3");
-
-#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
-NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(SecTpmOsx, "tpm-osxkeychain", "osx-keychain");
-#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
-
-NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(SecTpmFile, "tpm-file", "file");
-
-template<class T>
-struct Factory
-{
-  Factory(const std::string& canonicalName, const T& create)
-    : canonicalName(canonicalName)
-    , create(create)
-  {
-  }
-
-  std::string canonicalName;
-  T create;
-};
-typedef Factory<KeyChain::PibCreateFunc> PibFactory;
-typedef Factory<KeyChain::TpmCreateFunc> TpmFactory;
-
-static std::map<std::string, PibFactory>&
-getPibFactories()
-{
-  static std::map<std::string, PibFactory> pibFactories;
-  return pibFactories;
-}
-
-static std::map<std::string, TpmFactory>&
-getTpmFactories()
-{
-  static std::map<std::string, TpmFactory> tpmFactories;
-  return tpmFactories;
-}
-
-void
-KeyChain::registerPibImpl(const std::string& canonicalName,
-                          std::initializer_list<std::string> aliases,
-                          KeyChain::PibCreateFunc createFunc)
-{
-  for (const std::string& alias : aliases) {
-    getPibFactories().insert(make_pair(alias, PibFactory(canonicalName, createFunc)));
-  }
-}
-
-void
-KeyChain::registerTpmImpl(const std::string& canonicalName,
-                          std::initializer_list<std::string> aliases,
-                          KeyChain::TpmCreateFunc createFunc)
-{
-  for (const std::string& alias : aliases) {
-    getTpmFactories().insert(make_pair(alias, TpmFactory(canonicalName, createFunc)));
-  }
-}
-
-KeyChain::KeyChain()
-  : m_pib(nullptr)
-  , m_tpm(nullptr)
-  , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
-{
-  std::string pibLocator;
-  std::string tpmLocator;
-
-  if (getenv("NDN_CLIENT_PIB") != nullptr) {
-    pibLocator = getenv("NDN_CLIENT_PIB");
-  }
-
-  if (getenv("NDN_CLIENT_TPM") != nullptr) {
-    tpmLocator = getenv("NDN_CLIENT_TPM");
-  }
-
-  if (pibLocator.empty() || tpmLocator.empty()) {
-    ConfigFile config;
-    const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
-
-    if (pibLocator.empty()) {
-      pibLocator = parsed.get<std::string>("pib", "");
-    }
-
-    if (tpmLocator.empty()) {
-      tpmLocator = parsed.get<std::string>("tpm", "");
-    }
-  }
-
-  initialize(pibLocator, tpmLocator, false);
-}
-
-KeyChain::KeyChain(const std::string& pibName,
-                   const std::string& tpmName,
-                   bool allowReset)
-  : m_pib(nullptr)
-  , m_tpm(nullptr)
-  , m_lastTimestamp(time::toUnixTimestamp(time::system_clock::now()))
-{
-  initialize(pibName, tpmName, allowReset);
-}
-
-KeyChain::~KeyChain()
-{
-}
-
-static inline std::tuple<std::string/*type*/, std::string/*location*/>
-parseUri(const std::string& uri)
-{
-  size_t pos = uri.find(':');
-  if (pos != std::string::npos) {
-    return std::make_tuple(uri.substr(0, pos),
-                           uri.substr(pos + 1));
-  }
-  else {
-    return std::make_tuple(uri, "");
-  }
-}
-
-std::string
-KeyChain::getDefaultPibLocator()
-{
-  std::string defaultPibLocator = DEFAULT_PIB_SCHEME + ":";
-  return defaultPibLocator;
-}
-
-static inline std::tuple<std::string/*type*/, std::string/*location*/>
-getCanonicalPibLocator(const std::string& pibLocator)
-{
-  std::string pibScheme, pibLocation;
-  std::tie(pibScheme, pibLocation) = parseUri(pibLocator);
-
-  if (pibScheme.empty()) {
-    pibScheme = DEFAULT_PIB_SCHEME;
-  }
-
-  auto pibFactory = getPibFactories().find(pibScheme);
-  if (pibFactory == getPibFactories().end()) {
-    BOOST_THROW_EXCEPTION(KeyChain::Error("PIB scheme '" + pibScheme + "' is not supported"));
-  }
-  pibScheme = pibFactory->second.canonicalName;
-
-  return std::make_tuple(pibScheme, pibLocation);
-}
-
-unique_ptr<SecPublicInfo>
-KeyChain::createPib(const std::string& pibLocator)
-{
-  BOOST_ASSERT(!getPibFactories().empty());
-
-  std::string pibScheme, pibLocation;
-  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
-  auto pibFactory = getPibFactories().find(pibScheme);
-  BOOST_ASSERT(pibFactory != getPibFactories().end());
-  return pibFactory->second.create(pibLocation);
-}
-
-std::string
-KeyChain::getDefaultTpmLocator()
-{
-  std::string defaultTpmLocator = DEFAULT_TPM_SCHEME + ":";
-  return defaultTpmLocator;
-}
-
-static inline std::tuple<std::string/*type*/, std::string/*location*/>
-getCanonicalTpmLocator(const std::string& tpmLocator)
-{
-  std::string tpmScheme, tpmLocation;
-  std::tie(tpmScheme, tpmLocation) = parseUri(tpmLocator);
-
-  if (tpmScheme.empty()) {
-    tpmScheme = DEFAULT_TPM_SCHEME;
-  }
-  auto tpmFactory = getTpmFactories().find(tpmScheme);
-  if (tpmFactory == getTpmFactories().end()) {
-    BOOST_THROW_EXCEPTION(KeyChain::Error("TPM scheme '" + tpmScheme + "' is not supported"));
-  }
-  tpmScheme = tpmFactory->second.canonicalName;
-
-  return std::make_tuple(tpmScheme, tpmLocation);
-}
-
-unique_ptr<SecTpm>
-KeyChain::createTpm(const std::string& tpmLocator)
-{
-  BOOST_ASSERT(!getTpmFactories().empty());
-
-  std::string tpmScheme, tpmLocation;
-  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
-  auto tpmFactory = getTpmFactories().find(tpmScheme);
-  BOOST_ASSERT(tpmFactory != getTpmFactories().end());
-  return tpmFactory->second.create(tpmLocation);
-}
-
-void
-KeyChain::initialize(const std::string& pibLocator,
-                     const std::string& tpmLocator,
-                     bool allowReset)
-{
-  // PIB Locator
-  std::string pibScheme, pibLocation;
-  std::tie(pibScheme, pibLocation) = getCanonicalPibLocator(pibLocator);
-  std::string canonicalPibLocator = pibScheme + ":" + pibLocation;
-
-  // Create PIB
-  m_pib = createPib(canonicalPibLocator);
-
-  // TPM Locator
-  std::string tpmScheme, tpmLocation;
-  std::tie(tpmScheme, tpmLocation) = getCanonicalTpmLocator(tpmLocator);
-  std::string canonicalTpmLocator = tpmScheme + ":" + tpmLocation;
-
-  // Create TPM, checking that it matches to the previously associated one
-  try {
-    if (!allowReset &&
-        !m_pib->getTpmLocator().empty() && m_pib->getTpmLocator() != canonicalTpmLocator)
-      // Tpm mismatch, but we do not want to reset PIB
-      BOOST_THROW_EXCEPTION(MismatchError("TPM locator supplied does not match TPM locator in PIB: "
-                                          + m_pib->getTpmLocator() + " != " + canonicalTpmLocator));
-  }
-  catch (const SecPublicInfo::Error&) {
-    // TPM locator is not set in PIB yet.
-  }
-
-  // note that key mismatch may still happen if the TPM locator is initially set to a
-  // wrong one or if the PIB was shared by more than one TPMs before.  This is due to the
-  // old PIB does not have TPM info, new pib should not have this problem.
-  m_tpm = createTpm(canonicalTpmLocator);
-  m_pib->setTpmLocator(canonicalTpmLocator);
-}
-
-Name
-KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
-{
-  m_pib->addIdentity(identityName);
-
-  Name keyName;
-  try {
-    keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
-
-    shared_ptr<PublicKey> key = m_pib->getPublicKey(keyName);
-
-    if (key->getKeyType() != params.getKeyType()) {
-      keyName = generateKeyPair(identityName, true, params);
-      m_pib->setDefaultKeyNameForIdentity(keyName);
-    }
-  }
-  catch (const SecPublicInfo::Error& e) {
-    keyName = generateKeyPair(identityName, true, params);
-    m_pib->setDefaultKeyNameForIdentity(keyName);
-  }
-
-  Name certName;
-  try {
-    certName = m_pib->getDefaultCertificateNameForKey(keyName);
-  }
-  catch (const SecPublicInfo::Error& e) {
-    shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
-    m_pib->addCertificateAsIdentityDefault(*selfCert);
-    certName = selfCert->getName();
-  }
-
-  return certName;
-}
-
-Name
-KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
-{
-  RsaKeyParams params(keySize);
-  return generateKeyPair(identityName, isKsk, params);
-}
-
-Name
-KeyChain::generateEcKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
-{
-  EcKeyParams params(keySize);
-  return generateKeyPair(identityName, isKsk, params);
-}
-
-Name
-KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
-{
-  Name keyName = generateRsaKeyPair(identityName, isKsk, keySize);
-
-  m_pib->setDefaultKeyNameForIdentity(keyName);
-
-  return keyName;
-}
-
-Name
-KeyChain::generateEcKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
-{
-  Name keyName = generateEcKeyPair(identityName, isKsk, keySize);
-
-  m_pib->setDefaultKeyNameForIdentity(keyName);
-
-  return keyName;
-}
-
-
-shared_ptr<IdentityCertificate>
-KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
-  const Name& signingIdentity,
-  const time::system_clock::TimePoint& notBefore,
-  const time::system_clock::TimePoint& notAfter,
-  const std::vector<CertificateSubjectDescription>& subjectDescription,
-  const Name& certPrefix)
-{
-  shared_ptr<PublicKey> publicKey;
-  try {
-    publicKey = m_pib->getPublicKey(keyName);
-  }
-  catch (const SecPublicInfo::Error& e) {
-    return nullptr;
-  }
-
-  return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
-                                            notBefore, notAfter,
-                                            subjectDescription, certPrefix);
-}
-
-shared_ptr<IdentityCertificate>
-KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
-  const PublicKey& publicKey,
-  const Name& signingIdentity,
-  const time::system_clock::TimePoint& notBefore,
-  const time::system_clock::TimePoint& notAfter,
-  const std::vector<CertificateSubjectDescription>& subjectDescription,
-  const Name& certPrefix)
-{
-  if (keyName.size() < 1)
-    return nullptr;
-
-  std::string keyIdPrefix = keyName.get(-1).toUri().substr(0, 4);
-  if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
-    return nullptr;
-
-  Name certName;
-
-  if (certPrefix == KeyChain::DEFAULT_PREFIX) {
-    // No certificate prefix hint, infer the prefix
-    if (signingIdentity.isPrefixOf(keyName))
-      certName.append(signingIdentity)
-        .append("KEY")
-        .append(keyName.getSubName(signingIdentity.size()))
-        .append("ID-CERT")
-        .appendVersion();
-    else
-      certName.append(keyName.getPrefix(-1))
-        .append("KEY")
-        .append(keyName.get(-1))
-        .append("ID-CERT")
-        .appendVersion();
-  }
-  else {
-    // cert prefix hint is supplied, determine the cert name.
-    if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
-      certName.append(certPrefix)
-        .append("KEY")
-        .append(keyName.getSubName(certPrefix.size()))
-        .append("ID-CERT")
-        .appendVersion();
-    else
-      return nullptr;
-  }
-
-  auto certificate = make_shared<IdentityCertificate>();
-  certificate->setName(certName);
-  certificate->setNotBefore(notBefore);
-  certificate->setNotAfter(notAfter);
-  certificate->setPublicKeyInfo(publicKey);
-
-  if (subjectDescription.empty()) {
-    CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
-    certificate->addSubjectDescription(subjectName);
-  }
-  else {
-    std::vector<CertificateSubjectDescription>::const_iterator sdIt = subjectDescription.begin();
-    std::vector<CertificateSubjectDescription>::const_iterator sdEnd = subjectDescription.end();
-    for(; sdIt != sdEnd; sdIt++)
-      certificate->addSubjectDescription(*sdIt);
-  }
-
-  certificate->encode();
-
-  return certificate;
-}
-
-std::tuple<Name, SignatureInfo>
-KeyChain::prepareSignatureInfo(const SigningInfo& params)
-{
-  SignatureInfo sigInfo = params.getSignatureInfo();
-
-  shared_ptr<IdentityCertificate> signingCert;
-
-  switch (params.getSignerType()) {
-    case SigningInfo::SIGNER_TYPE_NULL: {
-      if (m_pib->getDefaultCertificate() == nullptr)
-        setDefaultCertificateInternal();
-
-      signingCert = m_pib->getDefaultCertificate();
-      break;
-    }
-    case SigningInfo::SIGNER_TYPE_ID:  {
-      Name signingCertName;
-      try {
-        signingCertName = m_pib->getDefaultCertificateNameForIdentity(params.getSignerName());
-      }
-      catch (const SecPublicInfo::Error&) {
-        signingCertName = createIdentity(params.getSignerName(), getDefaultKeyParamsForIdentity(params.getSignerName()));
-      }
-
-      signingCert = m_pib->getCertificate(signingCertName);
-
-      break;
-    }
-    case SigningInfo::SIGNER_TYPE_KEY: {
-      Name signingCertName;
-      try {
-        signingCertName = m_pib->getDefaultCertificateNameForKey(params.getSignerName());
-      }
-      catch (const SecPublicInfo::Error&) {
-        BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
-      }
-
-      signingCert = m_pib->getCertificate(signingCertName);
-
-      break;
-    }
-    case SigningInfo::SIGNER_TYPE_CERT: {
-      signingCert = m_pib->getCertificate(params.getSignerName());
-      if (signingCert == nullptr)
-        BOOST_THROW_EXCEPTION(Error("signing certificate does not exist"));
-
-      break;
-    }
-    case SigningInfo::SIGNER_TYPE_SHA256: {
-      sigInfo.setSignatureType(tlv::DigestSha256);
-      return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
-    }
-    default:
-      BOOST_THROW_EXCEPTION(Error("Unrecognized signer type"));
-  }
-
-  sigInfo.setSignatureType(getSignatureType(signingCert->getPublicKeyInfo().getKeyType(),
-                                            params.getDigestAlgorithm()));
-  sigInfo.setKeyLocator(KeyLocator(signingCert->getName().getPrefix(-1)));
-
-  return std::make_tuple(signingCert->getPublicKeyName(), sigInfo);
-}
-
-void
-KeyChain::sign(Data& data, const SigningInfo& params)
-{
-  signImpl(data, params);
-}
-
-void
-KeyChain::sign(Interest& interest, const SigningInfo& params)
-{
-  signImpl(interest, params);
-}
-
-Block
-KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params)
-{
-  Name keyName;
-  SignatureInfo sigInfo;
-  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
-  return pureSign(buffer, bufferLength, keyName, DigestAlgorithm::SHA256);
-}
-
-Signature
-KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
-{
-  shared_ptr<IdentityCertificate> certificate = m_pib->getCertificate(certificateName);
-
-  if (certificate == nullptr) {
-    BOOST_THROW_EXCEPTION(SecPublicInfo::Error("certificate does not exist"));
-  }
-
-  Signature sig;
-
-  // For temporary usage, we support SHA256 only, but will support more.
-  sig.setValue(m_tpm->signInTpm(buffer, bufferLength,
-                                certificate->getPublicKeyName(),
-                                DigestAlgorithm::SHA256));
-
-  return sig;
-}
-
-shared_ptr<IdentityCertificate>
-KeyChain::selfSign(const Name& keyName)
-{
-  shared_ptr<PublicKey> pubKey;
-  try {
-    pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
-  }
-  catch (const SecPublicInfo::Error&) {
-    return nullptr;
-  }
-
-  auto certificate = make_shared<IdentityCertificate>();
-
-  Name certificateName = keyName.getPrefix(-1);
-  certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
-
-  certificate->setName(certificateName);
-  certificate->setNotBefore(time::system_clock::now());
-  certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
-  certificate->setPublicKeyInfo(*pubKey);
-  certificate->addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
-                                                                       keyName.toUri()));
-  certificate->encode();
-
-  certificate->setSignature(Signature(SignatureInfo()));
-
-  selfSign(*certificate);
-  return certificate;
-}
-
-void
-KeyChain::selfSign(IdentityCertificate& cert)
-{
-  Name keyName = cert.getPublicKeyName();
-
-  if (!m_tpm->doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
-    BOOST_THROW_EXCEPTION(SecTpm::Error("Private key does not exist"));
-
-  SignatureInfo sigInfo(cert.getSignature().getInfo());
-  sigInfo.setKeyLocator(KeyLocator(cert.getName().getPrefix(-1)));
-  sigInfo.setSignatureType(getSignatureType(cert.getPublicKeyInfo().getKeyType(),
-                                            DigestAlgorithm::SHA256));
-
-  signPacketWrapper(cert, Signature(sigInfo), keyName, DigestAlgorithm::SHA256);
-}
-
-shared_ptr<SecuredBag>
-KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
-{
-  if (!m_pib->doesIdentityExist(identity))
-    BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Identity does not exist"));
-
-  Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
-
-  ConstBufferPtr pkcs5;
-  try {
-    pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
-  }
-  catch (const SecTpm::Error& e) {
-    BOOST_THROW_EXCEPTION(SecPublicInfo::Error("Fail to export PKCS5 of private key"));
-  }
-
-  shared_ptr<IdentityCertificate> cert;
-  try {
-    cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
-  }
-  catch (const SecPublicInfo::Error& e) {
-    cert = selfSign(keyName);
-    m_pib->addCertificateAsIdentityDefault(*cert);
-  }
-
-  // make_shared on OSX 10.9 has some strange problem here
-  return shared_ptr<SecuredBag>(new SecuredBag(*cert, pkcs5));
-}
-
-void
-KeyChain::importIdentity(const SecuredBag& securedBag, const std::string& passwordStr)
-{
-  Name certificateName = securedBag.getCertificate().getName();
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  Name identity = keyName.getPrefix(-1);
-
-  // Add identity
-  m_pib->addIdentity(identity);
-
-  // Add key
-  m_tpm->importPrivateKeyPkcs5IntoTpm(keyName,
-                                      securedBag.getKey()->buf(),
-                                      securedBag.getKey()->size(),
-                                      passwordStr);
-
-  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
-  // HACK! We should set key type according to the pkcs8 info.
-  m_pib->addKey(keyName, *pubKey);
-  m_pib->setDefaultKeyNameForIdentity(keyName);
-
-  // Add cert
-  m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
-}
-
-const KeyParams&
-KeyChain::getDefaultKeyParamsForIdentity(const Name& identityName) const
-{
-  KeyType keyType = KeyType::NONE;
-  try {
-    keyType = m_pib->getPublicKeyType(m_pib->getDefaultKeyNameForIdentity(identityName));
-  }
-  catch (const SecPublicInfo::Error& e) { // @TODO Switch to Pib::Error
-    return DEFAULT_KEY_PARAMS;
-  }
-
-  switch (keyType) {
-    case KeyType::RSA: {
-      static RsaKeyParams defaultRsaParams;
-      return defaultRsaParams;
-    }
-    case KeyType::EC: {
-      static EcKeyParams defaultEcParams;
-      return defaultEcParams;
-    }
-    case KeyType::NONE: {
-      return DEFAULT_KEY_PARAMS;
-    }
-    default:
-      BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
-  }
-}
-
-void
-KeyChain::setDefaultCertificateInternal()
-{
-  m_pib->refreshDefaultCertificate();
-
-  if (m_pib->getDefaultCertificate() == nullptr) {
-    Name defaultIdentity;
-    try {
-      defaultIdentity = m_pib->getDefaultIdentity();
-    }
-    catch (const SecPublicInfo::Error& e) {
-      uint32_t random = random::generateWord32();
-      defaultIdentity.append("tmp-identity")
-        .append(reinterpret_cast<uint8_t*>(&random), 4);
-    }
-    createIdentity(defaultIdentity);
-    m_pib->setDefaultIdentity(defaultIdentity);
-    m_pib->refreshDefaultCertificate();
-  }
-}
-
-Name
-KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
-{
-  Name keyName = m_pib->getNewKeyName(identityName, isKsk);
-
-  m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
-
-  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
-  m_pib->addKey(keyName, *pubKey);
-
-  return keyName;
-}
-
-void
-KeyChain::signPacketWrapper(Data& data, const Signature& signature,
-                            const Name& keyName, DigestAlgorithm digestAlgorithm)
-{
-  data.setSignature(signature);
-
-  EncodingBuffer encoder;
-  data.wireEncode(encoder, true);
-
-  Block sigValue = pureSign(encoder.buf(), encoder.size(), keyName, digestAlgorithm);
-
-  data.wireEncode(encoder, sigValue);
-}
-
-void
-KeyChain::signPacketWrapper(Interest& interest, const Signature& signature,
-                            const Name& keyName, DigestAlgorithm digestAlgorithm)
-{
-  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
-  if (timestamp <= m_lastTimestamp) {
-    timestamp = m_lastTimestamp + time::milliseconds(1);
-  }
-
-  Name signedName = interest.getName();
-  signedName
-    .append(name::Component::fromNumber(timestamp.count()))        // timestamp
-    .append(name::Component::fromNumber(random::generateWord64())) // nonce
-    .append(signature.getInfo());                                  // signatureInfo
-
-  Block sigValue = pureSign(signedName.wireEncode().value(),
-                            signedName.wireEncode().value_size(),
-                            keyName,
-                            digestAlgorithm);
-
-  sigValue.encode();
-  signedName.append(sigValue);                                     // signatureValue
-  interest.setName(signedName);
-}
-
-Block
-KeyChain::pureSign(const uint8_t* buf, size_t size,
-                   const Name& keyName, DigestAlgorithm digestAlgorithm) const
-{
-  if (keyName == SigningInfo::getDigestSha256Identity())
-    return Block(tlv::SignatureValue, util::Sha256::computeDigest(buf, size));
-
-  return m_tpm->signInTpm(buf, size, keyName, digestAlgorithm);
-}
-
-Signature
-KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
-{
-  Signature sig;
-  sig.setValue(sign(buffer, bufferLength, signingByIdentity(identityName)));
-  return sig;
-}
-
-void
-KeyChain::signWithSha256(Data& data)
-{
-  return sign(data, signingWithSha256());
-}
-
-void
-KeyChain::signWithSha256(Interest& interest)
-{
-  DigestSha256 sig;
-
-  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
-  if (timestamp <= m_lastTimestamp)
-    timestamp = m_lastTimestamp + time::milliseconds(1);
-
-  Name signedName = interest.getName();
-  signedName
-    .append(name::Component::fromNumber(timestamp.count()))        // timestamp
-    .append(name::Component::fromNumber(random::generateWord64())) // nonce
-    .append(sig.getInfo());                                        // signatureInfo
-
-  Block sigValue(tlv::SignatureValue,
-                 util::Sha256::computeDigest(signedName.wireEncode().value(),
-                                             signedName.wireEncode().value_size()));
-
-  sigValue.encode();
-  signedName.append(sigValue);                                     // signatureValue
-  interest.setName(signedName);
-}
-
-void
-KeyChain::deleteCertificate(const Name& certificateName)
-{
-  m_pib->deleteCertificateInfo(certificateName);
-}
-
-void
-KeyChain::deleteKey(const Name& keyName)
-{
-  m_pib->deletePublicKeyInfo(keyName);
-  m_tpm->deleteKeyPairInTpm(keyName);
-}
-
-void
-KeyChain::deleteIdentity(const Name& identity)
-{
-  std::vector<Name> keyNames;
-  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, true);
-  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, false);
-
-  m_pib->deleteIdentityInfo(identity);
-
-  for (const auto& keyName : keyNames)
-    m_tpm->deleteKeyPairInTpm(keyName);
-}
-
-tlv::SignatureTypeValue
-KeyChain::getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm)
-{
-  switch (keyType) {
-    case KeyType::RSA:
-      return tlv::SignatureSha256WithRsa;
-    case KeyType::EC:
-      return tlv::SignatureSha256WithEcdsa;
-    default:
-      BOOST_THROW_EXCEPTION(Error("Unsupported key types"));
-  }
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/key-chain.hpp b/src/security/v1/key-chain.hpp
deleted file mode 100644
index 3a84a47..0000000
--- a/src/security/v1/key-chain.hpp
+++ /dev/null
@@ -1,966 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_V1_KEY_CHAIN_HPP
-#define NDN_SECURITY_V1_KEY_CHAIN_HPP
-
-#include "sec-public-info.hpp"
-#include "sec-tpm.hpp"
-#include "secured-bag.hpp"
-#include "../key-params.hpp"
-#include "../signature-sha256-with-rsa.hpp"
-#include "../signature-sha256-with-ecdsa.hpp"
-#include "../digest-sha256.hpp"
-#include "../signing-info.hpp"
-#include "../../interest.hpp"
-#include "../../util/random.hpp"
-#include <initializer_list>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-/**
- * @brief The packet signing interface.
- *
- * @deprecated Use v2::KeyChain
- */
-class KeyChain : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Error thrown when the supplied TPM locator to KeyChain constructor does not match
-   *        the locator stored in PIB
-   */
-  class MismatchError : public Error
-  {
-  public:
-    explicit
-    MismatchError(const std::string& what)
-      : Error(what)
-    {
-    }
-  };
-
-  typedef function<unique_ptr<SecPublicInfo> (const std::string&)> PibCreateFunc;
-  typedef function<unique_ptr<SecTpm>(const std::string&)> TpmCreateFunc;
-
-  /**
-   * @brief Register a new PIB
-   * @param aliases List of schemes with which this PIB will be associated.
-   *        The first alias in the list is considered a canonical name of the PIB instance.
-   */
-  template<class PibType>
-  static void
-  registerPib(std::initializer_list<std::string> aliases);
-
-  /**
-   * @brief Register a new TPM
-   * @param aliases List of schemes with which this TPM will be associated
-   *        The first alias in the list is considered a canonical name of the TPM instance.
-   */
-  template<class TpmType>
-  static void
-  registerTpm(std::initializer_list<std::string> aliases);
-
-  /**
-   * @brief Get default PIB locator
-   */
-  static std::string
-  getDefaultPibLocator();
-
-  /**
-    * @brief Create a PIB according to @p pibLocator
-    */
-  static unique_ptr<SecPublicInfo>
-  createPib(const std::string& pibLocator);
-
-  /**
-   * @brief Get default TPM locator
-   */
-  static std::string
-  getDefaultTpmLocator();
-
-  /**
-    * @brief Create a TPM according to @p tpmLocator
-    */
-  static unique_ptr<SecTpm>
-  createTpm(const std::string& tpmLocator);
-
-  /**
-   * @brief Constructor to create KeyChain with default PIB and TPM
-   *
-   * Default PIB and TPM are platform-dependent and can be overriden system-wide or on
-   * per-use basis.
-   *
-   * @todo Add detailed description about config file behavior here
-   */
-  KeyChain();
-
-  /**
-   * @brief KeyChain constructor
-   *
-   * @sa  https://redmine.named-data.net/issues/2260
-   *
-   * @param pibLocator PIB locator
-   * @param tpmLocator TPM locator
-   * @param allowReset if true, the PIB will be reset when the supplied tpmLocator
-   *        mismatches the one in PIB
-   */
-  KeyChain(const std::string& pibLocator,
-           const std::string& tpmLocator,
-           bool allowReset = false);
-
-  virtual
-  ~KeyChain();
-
-  /**
-   * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a
-   *        self-signed certificate of the KSK.
-   *
-   * @param identityName The name of the identity.
-   * @param params The key parameter if a key needs to be generated for the identity.
-   * @return The name of the default certificate of the identity.
-   */
-  Name
-  createIdentity(const Name& identityName, const KeyParams& params = DEFAULT_KEY_PARAMS);
-
-  /**
-   * @brief Generate a pair of RSA keys for the specified identity.
-   *
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   * @see generateEcKeyPair
-   */
-  Name
-  generateRsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
-
-  /**
-   * @brief Generate a pair of EC keys for the specified identity.
-   *
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   * @see generateRsaKeyPair
-   */
-  Name
-  generateEcKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 256);
-
-  /**
-   * @brief Generate a pair of RSA keys for the specified identity and set it as default key for
-   *        the identity.
-   *
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   * @see generateRsaKeyPair, generateEcKeyPair, generateEcKeyPairAsDefault
-   */
-  Name
-  generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
-
-  /**
-   * @brief Generate a pair of EC keys for the specified identity and set it as default key for
-   *        the identity.
-   *
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   * @see generateRsaKeyPair, generateEcKeyPair, generateRsaKeyPairAsDefault
-   */
-  Name
-  generateEcKeyPairAsDefault(const Name& identityName, bool isKsk = false, uint32_t keySize = 256);
-
-  /**
-   * @brief prepare an unsigned identity certificate
-   *
-   * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
-   * @param signingIdentity The signing identity.
-   * @param notBefore Refer to IdentityCertificate.
-   * @param notAfter Refer to IdentityCertificate.
-   * @param subjectDescription Refer to IdentityCertificate.
-   * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
-   *                   certificate name according to the relation between the signingIdentity and
-   *                   the subject identity. If signingIdentity is a prefix of the subject identity,
-   *                   `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
-   *                   after subject identity (i.e., before `ksk-....`).
-   * @return IdentityCertificate.
-   */
-  shared_ptr<IdentityCertificate>
-  prepareUnsignedIdentityCertificate(const Name& keyName,
-    const Name& signingIdentity,
-    const time::system_clock::TimePoint& notBefore,
-    const time::system_clock::TimePoint& notAfter,
-    const std::vector<CertificateSubjectDescription>& subjectDescription,
-    const Name& certPrefix = DEFAULT_PREFIX);
-
-  /**
-   * @brief prepare an unsigned identity certificate
-   *
-   * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
-   * @param publicKey Public key to sign.
-   * @param signingIdentity The signing identity.
-   * @param notBefore Refer to IdentityCertificate.
-   * @param notAfter Refer to IdentityCertificate.
-   * @param subjectDescription Refer to IdentityCertificate.
-   * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
-   *                   certificate name according to the relation between the signingIdentity and
-   *                   the subject identity. If signingIdentity is a prefix of the subject identity,
-   *                   `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
-   *                   after subject identity (i.e., before `ksk-....`).
-   * @return IdentityCertificate.
-   */
-  shared_ptr<IdentityCertificate>
-  prepareUnsignedIdentityCertificate(const Name& keyName,
-    const PublicKey& publicKey,
-    const Name& signingIdentity,
-    const time::system_clock::TimePoint& notBefore,
-    const time::system_clock::TimePoint& notAfter,
-    const std::vector<CertificateSubjectDescription>& subjectDescription,
-    const Name& certPrefix = DEFAULT_PREFIX);
-
-  /**
-   * @brief Sign data according to the supplied signing information
-   *
-   * This method uses the supplied signing information @p params to create the SignatureInfo block:
-   * - it selects a private key and its certificate to sign the packet
-   * - sets the KeyLocator field with the certificate name, and
-   * - adds other requested information to the SignatureInfo block).
-   *
-   * After that, the method assigns the created SignatureInfo to the data packets, generate a
-   * signature and sets as part of the SignatureValue block.
-   *
-   * @param data The data to sign
-   * @param params The signing parameters.
-   * @throws Error if signing fails.
-   * @see SigningInfo
-   */
-  void
-  sign(Data& data, const SigningInfo& params = DEFAULT_SIGNING_INFO);
-
-  /**
-   * @brief Sign interest according to the supplied signing information
-   *
-   * This method uses the supplied signing information @p params to create the SignatureInfo block:
-   * - it selects a private key and its certificate to sign the packet
-   * - sets the KeyLocator field with the certificate name, and
-   * - adds other requested information to the SignatureInfo block).
-   *
-   * After that, the method appends the created SignatureInfo to the interest name, generate a
-   * signature and appends it as part of the SignatureValue block to the interest name.
-   *
-   * @param interest The interest to sign
-   * @param params The signing parameters.
-   * @throws Error if signing fails.
-   * @see SigningInfo
-   */
-  void
-  sign(Interest& interest, const SigningInfo& params = DEFAULT_SIGNING_INFO);
-
-  /**
-   * @brief Sign buffer according to the supplied signing information
-   *
-   * @param buffer The buffer to sign
-   * @param bufferLength The buffer size
-   * @param params The signing parameters.
-   * @return a SignatureValue TLV block
-   * @throws Error if signing fails.
-   * @see SigningInfo
-   */
-  Block
-  sign(const uint8_t* buffer, size_t bufferLength, const SigningInfo& params);
-
-  /**
-   * @deprecated use sign sign(T&, const SigningInfo&)
-   * @brief Sign packet with a particular certificate.
-   *
-   * @param packet The packet to be signed.
-   * @param certificateName The certificate name of the key to use for signing.
-   * @throws SecPublicInfo::Error if certificate does not exist.
-   */
-  template<typename T>
-  void
-  sign(T& packet, const Name& certificateName);
-
-  /**
-   * @deprecated Use sign(const uint8_t*, size_t, const SigningInfo&) instead
-   * @brief Sign the byte array using a particular certificate.
-   *
-   * @param buffer The byte array to be signed.
-   * @param bufferLength the length of buffer.
-   * @param certificateName The certificate name of the signing key.
-   * @return The Signature.
-   * @throws SecPublicInfo::Error if certificate does not exist.
-   */
-  Signature
-  sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
-
-  /**
-   * @deprecated use sign sign(T&, const SigningInfo&)
-   * @brief Sign packet using the default certificate of a particular identity.
-   *
-   * If there is no default certificate of that identity, this method will create a self-signed
-   * certificate.
-   *
-   * @param packet The packet to be signed.
-   * @param identityName The signing identity name.
-   */
-  template<typename T>
-  void
-  signByIdentity(T& packet, const Name& identityName);
-
-  /**
-   * @deprecated use sign(const uint8_t*, size_t, const SigningInfo&) instead
-   * @brief Sign the byte array using the default certificate of a particular identity.
-   *
-   * @param buffer The byte array to be signed.
-   * @param bufferLength the length of buffer.
-   * @param identityName The identity name.
-   * @return The Signature.
-   */
-  Signature
-  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
-
-  /**
-   * @deprecated use sign(Data&, SigningInfo(SigningInfo::SIGNER_TYPE_SHA256))
-   * @brief Set Sha256 weak signature for @p data
-   */
-  void
-  signWithSha256(Data& data);
-
-  /**
-   * @deprecated use sign(Interest&, SigningInfo(SigningInfo::SIGNER_TYPE_SHA256))
-   * @brief Set Sha256 weak signature for @p interest
-   */
-  void
-  signWithSha256(Interest& interest);
-
-  /**
-   * @brief Generate a self-signed certificate for a public key.
-   *
-   * @param keyName The name of the public key
-   * @return The generated certificate, shared_ptr<IdentityCertificate>() if selfSign fails
-   */
-  shared_ptr<IdentityCertificate>
-  selfSign(const Name& keyName);
-
-  /**
-   * @brief Self-sign the supplied identity certificate.
-   *
-   * @param cert The supplied cert.
-   * @throws SecTpm::Error if the private key does not exist.
-   */
-  void
-  selfSign(IdentityCertificate& cert);
-
-  /**
-   * @brief delete a certificate.
-   *
-   * @param certificateName The certificate to be deleted.
-   * @throws KeyChain::Error if certificate cannot be deleted.
-   */
-  void
-  deleteCertificate(const Name& certificateName);
-
-  /**
-   * @brief delete a key.
-   *
-   * @param keyName The key to be deleted.
-   * @throws KeyChain::Error if key cannot be deleted.
-   */
-  void
-  deleteKey(const Name& keyName);
-
-  /**
-   * @brief delete an identity.
-   *
-   * @param identity The identity to be deleted.
-   * @throws KeyChain::Error if identity cannot be deleted.
-   */
-  void
-  deleteIdentity(const Name& identity);
-
-  /**
-   * @brief export an identity.
-   *
-   * @param identity The identity to export.
-   * @param passwordStr The password to secure the private key.
-   * @return The encoded export data.
-   * @throws SecPublicInfo::Error if anything goes wrong in exporting.
-   */
-  shared_ptr<SecuredBag>
-  exportIdentity(const Name& identity, const std::string& passwordStr);
-
-  /**
-   * @brief import an identity.
-   *
-   * @param securedBag The encoded import data.
-   * @param passwordStr The password to secure the private key.
-   */
-  void
-  importIdentity(const SecuredBag& securedBag, const std::string& passwordStr);
-
-  SecPublicInfo&
-  getPib()
-  {
-    return *m_pib;
-  }
-
-  const SecPublicInfo&
-  getPib() const
-  {
-    return *m_pib;
-  }
-
-  SecTpm&
-  getTpm()
-  {
-    return *m_tpm;
-  }
-
-  const SecTpm&
-  getTpm() const
-  {
-    return *m_tpm;
-  }
-
-  /*******************************
-   *  Wrapper of SecPublicInfo   *
-   *******************************/
-  bool
-  doesIdentityExist(const Name& identityName) const
-  {
-    return m_pib->doesIdentityExist(identityName);
-  }
-
-  void
-  addIdentity(const Name& identityName)
-  {
-    return m_pib->addIdentity(identityName);
-  }
-
-  bool
-  doesPublicKeyExist(const Name& keyName) const
-  {
-    return m_pib->doesPublicKeyExist(keyName);
-  }
-
-  void
-  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
-  {
-    return m_pib->addKey(keyName, publicKeyDer);
-  }
-
-  void
-  addKey(const Name& keyName, const PublicKey& publicKeyDer)
-  {
-    return m_pib->addKey(keyName, publicKeyDer);
-  }
-
-  shared_ptr<PublicKey>
-  getPublicKey(const Name& keyName) const
-  {
-    return m_pib->getPublicKey(keyName);
-  }
-
-  bool
-  doesCertificateExist(const Name& certificateName) const
-  {
-    return m_pib->doesCertificateExist(certificateName);
-  }
-
-  void
-  addCertificate(const IdentityCertificate& certificate)
-  {
-    return m_pib->addCertificate(certificate);
-  }
-
-  shared_ptr<IdentityCertificate>
-  getCertificate(const Name& certificateName) const
-  {
-    return m_pib->getCertificate(certificateName);
-  }
-
-  Name
-  getDefaultIdentity() const
-  {
-    return m_pib->getDefaultIdentity();
-  }
-
-  Name
-  getDefaultKeyNameForIdentity(const Name& identityName) const
-  {
-    return m_pib->getDefaultKeyNameForIdentity(identityName);
-  }
-
-  /**
-   * @brief Get default key parameters for the specified identity
-   *
-   * If identity has a previously generated key, the returned parameters
-   * will include the same type of the key.  If there are no existing
-   * keys, DEFAULT_KEY_PARAMS is used.
-   */
-  const KeyParams&
-  getDefaultKeyParamsForIdentity(const Name& identityName) const;
-
-  Name
-  getDefaultCertificateNameForKey(const Name& keyName) const
-  {
-    return m_pib->getDefaultCertificateNameForKey(keyName);
-  }
-
-  void
-  getAllIdentities(std::vector<Name>& nameList, bool isDefault) const
-  {
-    return m_pib->getAllIdentities(nameList, isDefault);
-  }
-
-  void
-  getAllKeyNames(std::vector<Name>& nameList, bool isDefault) const
-  {
-    return m_pib->getAllKeyNames(nameList, isDefault);
-  }
-
-  void
-  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) const
-  {
-    return m_pib->getAllKeyNamesOfIdentity(identity, nameList, isDefault);
-  }
-
-  void
-  getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) const
-  {
-    return m_pib->getAllCertificateNames(nameList, isDefault);
-  }
-
-  void
-  getAllCertificateNamesOfKey(const Name& keyName,
-                              std::vector<Name>& nameList,
-                              bool isDefault) const
-  {
-    return m_pib->getAllCertificateNamesOfKey(keyName, nameList, isDefault);
-  }
-
-  void
-  deleteCertificateInfo(const Name& certificateName)
-  {
-    return m_pib->deleteCertificateInfo(certificateName);
-  }
-
-  void
-  deletePublicKeyInfo(const Name& keyName)
-  {
-    return m_pib->deletePublicKeyInfo(keyName);
-  }
-
-  void
-  deleteIdentityInfo(const Name& identity)
-  {
-    return m_pib->deleteIdentityInfo(identity);
-  }
-
-  void
-  setDefaultIdentity(const Name& identityName)
-  {
-    return m_pib->setDefaultIdentity(identityName);
-  }
-
-  void
-  setDefaultKeyNameForIdentity(const Name& keyName)
-  {
-    return m_pib->setDefaultKeyNameForIdentity(keyName);
-  }
-
-  void
-  setDefaultCertificateNameForKey(const Name& certificateName)
-  {
-    return m_pib->setDefaultCertificateNameForKey(certificateName);
-  }
-
-  Name
-  getNewKeyName(const Name& identityName, bool useKsk)
-  {
-    return m_pib->getNewKeyName(identityName, useKsk);
-  }
-
-  Name
-  getDefaultCertificateNameForIdentity(const Name& identityName) const
-  {
-    return m_pib->getDefaultCertificateNameForIdentity(identityName);
-  }
-
-  Name
-  getDefaultCertificateName() const
-  {
-    return m_pib->getDefaultCertificateName();
-  }
-
-  void
-  addCertificateAsKeyDefault(const IdentityCertificate& certificate)
-  {
-    return m_pib->addCertificateAsKeyDefault(certificate);
-  }
-
-  void
-  addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
-  {
-    return m_pib->addCertificateAsIdentityDefault(certificate);
-  }
-
-  void
-  addCertificateAsSystemDefault(const IdentityCertificate& certificate)
-  {
-    return m_pib->addCertificateAsSystemDefault(certificate);
-  }
-
-  shared_ptr<IdentityCertificate>
-  getDefaultCertificate() const
-  {
-    if (!static_cast<bool>(m_pib->getDefaultCertificate()))
-      const_cast<KeyChain*>(this)->setDefaultCertificateInternal();
-
-    return m_pib->getDefaultCertificate();
-  }
-
-  void
-  refreshDefaultCertificate()
-  {
-    return m_pib->refreshDefaultCertificate();
-  }
-
-  /*******************************
-   *  Wrapper of SecTpm          *
-   *******************************/
-
-  void
-  setTpmPassword(const uint8_t* password, size_t passwordLength)
-  {
-    return m_tpm->setTpmPassword(password, passwordLength);
-  }
-
-  void
-  resetTpmPassword()
-  {
-    return m_tpm->resetTpmPassword();
-  }
-
-  void
-  setInTerminal(bool inTerminal)
-  {
-    return m_tpm->setInTerminal(inTerminal);
-  }
-
-  bool
-  getInTerminal() const
-  {
-    return m_tpm->getInTerminal();
-  }
-
-  bool
-  isLocked() const
-  {
-    return m_tpm->isLocked();
-  }
-
-  bool
-  unlockTpm(const char* password, size_t passwordLength, bool usePassword)
-  {
-    return m_tpm->unlockTpm(password, passwordLength, usePassword);
-  }
-
-  void
-  generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
-  {
-    return m_tpm->generateKeyPairInTpm(keyName, params);
-  }
-
-  void
-  deleteKeyPairInTpm(const Name& keyName)
-  {
-    return m_tpm->deleteKeyPairInTpm(keyName);
-  }
-
-  shared_ptr<PublicKey>
-  getPublicKeyFromTpm(const Name& keyName) const
-  {
-    return m_tpm->getPublicKeyFromTpm(keyName);
-  }
-
-  Block
-  signInTpm(const uint8_t* data, size_t dataLength,
-            const Name& keyName,
-            DigestAlgorithm digestAlgorithm)
-  {
-    return m_tpm->signInTpm(data, dataLength, keyName, digestAlgorithm);
-  }
-
-  ConstBufferPtr
-  decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
-  {
-    return m_tpm->decryptInTpm(data, dataLength, keyName, isSymmetric);
-  }
-
-  ConstBufferPtr
-  encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
-  {
-    return m_tpm->encryptInTpm(data, dataLength, keyName, isSymmetric);
-  }
-
-  void
-  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
-  {
-    return m_tpm->generateSymmetricKeyInTpm(keyName, params);
-  }
-
-  bool
-  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) const
-  {
-    return m_tpm->doesKeyExistInTpm(keyName, keyClass);
-  }
-
-  bool
-  generateRandomBlock(uint8_t* res, size_t size) const
-  {
-    return m_tpm->generateRandomBlock(res, size);
-  }
-
-  void
-  addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
-  {
-    return m_tpm->addAppToAcl(keyName, keyClass, appPath, acl);
-  }
-
-  ConstBufferPtr
-  exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password)
-  {
-    return m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, password);
-  }
-
-  bool
-  importPrivateKeyPkcs5IntoTpm(const Name& keyName,
-                               const uint8_t* buf, size_t size,
-                               const std::string& password)
-  {
-    return m_tpm->importPrivateKeyPkcs5IntoTpm(keyName, buf, size, password);
-  }
-
-private:
-  void
-  initialize(const std::string& pibLocatorUri,
-             const std::string& tpmLocatorUri,
-             bool needReset);
-
-  /**
-   * @brief Prepare a SignatureInfo TLV according to signing information and return the signing key name
-   *
-   * @param params The signing parameters.
-   * @return The signing key name and prepared SignatureInfo.
-   * @throw Error when the requested signing method cannot be satisfied.
-   */
-  std::tuple<Name, SignatureInfo>
-  prepareSignatureInfo(const SigningInfo& params);
-
-  /**
-   * @brief Internal abstraction of packet signing.
-   *
-   * @param packet The packet to sign
-   * @param params The signing parameters.
-   * @throw Error when the signing fails.
-   */
-  template<typename T>
-  void
-  signImpl(T& packet, const SigningInfo& params);
-
-  /**
-   * @brief Set default certificate if it is not initialized
-   */
-  void
-  setDefaultCertificateInternal();
-
-  /**
-   * @brief Generate a key pair for the specified identity.
-   *
-   * @param identityName The name of the specified identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param params The parameter of the key.
-   * @return The name of the generated key.
-   */
-  Name
-  generateKeyPair(const Name& identityName, bool isKsk = false,
-                  const KeyParams& params = DEFAULT_KEY_PARAMS);
-
-  /**
-   * @brief Sign the data using a particular key.
-   *
-   * @param data Reference to the data packet.
-   * @param signature Signature to be added.
-   * @param keyName The name of the signing key.
-   * @param digestAlgorithm the digest algorithm.
-   * @throws Tpm::Error
-   */
-  void
-  signPacketWrapper(Data& data, const Signature& signature,
-                    const Name& keyName, DigestAlgorithm digestAlgorithm);
-
-  /**
-   * @brief Sign the interest using a particular key.
-   *
-   * @param interest Reference to the interest packet.
-   * @param signature Signature to be added.
-   * @param keyName The name of the signing key.
-   * @param digestAlgorithm the digest algorithm.
-   * @throws Tpm::Error
-   */
-  void
-  signPacketWrapper(Interest& interest, const Signature& signature,
-                    const Name& keyName, DigestAlgorithm digestAlgorithm);
-
-  /**
-   * @brief Generate a SignatureValue block for a buffer @p buf with size @p size using
-   *        a key with name @p keyName and digest algorithm @p digestAlgorithm.
-   */
-  Block
-  pureSign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const;
-
-  static void
-  registerPibImpl(const std::string& canonicalName,
-                  std::initializer_list<std::string> aliases, PibCreateFunc createFunc);
-
-  static void
-  registerTpmImpl(const std::string& canonicalName,
-                  std::initializer_list<std::string> aliases, TpmCreateFunc createFunc);
-
-public:
-  static tlv::SignatureTypeValue
-  getSignatureType(KeyType keyType, DigestAlgorithm digestAlgorithm);
-
-public:
-  static const Name DEFAULT_PREFIX;
-  static const SigningInfo DEFAULT_SIGNING_INFO;
-
-  // RsaKeyParams is set to be default for backward compatibility.
-  static const RsaKeyParams DEFAULT_KEY_PARAMS;
-
-  typedef std::map<std::string, Block> SignParams;
-
-private:
-  std::unique_ptr<SecPublicInfo> m_pib;
-  std::unique_ptr<SecTpm> m_tpm;
-  time::milliseconds m_lastTimestamp;
-};
-
-template<typename T>
-void
-KeyChain::signImpl(T& packet, const SigningInfo& params)
-{
-  Name keyName;
-  SignatureInfo sigInfo;
-  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
-
-  signPacketWrapper(packet, Signature(sigInfo),
-                    keyName, params.getDigestAlgorithm());
-}
-
-template<typename T>
-void
-KeyChain::sign(T& packet, const Name& certificateName)
-{
-  signImpl(packet, SigningInfo(SigningInfo::SIGNER_TYPE_CERT, certificateName));
-}
-
-template<typename T>
-void
-KeyChain::signByIdentity(T& packet, const Name& identityName)
-{
-  signImpl(packet, SigningInfo(SigningInfo::SIGNER_TYPE_ID, identityName));
-}
-
-template<class PibType>
-inline void
-KeyChain::registerPib(std::initializer_list<std::string> aliases)
-{
-  registerPibImpl(*aliases.begin(), aliases, [] (const std::string& locator) {
-      return make_unique<PibType>(locator);
-    });
-}
-
-template<class TpmType>
-inline void
-KeyChain::registerTpm(std::initializer_list<std::string> aliases)
-{
-  registerTpmImpl(*aliases.begin(), aliases, [] (const std::string& locator) {
-      return make_unique<TpmType>(locator);
-    });
-}
-
-/**
- * \brief Register SecPib class in ndn-cxx KeyChain
- *
- * This macro should be placed once in the implementation file of the
- * SecPib type within the namespace where the type is declared.
- */
-#define NDN_CXX_V1_KEYCHAIN_REGISTER_PIB(PibType, ...)     \
-static class NdnCxxAuto ## PibType ## PibRegistrationClass    \
-{                                                             \
-public:                                                       \
-  NdnCxxAuto ## PibType ## PibRegistrationClass()             \
-  {                                                           \
-    ::ndn::security::v1::KeyChain::registerPib<PibType>({__VA_ARGS__});     \
-  }                                                           \
-} ndnCxxAuto ## PibType ## PibRegistrationVariable
-
-/**
- * \brief Register SecTpm class in ndn-cxx KeyChain
- *
- * This macro should be placed once in the implementation file of the
- * SecTpm type within the namespace where the type is declared.
- */
-#define NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(TpmType, ...)     \
-static class NdnCxxAuto ## TpmType ## TpmRegistrationClass    \
-{                                                             \
-public:                                                       \
-  NdnCxxAuto ## TpmType ## TpmRegistrationClass()             \
-  {                                                           \
-    ::ndn::security::v1::KeyChain::registerTpm<TpmType>({__VA_ARGS__});     \
-  }                                                           \
-} ndnCxxAuto ## TpmType ## TpmRegistrationVariable
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_KEY_CHAIN_HPP
diff --git a/src/security/v1/public-key.cpp b/src/security/v1/public-key.cpp
deleted file mode 100644
index 9e245e9..0000000
--- a/src/security/v1/public-key.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "public-key.hpp"
-
-#include "../../encoding/oid.hpp"
-#include "../../util/sha256.hpp"
-#include "cryptopp.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-PublicKey::PublicKey()
-  : m_type(KeyType::NONE)
-{
-}
-
-PublicKey::PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize)
-  : m_type(KeyType::NONE)
-{
-  CryptoPP::StringSource src(keyDerBuf, keyDerSize, true);
-  decode(src);
-}
-
-const Block&
-PublicKey::computeDigest() const
-{
-  if (m_key.empty())
-    BOOST_THROW_EXCEPTION(Error("Public key is empty"));
-
-  if (m_digest.hasWire())
-    return m_digest;
-  else {
-    m_digest = Block(tlv::KeyDigest, util::Sha256::computeDigest(m_key.buf(), m_key.size()));
-    m_digest.encode();
-    return m_digest;
-  }
-}
-
-
-void
-PublicKey::encode(CryptoPP::BufferedTransformation& out) const
-{
-  // SubjectPublicKeyInfo ::= SEQUENCE {
-  //     algorithm           AlgorithmIdentifier
-  //     keybits             BIT STRING   }
-
-  out.Put(m_key.buf(), m_key.size());
-}
-
-void
-PublicKey::decode(CryptoPP::BufferedTransformation& in)
-{
-  // SubjectPublicKeyInfo ::= SEQUENCE {
-  //     algorithm           AlgorithmIdentifier
-  //     keybits             BIT STRING   }
-
-  using namespace CryptoPP;
-  try
-    {
-      std::string out;
-      StringSink sink(out);
-
-      ////////////////////////
-      // part 1: copy as is //
-      ////////////////////////
-      BERSequenceDecoder decoder(in);
-      {
-        assert(decoder.IsDefiniteLength());
-
-        DERSequenceEncoder encoder(sink);
-        decoder.TransferTo(encoder, decoder.RemainingLength());
-        encoder.MessageEnd();
-      }
-      decoder.MessageEnd();
-
-      ////////////////////////
-      // part 2: check if the key is RSA (since it is the only supported for now)
-      ////////////////////////
-      StringSource checkedSource(out, true);
-      BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
-      {
-        BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
-        {
-          Oid algorithm;
-          algorithm.decode(algorithmInfo);
-
-          if (algorithm == oid::RSA)
-            m_type = KeyType::RSA;
-          else if (algorithm == oid::ECDSA)
-            m_type = KeyType::EC;
-          else
-            BOOST_THROW_EXCEPTION(Error("Only RSA/EC public keys are supported for now (" +
-                                        algorithm.toString() + " requested)"));
-        }
-      }
-
-      m_key.assign(out.begin(), out.end());
-    }
-  catch (const CryptoPP::BERDecodeErr& err)
-    {
-      m_type = KeyType::NONE;
-      BOOST_THROW_EXCEPTION(Error("PublicKey decoding error"));
-    }
-
-  m_digest.reset();
-}
-
-// Blob
-// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
-// {
-//   if (digestAlgorithm == DigestAlgorithm::SHA256) {
-//     uint8_t digest[SHA256_DIGEST_LENGTH];
-//     ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
-
-//     return Blob(digest, sizeof(digest));
-//   }
-//   else
-//     throw UnrecognizedDigestAlgorithmException("Wrong format!");
-// }
-
-std::ostream&
-operator<<(std::ostream& os, const PublicKey& key)
-{
-  CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
-                         new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
-
-  return os;
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/public-key.hpp b/src/security/v1/public-key.hpp
deleted file mode 100644
index 6b67535..0000000
--- a/src/security/v1/public-key.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- */
-
-#ifndef NDN_SECURITY_V1_PUBLIC_KEY_HPP
-#define NDN_SECURITY_V1_PUBLIC_KEY_HPP
-
-#include "../../common.hpp"
-
-#include "../../encoding/buffer.hpp"
-#include "../../encoding/block.hpp"
-#include "../security-common.hpp"
-
-namespace CryptoPP {
-class BufferedTransformation;
-} // namespace CryptoPP
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class PublicKey
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * The default constructor.
-   */
-  PublicKey();
-
-  /**
-   * @brief Create a new PublicKey from @p keyDerBuf in DER buffer
-   *
-   * @param keyDerBuf The pointer to the first byte of buffer containing DER of public key
-   * @param keyDerSize Size of the buffer
-   *
-   * @throws PublicKey::Error If DER in buffer cannot be decoded
-   */
-  PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize);
-
-  const Buffer&
-  get() const
-  {
-    return m_key;
-  }
-
-  void
-  set(const uint8_t* keyDerBuf, size_t keyDerSize)
-  {
-    Buffer buf(keyDerBuf, keyDerSize);
-    m_key.swap(buf);
-  }
-
-  KeyType
-  getKeyType() const
-  {
-    return m_type;
-  }
-
-  /**
-   * @return a KeyDigest block that matches this public key
-   */
-  const Block&
-  computeDigest() const;
-
-  void
-  encode(CryptoPP::BufferedTransformation& out) const;
-
-  void
-  decode(CryptoPP::BufferedTransformation& in);
-
-  bool
-  operator==(const PublicKey& key) const
-  {
-    return m_key == key.m_key;
-  }
-
-  bool
-  operator!=(const PublicKey& key) const
-  {
-    return m_key != key.m_key;
-  }
-
-private:
-  KeyType m_type;
-  Buffer m_key;
-  mutable Block m_digest;
-};
-
-std::ostream&
-operator<<(std::ostream& os, const PublicKey& key);
-
-} // namespace v1
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-/// @deprecated When needed, use explicit namespace
-using security::v1::PublicKey;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_PUBLIC_KEY_HPP
diff --git a/src/security/v1/sec-public-info-sqlite3.cpp b/src/security/v1/sec-public-info-sqlite3.cpp
deleted file mode 100644
index efb4e0f..0000000
--- a/src/security/v1/sec-public-info-sqlite3.cpp
+++ /dev/null
@@ -1,958 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- */
-
-#include "sec-public-info-sqlite3.hpp"
-#include "identity-certificate.hpp"
-#include "../signature-sha256-with-rsa.hpp"
-#include "../signature-sha256-with-ecdsa.hpp"
-#include "../../data.hpp"
-
-#include <sqlite3.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sstream>
-#include <fstream>
-#include <boost/filesystem.hpp>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-using std::string;
-using std::vector;
-
-const std::string SecPublicInfoSqlite3::SCHEME("pib-sqlite3");
-
-static const string INIT_TPM_INFO_TABLE =
-  "CREATE TABLE IF NOT EXISTS                "
-  "  TpmInfo(                                "
-  "      tpm_locator           BLOB NOT NULL,"
-  "      PRIMARY KEY (tpm_locator)           "
-  "  );                                      ";
-
-static const string INIT_ID_TABLE =
-  "CREATE TABLE IF NOT EXISTS                             "
-  "  Identity(                                            "
-  "      identity_name     BLOB NOT NULL,                 "
-  "      default_identity  INTEGER DEFAULT 0,             "
-  "      PRIMARY KEY (identity_name)                      "
-  "  );                                                   "
-  "CREATE INDEX identity_index ON Identity(identity_name);";
-
-static const string INIT_KEY_TABLE =
-  "CREATE TABLE IF NOT EXISTS                       "
-  "  Key(                                           "
-  "      identity_name     BLOB NOT NULL,           "
-  "      key_identifier    BLOB NOT NULL,           "
-  "      key_type          INTEGER,                 "
-  "      public_key        BLOB,                    "
-  "      default_key       INTEGER DEFAULT 0,       "
-  "      active            INTEGER DEFAULT 0,       "
-  "      PRIMARY KEY (identity_name, key_identifier)"
-  "  );                                             "
-  "CREATE INDEX key_index ON Key(identity_name);    ";
-
-
-static const string INIT_CERT_TABLE =
-  "CREATE TABLE IF NOT EXISTS                         "
-  "  Certificate(                                     "
-  "      cert_name         BLOB NOT NULL,             "
-  "      cert_issuer       BLOB NOT NULL,             "
-  "      identity_name     BLOB NOT NULL,             "
-  "      key_identifier    BLOB NOT NULL,             "
-  "      not_before        TIMESTAMP,                 "
-  "      not_after         TIMESTAMP,                 "
-  "      certificate_data  BLOB NOT NULL,             "
-  "      valid_flag        INTEGER DEFAULT 1,         "
-  "      default_cert      INTEGER DEFAULT 0,         "
-  "      PRIMARY KEY (cert_name)                      "
-  "  );                                               "
-  "CREATE INDEX cert_index ON Certificate(cert_name); "
-  "CREATE INDEX subject ON Certificate(identity_name);";
-
-/**
- * A utility function to call the normal sqlite3_bind_text where the value and length are
- * value.c_str() and value.size().
- */
-static int
-sqlite3_bind_string(sqlite3_stmt* statement,
-                    int index,
-                    const string& value,
-                    void(*destructor)(void*))
-{
-  return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
-}
-
-static string
-sqlite3_column_string(sqlite3_stmt* statement, int column)
-{
-  return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
-                sqlite3_column_bytes(statement, column));
-}
-
-SecPublicInfoSqlite3::SecPublicInfoSqlite3(const std::string& dir)
-  : SecPublicInfo(dir)
-  , m_database(nullptr)
-{
-  boost::filesystem::path identityDir;
-  if (dir == "") {
-#ifdef NDN_CXX_HAVE_TESTS
-    if (getenv("TEST_HOME") != nullptr) {
-      identityDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
-    }
-    else
-#endif // NDN_CXX_HAVE_TESTS
-    if (getenv("HOME") != nullptr) {
-      identityDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
-    }
-    else {
-      identityDir = boost::filesystem::path(".") / ".ndn";
-    }
-  }
-  else {
-    identityDir = boost::filesystem::path(dir);
-  }
-  boost::filesystem::create_directories(identityDir);
-
-  /// @todo Add define for windows/unix in wscript. The following may completely fail on windows
-  int res = sqlite3_open_v2((identityDir / "ndnsec-public-info.db").c_str(), &m_database,
-                            SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
-#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
-                                                       "unix-dotfile"
-#else
-                            0
-#endif
-                            );
-  if (res != SQLITE_OK)
-    BOOST_THROW_EXCEPTION(Error("identity DB cannot be opened/created"));
-
-
-  BOOST_ASSERT(m_database != nullptr);
-
-  initializeTable("TpmInfo", INIT_TPM_INFO_TABLE); // Check if TpmInfo table exists;
-  initializeTable("Identity", INIT_ID_TABLE);      // Check if Identity table exists;
-  initializeTable("Key", INIT_KEY_TABLE);          // Check if Key table exists;
-  initializeTable("Certificate", INIT_CERT_TABLE); // Check if Certificate table exists;
-}
-
-SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
-{
-  sqlite3_close(m_database);
-  m_database = nullptr;
-}
-
-bool
-SecPublicInfoSqlite3::doesTableExist(const string& tableName)
-{
-  // Check if the table exists;
-  bool doesTableExist = false;
-  string checkingString =
-    "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "'";
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database, checkingString.c_str(), -1, &statement, 0);
-
-  int result = sqlite3_step(statement);
-  if (result == SQLITE_ROW)
-    doesTableExist = true;
-  sqlite3_finalize(statement);
-
-  return doesTableExist;
-}
-
-bool
-SecPublicInfoSqlite3::initializeTable(const string& tableName, const string& initCommand)
-{
-  // Create the table if it does not exist
-  if (!doesTableExist(tableName)) {
-    char* errorMessage = 0;
-    int result = sqlite3_exec(m_database, initCommand.c_str(), NULL, NULL, &errorMessage);
-
-    if (result != SQLITE_OK && errorMessage != 0) {
-      sqlite3_free(errorMessage);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void
-SecPublicInfoSqlite3::deleteTable(const string& tableName)
-{
-  string query = "DROP TABLE IF EXISTS " + tableName;
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database, query.c_str(), -1, &statement, 0);
-
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-void
-SecPublicInfoSqlite3::setTpmLocator(const string& tpmLocator)
-{
-  string currentTpm;
-  try {
-    currentTpm = getTpmLocator();
-  }
-  catch (SecPublicInfo::Error&) {
-    setTpmLocatorInternal(tpmLocator, false); // set tpmInfo without resetting
-    return;
-  }
-
-  if (currentTpm == tpmLocator)
-    return; // if the same, nothing will be changed
-
-  setTpmLocatorInternal(tpmLocator, true); // set tpmInfo and reset pib
-}
-
-string
-SecPublicInfoSqlite3::getTpmLocator()
-{
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM TpmInfo", -1, &statement, 0);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    string tpmLocator = sqlite3_column_string(statement, 0);
-    sqlite3_finalize(statement);
-    return tpmLocator;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(SecPublicInfo::Error("TPM info does not exist"));
-  }
-}
-
-void
-SecPublicInfoSqlite3::setTpmLocatorInternal(const string& tpmLocator, bool needReset)
-{
-  sqlite3_stmt* statement = nullptr;
-
-  if (needReset) {
-    deleteTable("Identity");
-    deleteTable("Key");
-    deleteTable("Certificate");
-
-    initializeTable("Identity", INIT_ID_TABLE);
-    initializeTable("Key", INIT_KEY_TABLE);
-    initializeTable("Certificate", INIT_CERT_TABLE);
-
-    sqlite3_prepare_v2(m_database, "UPDATE TpmInfo SET tpm_locator = ?",
-                       -1, &statement, 0);
-    sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
-  }
-  else {
-    // no reset implies there is no tpmLocator record, insert one
-    sqlite3_prepare_v2(m_database, "INSERT INTO TpmInfo (tpm_locator) VALUES (?)",
-                       -1, &statement, 0);
-    sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
-  }
-
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-std::string
-SecPublicInfoSqlite3::getPibLocator()
-{
-  return string("pib-sqlite3:").append(m_location);
-}
-
-bool
-SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
-{
-  bool result = false;
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT count(*) FROM Identity WHERE identity_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    int countAll = sqlite3_column_int(statement, 0);
-    if (countAll > 0)
-      result = true;
-  }
-
-  sqlite3_finalize(statement);
-
-  return result;
-}
-
-void
-SecPublicInfoSqlite3::addIdentity(const Name& identityName)
-{
-  if (doesIdentityExist(identityName))
-    return;
-
-  sqlite3_stmt* statement = nullptr;
-
-  sqlite3_prepare_v2(m_database,
-                     "INSERT OR REPLACE INTO Identity (identity_name) values (?)",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-bool
-SecPublicInfoSqlite3::revokeIdentity()
-{
-  //TODO:
-  return false;
-}
-
-bool
-SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
-{
-  if (keyName.empty())
-    BOOST_THROW_EXCEPTION(Error("Incorrect key name " + keyName.toUri()));
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  bool keyIdExist = false;
-  if (res == SQLITE_ROW) {
-    int countAll = sqlite3_column_int(statement, 0);
-    if (countAll > 0)
-      keyIdExist = true;
-  }
-
-  sqlite3_finalize(statement);
-
-  return keyIdExist;
-}
-
-void
-SecPublicInfoSqlite3::addKey(const Name& keyName,
-                             const PublicKey& publicKeyDer)
-{
-  if (keyName.empty())
-    return;
-
-  if (doesPublicKeyExist(keyName))
-    return;
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  addIdentity(identityName);
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT OR REPLACE INTO Key \
-                      (identity_name, key_identifier, key_type, public_key) \
-                      values (?, ?, ?, ?)",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-  sqlite3_bind_int(statement, 3, static_cast<int>(publicKeyDer.getKeyType()));
-  sqlite3_bind_blob(statement, 4,
-                    publicKeyDer.get().buf(),
-                    publicKeyDer.get().size(),
-                    SQLITE_STATIC);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-shared_ptr<PublicKey>
-SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
-{
-  if (keyName.empty())
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getPublicKey  Empty keyName"));
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  shared_ptr<PublicKey> result;
-  if (res == SQLITE_ROW) {
-    result = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
-                                        sqlite3_column_bytes(statement, 0));
-    sqlite3_finalize(statement);
-    return result;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getPublicKey  public key does not exist"));
-  }
-}
-
-KeyType
-SecPublicInfoSqlite3::getPublicKeyType(const Name& keyName)
-{
-  if (keyName.empty())
-    return KeyType::NONE;
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT key_type FROM Key WHERE identity_name=? AND key_identifier=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    int typeValue = sqlite3_column_int(statement, 0);
-    sqlite3_finalize(statement);
-    return static_cast<KeyType>(typeValue);
-  }
-  else {
-    sqlite3_finalize(statement);
-    return KeyType::NONE;
-  }
-}
-
-bool
-SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
-{
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT count(*) FROM Certificate WHERE cert_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  bool certExist = false;
-  if (res == SQLITE_ROW) {
-    int countAll = sqlite3_column_int(statement, 0);
-    if (countAll > 0)
-      certExist = true;
-  }
-
-  sqlite3_finalize(statement);
-
-  return certExist;
-}
-
-void
-SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
-{
-  const Name& certificateName = certificate.getName();
-  // KeyName is from IdentityCertificate name, so should be qualified.
-  Name keyName =
-    IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
-
-  addKey(keyName, certificate.getPublicKeyInfo());
-
-  if (doesCertificateExist(certificateName))
-    return;
-
-  string keyId = keyName.get(-1).toUri();
-  Name identity = keyName.getPrefix(-1);
-
-  // Insert the certificate
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT OR REPLACE INTO Certificate \
-                      (cert_name, cert_issuer, identity_name, key_identifier, \
-                       not_before, not_after, certificate_data) \
-                      values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
-                      -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
-
-  try {
-    // this will throw an exception if the signature is not the standard one
-    // or there is no key locator present
-    std::string signerName = certificate.getSignature().getKeyLocator().getName().toUri();
-    sqlite3_bind_string(statement, 2, signerName, SQLITE_TRANSIENT);
-  }
-  catch (tlv::Error&) {
-    return;
-  }
-
-  sqlite3_bind_string(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 4, keyId, SQLITE_STATIC);
-
-  sqlite3_bind_int64(statement, 5,
-    static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotBefore()).count()));
-  sqlite3_bind_int64(statement, 6,
-    static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotAfter()).count()));
-
-  sqlite3_bind_blob(statement, 7,
-                    certificate.wireEncode().wire(),
-                    certificate.wireEncode().size(),
-                    SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-shared_ptr<IdentityCertificate>
-SecPublicInfoSqlite3::getCertificate(const Name& certificateName)
-{
-  sqlite3_stmt* statement = nullptr;
-
-  sqlite3_prepare_v2(m_database,
-                     "SELECT certificate_data FROM Certificate WHERE cert_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
-    try {
-      certificate->wireDecode(Block(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
-                                    sqlite3_column_bytes(statement, 0)));
-    }
-    catch (tlv::Error&) {
-      sqlite3_finalize(statement);
-      BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getCertificate  certificate cannot be "
-                                  "decoded"));
-    }
-
-    sqlite3_finalize(statement);
-    return certificate;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getCertificate  certificate does not "
-                                "exist"));
-  }
-}
-
-
-Name
-SecPublicInfoSqlite3::getDefaultIdentity()
-{
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT identity_name FROM Identity WHERE default_identity=1",
-                     -1, &statement, 0);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    Name identity(sqlite3_column_string(statement, 0));
-    sqlite3_finalize(statement);
-    return identity;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultIdentity  no default identity"));
-  }
-}
-
-void
-SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
-{
-  addIdentity(identityName);
-
-  sqlite3_stmt* statement = nullptr;
-
-  //Reset previous default identity
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Identity SET default_identity=0 WHERE default_identity=1",
-                     -1, &statement, 0);
-
-  while (sqlite3_step(statement) == SQLITE_ROW)
-    ;
-
-  sqlite3_finalize(statement);
-
-  //Set current default identity
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Identity SET default_identity=1 WHERE identity_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-Name
-SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
-{
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    Name keyName = identityName;
-    keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)),
-                          sqlite3_column_bytes(statement, 0)));
-    sqlite3_finalize(statement);
-    return keyName;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultKeyNameForIdentity key not "
-                                "found"));
-  }
-}
-
-void
-SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
-{
-  if (!doesPublicKeyExist(keyName))
-    BOOST_THROW_EXCEPTION(Error("Key does not exist:" + keyName.toUri()));
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-
-  //Reset previous default Key
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-
-  while (sqlite3_step(statement) == SQLITE_ROW)
-    ;
-
-  sqlite3_finalize(statement);
-
-  //Set current default Key
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-Name
-SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
-{
-  if (keyName.empty())
-    BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey wrong key"));
-
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT cert_name FROM Certificate \
-                      WHERE identity_name=? AND key_identifier=? AND default_cert=1",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  int res = sqlite3_step(statement);
-
-  if (res == SQLITE_ROW) {
-    Name certName(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)),
-                         sqlite3_column_bytes(statement, 0)));
-    sqlite3_finalize(statement);
-    return certName;
-  }
-  else {
-    sqlite3_finalize(statement);
-    BOOST_THROW_EXCEPTION(Error("certificate not found"));
-  }
-}
-
-void
-SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
-{
-  if (!doesCertificateExist(certificateName))
-    BOOST_THROW_EXCEPTION(Error("certificate does not exist:" + certificateName.toUri()));
-
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  string keyId = keyName.get(-1).toUri();
-  Name identityName = keyName.getPrefix(-1);
-
-  sqlite3_stmt* statement = nullptr;
-
-  //Reset previous default Key
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Certificate SET default_cert=0 \
-                      WHERE default_cert=1 AND identity_name=? AND key_identifier=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-
-  while (sqlite3_step(statement) == SQLITE_ROW)
-    ;
-
-  sqlite3_finalize(statement);
-
-  //Set current default Key
-  sqlite3_prepare_v2(m_database,
-                     "UPDATE Certificate SET default_cert=1 \
-                      WHERE identity_name=? AND key_identifier=? AND cert_name=?",
-                     -1, &statement, 0);
-
-  sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
-  sqlite3_bind_string(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
-}
-
-void
-SecPublicInfoSqlite3::getAllIdentities(vector<Name>& nameList, bool isDefault)
-{
-  sqlite3_stmt* stmt;
-  if (isDefault)
-    sqlite3_prepare_v2(m_database,
-                       "SELECT identity_name FROM Identity WHERE default_identity=1",
-                       -1, &stmt, 0);
-  else
-    sqlite3_prepare_v2(m_database,
-                       "SELECT identity_name FROM Identity WHERE default_identity=0",
-                       -1, &stmt, 0);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW)
-    nameList.push_back(Name(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
-                                   sqlite3_column_bytes(stmt, 0))));
-
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::getAllKeyNames(vector<Name>& nameList, bool isDefault)
-{
-  sqlite3_stmt* stmt;
-
-  if (isDefault)
-    sqlite3_prepare_v2(m_database,
-                       "SELECT identity_name, key_identifier FROM Key WHERE default_key=1",
-                       -1, &stmt, 0);
-  else
-    sqlite3_prepare_v2(m_database,
-                       "SELECT identity_name, key_identifier FROM Key WHERE default_key=0",
-                       -1, &stmt, 0);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW) {
-    Name keyName(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
-                        sqlite3_column_bytes(stmt, 0)));
-    keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)),
-                          sqlite3_column_bytes(stmt, 1)));
-    nameList.push_back(keyName);
-  }
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity,
-                                               vector<Name>& nameList,
-                                               bool isDefault)
-{
-  sqlite3_stmt* stmt;
-
-  if (isDefault)
-    sqlite3_prepare_v2(m_database,
-                       "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?",
-                       -1, &stmt, 0);
-  else
-    sqlite3_prepare_v2(m_database,
-                       "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?",
-                       -1, &stmt, 0);
-
-  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW) {
-    Name keyName(identity);
-    keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
-                          sqlite3_column_bytes(stmt, 0)));
-    nameList.push_back(keyName);
-  }
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::getAllCertificateNames(vector<Name>& nameList, bool isDefault)
-{
-  sqlite3_stmt* stmt;
-
-  if (isDefault)
-    sqlite3_prepare_v2(m_database,
-                       "SELECT cert_name FROM Certificate WHERE default_cert=1",
-                       -1, &stmt, 0);
-  else
-    sqlite3_prepare_v2(m_database,
-                       "SELECT cert_name FROM Certificate WHERE default_cert=0",
-                       -1, &stmt, 0);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW)
-    nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
-                              sqlite3_column_bytes(stmt, 0)));
-
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName,
-                                                  vector<Name>& nameList,
-                                                  bool isDefault)
-{
-  if (keyName.empty())
-    return;
-
-  sqlite3_stmt* stmt;
-  if (isDefault)
-    sqlite3_prepare_v2(m_database,
-                       "SELECT cert_name FROM Certificate \
-                        WHERE default_cert=1 and identity_name=? and key_identifier=?",
-                       -1, &stmt, 0);
-  else
-    sqlite3_prepare_v2(m_database,
-                       "SELECT cert_name FROM Certificate \
-                        WHERE default_cert=0 and identity_name=? and key_identifier=?",
-                       -1, &stmt, 0);
-
-  Name identity = keyName.getPrefix(-1);
-  sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
-
-  std::string baseKeyName = keyName.get(-1).toUri();
-  sqlite3_bind_string(stmt, 2, baseKeyName, SQLITE_TRANSIENT);
-
-  while (sqlite3_step(stmt) == SQLITE_ROW)
-    nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
-                              sqlite3_column_bytes(stmt, 0)));
-
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::deleteCertificateInfo(const Name& certName)
-{
-  if (certName.empty())
-    return;
-
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE cert_name=?", -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, certName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::deletePublicKeyInfo(const Name& keyName)
-{
-  if (keyName.empty())
-    return;
-
-  string identity = keyName.getPrefix(-1).toUri();
-  string keyId = keyName.get(-1).toUri();
-
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database,
-                     "DELETE FROM Certificate WHERE identity_name=? and key_identifier=?",
-                     -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
-  sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-
-  sqlite3_prepare_v2(m_database,
-                     "DELETE FROM Key WHERE identity_name=? and key_identifier=?",
-                     -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
-  sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-}
-
-void
-SecPublicInfoSqlite3::deleteIdentityInfo(const Name& identityName)
-{
-  string identity = identityName.toUri();
-
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=?", -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-
-  sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=?", -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-
-  sqlite3_prepare_v2(m_database, "DELETE FROM Identity WHERE identity_name=?", -1, &stmt, 0);
-  sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-}
-
-std::string
-SecPublicInfoSqlite3::getScheme()
-{
-  return SCHEME;
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/sec-public-info-sqlite3.hpp b/src/security/v1/sec-public-info-sqlite3.hpp
deleted file mode 100644
index 6e9dfd7..0000000
--- a/src/security/v1/sec-public-info-sqlite3.hpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Jeff Thompson <jefft0@remap.ucla.edu>
- */
-
-#ifndef NDN_SECURITY_V1_SEC_PUBLIC_INFO_SQLITE3_HPP
-#define NDN_SECURITY_V1_SEC_PUBLIC_INFO_SQLITE3_HPP
-
-#include "../../common.hpp"
-#include "sec-public-info.hpp"
-
-struct sqlite3;
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class SecPublicInfoSqlite3 : public SecPublicInfo
-{
-public:
-  class Error : public SecPublicInfo::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : SecPublicInfo::Error(what)
-    {
-    }
-  };
-
-  explicit
-  SecPublicInfoSqlite3(const std::string& dir = "");
-
-  virtual
-  ~SecPublicInfoSqlite3();
-
-  /**********************
-   * from SecPublicInfo *
-   **********************/
-
-  virtual void
-  setTpmLocator(const std::string& tpmLocator);
-
-  virtual std::string
-  getTpmLocator();
-
-  virtual std::string
-  getPibLocator();
-
-  virtual bool
-  doesIdentityExist(const Name& identityName);
-
-  virtual void
-  addIdentity(const Name& identityName);
-
-  virtual bool
-  revokeIdentity();
-
-  virtual bool
-  doesPublicKeyExist(const Name& keyName);
-
-  virtual void
-  addKey(const Name& keyName, const PublicKey& publicKeyDer);
-
-  virtual shared_ptr<PublicKey>
-  getPublicKey(const Name& keyName);
-
-  virtual KeyType
-  getPublicKeyType(const Name& keyName);
-
-  virtual bool
-  doesCertificateExist(const Name& certificateName);
-
-  virtual void
-  addCertificate(const IdentityCertificate& certificate);
-
-  virtual shared_ptr<IdentityCertificate>
-  getCertificate(const Name& certificateName);
-
-
-
-  virtual Name
-  getDefaultIdentity();
-
-  virtual Name
-  getDefaultKeyNameForIdentity(const Name& identityName);
-
-  virtual Name
-  getDefaultCertificateNameForKey(const Name& keyName);
-
-  virtual void
-  getAllIdentities(std::vector<Name>& nameList, bool isDefault);
-
-  virtual void
-  getAllKeyNames(std::vector<Name>& nameList, bool isDefault);
-
-  virtual void
-  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault);
-
-  virtual void
-  getAllCertificateNames(std::vector<Name>& nameList, bool isDefault);
-
-  virtual void
-  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name>& nameList, bool isDefault);
-
-  virtual void
-  deleteCertificateInfo(const Name& certificateName);
-
-  virtual void
-  deletePublicKeyInfo(const Name& keyName);
-
-  virtual void
-  deleteIdentityInfo(const Name& identity);
-
-private:
-  bool
-  initializeTable(const std::string& tableName, const std::string& initCommand);
-
-  void
-  deleteTable(const std::string& tableName);
-
-  void
-  setTpmLocatorInternal(const std::string& tpmLocator, bool needReset);
-
-  void
-  setDefaultIdentityInternal(const Name& identityName);
-
-  void
-  setDefaultKeyNameForIdentityInternal(const Name& keyName);
-
-  void
-  setDefaultCertificateNameForKeyInternal(const Name& certificateName);
-
-  std::string
-  getScheme();
-
-NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  bool
-  doesTableExist(const std::string& tableName);
-
-public:
-  static const std::string SCHEME;
-
-private:
-  sqlite3* m_database;
-};
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SEC_PUBLIC_INFO_SQLITE3_HPP
diff --git a/src/security/v1/sec-public-info.cpp b/src/security/v1/sec-public-info.cpp
deleted file mode 100644
index 96c4441..0000000
--- a/src/security/v1/sec-public-info.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-#include "sec-public-info.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-SecPublicInfo::SecPublicInfo(const std::string& location)
-  : m_location(location)
-{
-}
-
-SecPublicInfo::~SecPublicInfo()
-{
-}
-
-std::string
-SecPublicInfo::getPibLocator()
-{
-  return this->getScheme() + ":" + m_location;
-}
-
-void
-SecPublicInfo::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKey)
-{
-  addKey(keyName, publicKey);
-}
-
-void
-SecPublicInfo::setDefaultIdentity(const Name& identityName)
-{
-  setDefaultIdentityInternal(identityName);
-  refreshDefaultCertificate();
-}
-
-void
-SecPublicInfo::setDefaultKeyNameForIdentity(const Name& keyName)
-{
-  setDefaultKeyNameForIdentityInternal(keyName);
-  refreshDefaultCertificate();
-}
-
-void
-SecPublicInfo::setDefaultCertificateNameForKey(const Name& certificateName)
-{
-  setDefaultCertificateNameForKeyInternal(certificateName);
-  refreshDefaultCertificate();
-}
-
-Name
-SecPublicInfo::getDefaultCertificateNameForIdentity(const Name& identityName)
-{
-  return getDefaultCertificateNameForKey(getDefaultKeyNameForIdentity(identityName));
-}
-
-Name
-SecPublicInfo::getDefaultCertificateName()
-{
-  if (m_defaultCertificate == nullptr)
-    refreshDefaultCertificate();
-
-  if (m_defaultCertificate == nullptr)
-    BOOST_THROW_EXCEPTION(Error("No default certificate is set"));
-
-  return m_defaultCertificate->getName();
-}
-
-Name
-SecPublicInfo::getNewKeyName(const Name& identityName, bool useKsk)
-{
-  std::ostringstream oss;
-
-  if (useKsk)
-    oss << "ksk-";
-  else
-    oss << "dsk-";
-
-  oss << time::toUnixTimestamp(time::system_clock::now()).count();
-
-  Name keyName = Name(identityName).append(oss.str());
-
-  if (doesPublicKeyExist(keyName))
-    BOOST_THROW_EXCEPTION(Error("Key name already exists: " + keyName.toUri()));
-
-  return keyName;
-}
-
-void
-SecPublicInfo::addCertificateAsKeyDefault(const IdentityCertificate& certificate)
-{
-  addCertificate(certificate);
-  setDefaultCertificateNameForKeyInternal(certificate.getName());
-  refreshDefaultCertificate();
-}
-
-void
-SecPublicInfo::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
-{
-  addCertificate(certificate);
-  Name certName = certificate.getName();
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName);
-  setDefaultKeyNameForIdentityInternal(keyName);
-  setDefaultCertificateNameForKeyInternal(certName);
-  refreshDefaultCertificate();
-}
-
-void
-SecPublicInfo::addCertificateAsSystemDefault(const IdentityCertificate& certificate)
-{
-  addCertificate(certificate);
-  Name certName = certificate.getName();
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certName);
-  setDefaultIdentityInternal(keyName.getPrefix(-1));
-  setDefaultKeyNameForIdentityInternal(keyName);
-  setDefaultCertificateNameForKeyInternal(certName);
-  refreshDefaultCertificate();
-}
-
-shared_ptr<IdentityCertificate>
-SecPublicInfo::defaultCertificate()
-{
-  return getDefaultCertificate();
-}
-
-shared_ptr<IdentityCertificate>
-SecPublicInfo::getDefaultCertificate()
-{
-  return m_defaultCertificate;
-}
-
-void
-SecPublicInfo::refreshDefaultCertificate()
-{
-  try {
-    Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
-    m_defaultCertificate = getCertificate(certName);
-  }
-  catch (SecPublicInfo::Error&) {
-    m_defaultCertificate.reset();
-  }
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/sec-public-info.hpp b/src/security/v1/sec-public-info.hpp
deleted file mode 100644
index 7ed6ef4..0000000
--- a/src/security/v1/sec-public-info.hpp
+++ /dev/null
@@ -1,473 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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_SECURITY_V1_SEC_PUBLIC_INFO_HPP
-#define NDN_SECURITY_V1_SEC_PUBLIC_INFO_HPP
-
-#include "../../name.hpp"
-#include "../security-common.hpp"
-#include "public-key.hpp"
-#include "identity-certificate.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-/**
- * @brief SecPublicInfo is a base class for the storage of public information.
- *
- * It specify interfaces related to public information, such as identity, public keys and
- * certificates.
- */
-class SecPublicInfo : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  explicit
-  SecPublicInfo(const std::string& location);
-
-  /**
-   * @brief The virtual Destructor
-   */
-  virtual
-  ~SecPublicInfo();
-
-  /**
-   * @brief Set the corresponding TPM information to @p tpmLocator
-   *
-   * If the provided @p tpmLocator is different from the existing one, the PIB will be reset,
-   * otherwise nothing will be changed.
-   *
-   * For legacy issue, the TPM info may not exist (some old PIB content may not have this info),
-   * this method will simply set the TPM info as provided without changing anything else. Thus an
-   * ideal process of handling old PIB is to check if TPM info exists. If it does not exist,
-   * then set it to the default value according to configuration.
-   */
-  virtual void
-  setTpmLocator(const std::string& tpmLocator) = 0;
-
-  /**
-   * @brief Get TPM Locator
-   *
-   * @throws SecPublicInfo::Error if the TPM info does not exist
-   */
-  virtual std::string
-  getTpmLocator() = 0;
-
-  /**
-   * @brief Get PIB Locator
-   */
-  std::string
-  getPibLocator();
-
-  /**
-   * @brief Check if the specified identity already exists
-   *
-   * @param identityName The identity name
-   * @return true if the identity exists, otherwise false
-   */
-  virtual bool
-  doesIdentityExist(const Name& identityName) = 0;
-
-  /**
-   * @brief Add a new identity
-   *
-   * if identity already exist, do not add it again
-   *
-   * @param identityName The identity name to be added
-   */
-  virtual void
-  addIdentity(const Name& identityName) = 0;
-
-  /**
-   * @brief Revoke the identity
-   *
-   * @return true if the identity was revoked, otherwise false
-   */
-  virtual bool
-  revokeIdentity() = 0;
-
-  /**
-   * @brief Check if the specified key already exists
-   *
-   * @param keyName The name of the key
-   * @return true if the key exists, otherwise false
-   */
-  virtual bool
-  doesPublicKeyExist(const Name& keyName) = 0;
-
-  /**
-   * @brief Add a public key to the identity storage.
-   *
-   * @param keyName The name of the public key to be added
-   * @param keyType Type of the public key to be added
-   * @param publicKey Reference to the PublicKey object
-   * @deprecated Use addKey instead
-   */
-  DEPRECATED(
-  void
-  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKey));
-
-  /**
-   * @brief Add a public key to the identity storage.
-   *
-   * @param keyName The name of the public key to be added
-   * @param publicKey Reference to the PublicKey object
-   */
-  virtual void
-  addKey(const Name& keyName, const PublicKey& publicKey) = 0;
-
-  /**
-   * @brief Get shared pointer to PublicKey object from the identity storage
-   *
-   * @param keyName The name of the requested public key
-   * @throws SecPublicInfo::Error if public key does not exist
-   */
-  virtual shared_ptr<PublicKey>
-  getPublicKey(const Name& keyName) = 0;
-
-  /**
-   * @brief Get the type of the queried public key
-   *
-   * @note KeyType is also available from PublicKey instance.
-   *       This method is more efficient if only KeyType is needed.
-   *
-   * @param keyName The name of the requested public key
-   * @return the type of the key. If the queried key does not exist, KeyType::NONE will be returned
-   */
-  virtual KeyType
-  getPublicKeyType(const Name& keyName) = 0;
-
-  /**
-   * @brief Check if the specified certificate already exists
-   *
-   * @param certificateName The name of the certificate
-   */
-  virtual bool
-  doesCertificateExist(const Name& certificateName) = 0;
-
-  /**
-   * @brief Add a certificate to the identity storage.
-   *
-   * It will add the corresponding public key and identity if they do not exist
-   *
-   * @param certificate The certificate to be added
-   */
-  virtual void
-  addCertificate(const IdentityCertificate& certificate) = 0;
-
-  /**
-   * @brief Get a shared pointer to identity certificate object from the identity storage
-   *
-   * @param certificateName The name of the requested certificate
-   * @throws SecPublicInfo::Error if the certificate does not exist
-   */
-  virtual shared_ptr<IdentityCertificate>
-  getCertificate(const Name& certificateName) = 0;
-
-
-  /*****************************************
-   *            Default Getter             *
-   *****************************************/
-
-  /**
-   * @brief Get name of the default identity
-   *
-   * @throws SecPublicInfo::Error if there is no default.
-   */
-  virtual Name
-  getDefaultIdentity() = 0;
-
-  /**
-   * @brief Get name of the default key name for the specified identity
-   *
-   * @param identityName The identity name
-   * @throws SecPublicInfo::Error if there is no default
-   */
-  virtual Name
-  getDefaultKeyNameForIdentity(const Name& identityName) = 0;
-
-  /**
-   * @brief Get name of the default certificate name for the specified key
-   *
-   * @param keyName The key name.
-   * @throws SecPublicInfo::Error if there is no default.
-   */
-  virtual Name
-  getDefaultCertificateNameForKey(const Name& keyName) = 0;
-
-  /**
-   * @brief Get all the identities from public info
-   *
-   * @param [out] nameList On return, the identity list
-   * @param isDefault      If specified, only the default identity is returned
-   */
-  virtual void
-  getAllIdentities(std::vector<Name>& nameList, bool isDefault) = 0;
-
-  /**
-   * @brief Get all the key names from public info
-   *
-   * @param [out] nameList On return, the key name list.
-   * @param isDefault      If specified, only the default keys are returned
-   */
-  virtual void
-  getAllKeyNames(std::vector<Name>& nameList, bool isDefault) = 0;
-
-  /**
-   * @brief Get all the key names of a particular identity
-   *
-   * @param identity       The specified identity name
-   * @param [out] nameList On return, the key name list
-   * @param isDefault      If specified, only the default key is returned
-   */
-  virtual void
-  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault) = 0;
-
-  /**
-   * @brief Get all the certificate name in public info
-   *
-   * @param [out] nameList On return, the certificate name list
-   * @param isDefault      If specified, only the default certificates are returned
-   */
-  virtual void
-  getAllCertificateNames(std::vector<Name>& nameList, bool isDefault) = 0;
-
-  /**
-   * @brief Get all the certificate name of a particular key name
-   *
-   * @param keyName        The specified key name
-   * @param [out] nameList On return, the certificate name list
-   * @param isDefault      If specified, only the default certificate is returned
-   */
-  virtual void
-  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name>& nameList, bool isDefault) = 0;
-
-  /*****************************************
-   *            Delete Methods             *
-   *****************************************/
-
-  /**
-   * @brief Delete a certificate
-   *
-   * @param certificateName The certificate name
-   */
-  virtual void
-  deleteCertificateInfo(const Name& certificateName) = 0;
-
-  /**
-   * @brief Delete a public key and related certificates
-   *
-   * @param keyName The key name
-   */
-  virtual void
-  deletePublicKeyInfo(const Name& keyName) = 0;
-
-  /**
-   * @brief Delete an identity and related public keys and certificates
-   *
-   * @param identity The identity name
-   */
-  virtual void
-  deleteIdentityInfo(const Name& identity) = 0;
-
-protected:
-
-  /*****************************************
-   *            Default Setter             *
-   *****************************************/
-
-  /**
-   * @brief Set the default identity
-   *
-   * @param identityName The default identity name
-   */
-  virtual void
-  setDefaultIdentityInternal(const Name& identityName) = 0;
-
-  /**
-   * @brief Set the default key name for the corresponding identity
-   *
-   * @param keyName The key name
-   * @throws SecPublicInfo::Error if the key does not exist
-   */
-  virtual void
-  setDefaultKeyNameForIdentityInternal(const Name& keyName) = 0;
-
-  /**
-   * @brief Set the default certificate name for the corresponding key
-   *
-   * @param certificateName The certificate name
-   * @throws SecPublicInfo::Error if the certificate does not exist
-   */
-  virtual void
-  setDefaultCertificateNameForKeyInternal(const Name& certificateName) = 0;
-
-  /**
-   * @brief return the scheme of the PibLocator
-   */
-  virtual std::string
-  getScheme() = 0;
-
-public:
-
-  /*****************************************
-   *            Helper Methods             *
-   *****************************************/
-
-  /**
-   * @brief Set the default identity
-   *
-   * @param identityName The default identity name
-   * @throws SecPublicInfo::Error if the identity does not exist
-   */
-  void
-  setDefaultIdentity(const Name& identityName);
-
-  /**
-   * @brief Set the default key name for the corresponding identity
-   *
-   * @param keyName The key name
-   * @throws SecPublicInfo::Error if either the identity or key does not exist
-   */
-  void
-  setDefaultKeyNameForIdentity(const Name& keyName);
-
-  /**
-   * @brief Set the default certificate name for the corresponding key
-   *
-   * @param certificateName The certificate name
-   * @throws SecPublicInfo::Error if either the certificate or key does not exist
-   */
-  void
-  setDefaultCertificateNameForKey(const Name& certificateName);
-
-  /**
-   * @brief Generate a key name for the identity
-   *
-   * @param identityName The identity name
-   * @param useKsk If true, generate a KSK name, otherwise a DSK name
-   * @return The generated key name
-   */
-  Name
-  getNewKeyName(const Name& identityName, bool useKsk);
-
-  /**
-   * @brief Get the default certificate name for the specified identity
-   *
-   * @param identityName The identity name
-   * @return The default certificate name
-   * @throws SecPublicInfo::Error if no certificate is found
-   */
-  Name
-  getDefaultCertificateNameForIdentity(const Name& identityName);
-
-  /**
-   * @brief Get the default certificate name of the default identity
-   *
-   * @return The requested certificate name
-   * @throws SecPublicInfo::Error if no certificate is found
-   */
-  Name
-  getDefaultCertificateName();
-
-  /**
-   * @brief Add a certificate and set the certificate as the default one of its corresponding key
-   *
-   * @param certificate The certificate to be added
-   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
-   */
-  void
-  addCertificateAsKeyDefault(const IdentityCertificate& certificate);
-
-  /**
-   * @brief Add a certificate into the public key identity storage and set the certificate as the
-   *        default one of its corresponding identity
-   *
-   * @param certificate The certificate to be added
-   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
-   */
-  void
-  addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
-
-  /**
-   * @brief Add a certificate into the public key identity storage and set the certificate as the
-   *        default one of the default identity
-   *
-   * @param certificate The certificate to be added
-   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
-   */
-  void
-  addCertificateAsSystemDefault(const IdentityCertificate& certificate);
-
-  /**
-   * @brief Get cached default certificate of the default identity
-   *
-   * @return The certificate which might be empty shared_ptr<IdentityCertificate>()
-   * @deprecated Use getDefaultCertificate instead
-   */
-  DEPRECATED(
-  shared_ptr<IdentityCertificate>
-  defaultCertificate());
-
-  /**
-   * @brief Get cached default certificate of the default identity
-   *
-   * @return The certificate which might be empty shared_ptr<IdentityCertificate>()
-   */
-  shared_ptr<IdentityCertificate>
-  getDefaultCertificate();
-
-  /**
-   * @brief try to get the default certificate of the default identity from the public info
-   */
-  void
-  refreshDefaultCertificate();
-
-protected:
-  shared_ptr<IdentityCertificate> m_defaultCertificate;
-  std::string m_location;
-};
-
-} // namespace v1
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-using v1::SecPublicInfo;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-using security::v1::SecPublicInfo;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SEC_PUBLIC_INFO_HPP
diff --git a/src/security/v1/sec-tpm-file.cpp b/src/security/v1/sec-tpm-file.cpp
deleted file mode 100644
index a4bb654..0000000
--- a/src/security/v1/sec-tpm-file.cpp
+++ /dev/null
@@ -1,593 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Xingyu Ma <http://www.linkedin.com/pub/xingyu-ma/1a/384/5a8>
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "sec-tpm-file.hpp"
-
-#include "../../encoding/buffer-stream.hpp"
-
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp>
-
-#include "cryptopp.hpp"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-using std::string;
-using std::ostringstream;
-using std::ofstream;
-
-const std::string SecTpmFile::SCHEME("tpm-file");
-
-class SecTpmFile::Impl
-{
-public:
-  explicit
-  Impl(const string& dir)
-  {
-    boost::filesystem::path actualDir;
-    if (dir.empty()) {
-#ifdef NDN_CXX_HAVE_TESTS
-      if (getenv("TEST_HOME") != nullptr) {
-        actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
-      }
-      else
-#endif // NDN_CXX_HAVE_TESTS
-      if (getenv("HOME") != nullptr) {
-        actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
-      }
-      else {
-        actualDir = boost::filesystem::path(".") / ".ndn";
-      }
-    }
-    else {
-      actualDir = boost::filesystem::path(dir);
-    }
-
-    m_keystorePath = actualDir / "ndnsec-tpm-file";
-    boost::filesystem::create_directories(m_keystorePath);
-  }
-
-  boost::filesystem::path
-  transformName(const string& keyName, const string& extension)
-  {
-    using namespace CryptoPP;
-    string digest;
-    SHA256 hash;
-    StringSource src(keyName,
-                     true,
-                     new HashFilter(hash,
-                                    new Base64Encoder(new CryptoPP::StringSink(digest))));
-
-    boost::algorithm::trim(digest);
-    std::replace(digest.begin(), digest.end(), '/', '%');
-
-    return m_keystorePath / (digest + extension);
-  }
-
-  string
-  maintainMapping(const string& keyName)
-  {
-    string keyFileName = transformName(keyName, "").string();
-
-    ofstream outfile;
-    string dirFile = (m_keystorePath / "mapping.txt").string();
-
-    outfile.open(dirFile.c_str(), std::ios_base::app);
-    outfile << keyName << ' ' << keyFileName << '\n';
-    outfile.close();
-
-    return keyFileName;
-  }
-
-public:
-  boost::filesystem::path m_keystorePath;
-};
-
-
-SecTpmFile::SecTpmFile(const string& location)
-  : SecTpm(location)
-  , m_impl(new Impl(location))
-  , m_inTerminal(false)
-{
-}
-
-SecTpmFile::~SecTpmFile()
-{
-}
-
-void
-SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
-{
-  string keyURI = keyName.toUri();
-
-  if (doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
-    BOOST_THROW_EXCEPTION(Error("public key exists"));
-  if (doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
-    BOOST_THROW_EXCEPTION(Error("private key exists"));
-
-  string keyFileName = m_impl->maintainMapping(keyURI);
-
-  try {
-    switch (params.getKeyType()) {
-      case KeyType::RSA: {
-        using namespace CryptoPP;
-
-        const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
-        AutoSeededRandomPool rng;
-        InvertibleRSAFunction privateKey;
-        privateKey.Initialize(rng, rsaParams.getKeySize());
-
-        string privateKeyFileName = keyFileName + ".pri";
-        Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
-        privateKey.DEREncode(privateKeySink);
-        privateKeySink.MessageEnd();
-
-        RSAFunction publicKey(privateKey);
-        string publicKeyFileName = keyFileName + ".pub";
-        Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
-        publicKey.DEREncode(publicKeySink);
-        publicKeySink.MessageEnd();
-
-        // set file permission
-        chmod(privateKeyFileName.c_str(), 0000400);
-        chmod(publicKeyFileName.c_str(), 0000444);
-        return;
-      }
-
-      case KeyType::EC: {
-        using namespace CryptoPP;
-
-        const EcKeyParams& ecParams = static_cast<const EcKeyParams&>(params);
-
-        CryptoPP::OID curveName;
-        switch (ecParams.getKeySize()) {
-        case 256:
-          curveName = ASN1::secp256r1();
-          break;
-        case 384:
-          curveName = ASN1::secp384r1();
-          break;
-        default:
-          curveName = ASN1::secp256r1();
-          break;
-        }
-
-        AutoSeededRandomPool rng;
-
-        ECDSA<ECP, SHA256>::PrivateKey privateKey;
-        DL_GroupParameters_EC<ECP> cryptoParams(curveName);
-        cryptoParams.SetEncodeAsOID(true);
-        privateKey.Initialize(rng, cryptoParams);
-
-        ECDSA<ECP, SHA256>::PublicKey publicKey;
-        privateKey.MakePublicKey(publicKey);
-        publicKey.AccessGroupParameters().SetEncodeAsOID(true);
-
-        string privateKeyFileName = keyFileName + ".pri";
-        Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
-        privateKey.DEREncode(privateKeySink);
-        privateKeySink.MessageEnd();
-
-        string publicKeyFileName = keyFileName + ".pub";
-        Base64Encoder publicKeySink(new FileSink(publicKeyFileName.c_str()));
-        publicKey.Save(publicKeySink);
-        publicKeySink.MessageEnd();
-
-        // set file permission
-        chmod(privateKeyFileName.c_str(), 0000400);
-        chmod(publicKeyFileName.c_str(), 0000444);
-        return;
-      }
-
-      default:
-        BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
-    }
-  }
-  catch (const KeyParams::Error& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
-  }
-}
-
-void
-SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
-{
-  boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
-  boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
-
-  if (boost::filesystem::exists(publicKeyPath))
-    boost::filesystem::remove(publicKeyPath);
-
-  if (boost::filesystem::exists(privateKeyPath))
-    boost::filesystem::remove(privateKeyPath);
-}
-
-shared_ptr<PublicKey>
-SecTpmFile::getPublicKeyFromTpm(const Name&  keyName)
-{
-  string keyURI = keyName.toUri();
-
-  if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
-    BOOST_THROW_EXCEPTION(Error("Public Key does not exist"));
-
-  ostringstream os;
-  try {
-    using namespace CryptoPP;
-    FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
-               true,
-               new Base64Decoder(new FileSink(os)));
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
-  }
-
-  return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()),
-                                os.str().size());
-}
-
-std::string
-SecTpmFile::getScheme()
-{
-  return SCHEME;
-}
-
-ConstBufferPtr
-SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
-{
-  OBufferStream privateKeyOs;
-  CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
-                       new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
-
-  return privateKeyOs.buf();
-}
-
-bool
-SecTpmFile::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
-{
-  try {
-    using namespace CryptoPP;
-
-    string keyFileName = m_impl->maintainMapping(keyName.toUri());
-    keyFileName.append(".pri");
-    StringSource(buf, size,
-                 true,
-                 new Base64Encoder(new FileSink(keyFileName.c_str())));
-    return true;
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-}
-
-bool
-SecTpmFile::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
-{
-  try {
-    using namespace CryptoPP;
-
-    string keyFileName = m_impl->maintainMapping(keyName.toUri());
-    keyFileName.append(".pub");
-    StringSource(buf, size,
-                 true,
-                 new Base64Encoder(new FileSink(keyFileName.c_str())));
-    return true;
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-}
-
-Block
-SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
-                      const Name& keyName, DigestAlgorithm digestAlgorithm)
-{
-  string keyURI = keyName.toUri();
-
-  if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
-    BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));
-
-  try {
-    using namespace CryptoPP;
-    AutoSeededRandomPool rng;
-
-    // Read public key
-    shared_ptr<PublicKey> pubkeyPtr;
-    pubkeyPtr = getPublicKeyFromTpm(keyName);
-
-    switch (pubkeyPtr->getKeyType()) {
-      case KeyType::RSA: {
-        // Read private key
-        ByteQueue bytes;
-        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
-                        true, new Base64Decoder);
-        file.TransferTo(bytes);
-        bytes.MessageEnd();
-        RSA::PrivateKey privateKey;
-        privateKey.Load(bytes);
-
-        // Sign message
-        switch (digestAlgorithm) {
-          case DigestAlgorithm::SHA256: {
-            RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);
-
-            OBufferStream os;
-            StringSource(data, dataLength,
-                         true,
-                         new SignerFilter(rng, signer, new FileSink(os)));
-
-            return Block(tlv::SignatureValue, os.buf());
-          }
-
-          default:
-            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
-        }
-      }
-
-      case KeyType::EC: {
-        // Read private key
-        ByteQueue bytes;
-        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
-                        true, new Base64Decoder);
-        file.TransferTo(bytes);
-        bytes.MessageEnd();
-
-        // Sign message
-        switch (digestAlgorithm) {
-          case DigestAlgorithm::SHA256: {
-            ECDSA<ECP, SHA256>::PrivateKey privateKey;
-            privateKey.Load(bytes);
-            ECDSA<ECP, SHA256>::Signer signer(privateKey);
-
-            OBufferStream os;
-            StringSource(data, dataLength,
-                         true,
-                         new SignerFilter(rng, signer, new FileSink(os)));
-
-            uint8_t buf[200];
-            size_t bufSize = DSAConvertSignatureFormat(buf, sizeof(buf), DSA_DER,
-                                                       os.buf()->buf(), os.buf()->size(),
-                                                       DSA_P1363);
-
-            shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);
-
-            return Block(tlv::SignatureValue, sigBuffer);
-          }
-
-          default:
-            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
-        }
-      }
-
-      default:
-        BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
-    }
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error(e.what()));
-  }
-}
-
-
-ConstBufferPtr
-SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength,
-                         const Name& keyName, bool isSymmetric)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmFile::decryptInTpm is not supported"));
-  // string keyURI = keyName.toUri();
-  // if (!isSymmetric)
-  //   {
-  //     if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
-  //       throw Error("private key doesn't exist");
-
-  //     try{
-  //       using namespace CryptoPP;
-  //       AutoSeededRandomPool rng;
-
-  //       //Read private key
-  //       ByteQueue bytes;
-  //       FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
-  //       file.TransferTo(bytes);
-  //       bytes.MessageEnd();
-  //       RSA::PrivateKey privateKey;
-  //       privateKey.Load(bytes);
-  //       RSAES_PKCS1v15_Decryptor decryptor(privateKey);
-
-  //       OBufferStream os;
-  //       StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
-
-  //       return os.buf();
-  //     }
-  //     catch (const CryptoPP::Exception& e){
-  //       throw Error(e.what());
-  //     }
-  //   }
-  // else
-  //   {
-  //     throw Error("Symmetric encryption is not implemented!");
-  //     // if (!doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
-  //     //     throw Error("symmetric key doesn't exist");
-
-  //     // try{
-  //     //     string keyBits;
-  //     //     string symKeyFileName = m_impl->transformName(keyURI, ".key");
-  //     //     FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
-
-  //     //     using CryptoPP::AES;
-  //     //     AutoSeededRandomPool rnd;
-  //     //     byte iv[AES::BLOCKSIZE];
-  //     //     rnd.GenerateBlock(iv, AES::BLOCKSIZE);
-
-  //     //     CFB_Mode<AES>::Decryption decryptor;
-  //     //     decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
-
-  //     //     OBufferStream os;
-  //     //     StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
-  //     //     return os.buf();
-
-  //     // }
-  //     // catch (const CryptoPP::Exception& e){
-  //     //     throw Error(e.what());
-  //     // }
-  //   }
-}
-
-ConstBufferPtr
-SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength,
-                         const Name& keyName, bool isSymmetric)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmFile::encryptInTpm is not supported"));
-  // string keyURI = keyName.toUri();
-
-  // if (!isSymmetric)
-  //   {
-  //     if (!doesKeyExistInTpm(keyName, KeyClass::PUBLIC))
-  //       throw Error("public key doesn't exist");
-  //     try
-  //       {
-  //         using namespace CryptoPP;
-  //         AutoSeededRandomPool rng;
-
-  //         //Read private key
-  //         ByteQueue bytes;
-  //         FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
-  //         file.TransferTo(bytes);
-  //         bytes.MessageEnd();
-  //         RSA::PublicKey publicKey;
-  //         publicKey.Load(bytes);
-
-  //         OBufferStream os;
-  //         RSAES_PKCS1v15_Encryptor encryptor(publicKey);
-
-  //         StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
-  //         return os.buf();
-  //       }
-  //     catch (const CryptoPP::Exception& e){
-  //       throw Error(e.what());
-  //     }
-  //   }
-  // else
-  //   {
-  //     throw Error("Symmetric encryption is not implemented!");
-  //     // if (!doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
-  //     //     throw Error("symmetric key doesn't exist");
-
-  //     // try{
-  //     //     string keyBits;
-  //     //     string symKeyFileName = m_impl->transformName(keyURI, ".key");
-  //     //     FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
-
-  //     //     using CryptoPP::AES;
-  //     //     AutoSeededRandomPool rnd;
-  //     //     byte iv[AES::BLOCKSIZE];
-  //     //     rnd.GenerateBlock(iv, AES::BLOCKSIZE);
-
-  //     //     CFB_Mode<AES>::Encryption encryptor;
-  //     //     encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
-
-  //     //     OBufferStream os;
-  //     //     StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
-  //     //     return os.buf();
-  //     // } catch (const CryptoPP::Exception& e){
-  //     //     throw Error(e.what());
-  //     // }
-  //   }
-}
-
-void
-SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmFile::generateSymmetricKeyInTpm is not supported"));
-  // string keyURI = keyName.toUri();
-
-  // if (doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
-  //   throw Error("symmetric key exists");
-
-  // string keyFileName = m_impl->maintainMapping(keyURI);
-  // string symKeyFileName = keyFileName + ".key";
-
-  // try{
-  //   switch (keyType){
-  //   case KeyType::AES:
-  //     {
-  //       using namespace CryptoPP;
-  //       AutoSeededRandomPool rng;
-
-  //       SecByteBlock key(0x00, keySize);
-  //       rng.GenerateBlock(key, keySize);
-
-  //       StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
-
-  //       chmod(symKeyFileName.c_str(), 0000400);
-  //       return;
-  //     }
-  //   default:
-  //     throw Error("Unsupported symmetric key type!");
-  //   }
-  // } catch (const CryptoPP::Exception& e){
-  //   throw Error(e.what());
-  // }
-}
-
-bool
-SecTpmFile::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
-{
-  string keyURI = keyName.toUri();
-  if (keyClass == KeyClass::PUBLIC) {
-    return boost::filesystem::exists(m_impl->transformName(keyURI, ".pub"));
-  }
-  if (keyClass == KeyClass::PRIVATE) {
-    return boost::filesystem::exists(m_impl->transformName(keyURI, ".pri"));
-  }
-  if (keyClass == KeyClass::SYMMETRIC) {
-    return boost::filesystem::exists(m_impl->transformName(keyURI, ".key"));
-  }
-  return false;
-}
-
-bool
-SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
-{
-  try {
-    CryptoPP::AutoSeededRandomPool rng;
-    rng.GenerateBlock(res, size);
-    return true;
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/sec-tpm-file.hpp b/src/security/v1/sec-tpm-file.hpp
deleted file mode 100644
index aaaa4ce..0000000
--- a/src/security/v1/sec-tpm-file.hpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Xingyu Ma <http://www.linkedin.com/pub/xingyu-ma/1a/384/5a8>
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef NDN_SECURITY_V1_SEC_TPM_FILE_HPP
-#define NDN_SECURITY_V1_SEC_TPM_FILE_HPP
-
-#include "../../common.hpp"
-
-#include "sec-tpm.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class SecTpmFile : public SecTpm
-{
-public:
-  class Error : public SecTpm::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : SecTpm::Error(what)
-    {
-    }
-  };
-
-  explicit
-  SecTpmFile(const std::string& dir = "");
-
-  virtual
-  ~SecTpmFile();
-
-  virtual void
-  setTpmPassword(const uint8_t* password, size_t passwordLength)
-  {
-  }
-
-  virtual void
-  resetTpmPassword()
-  {
-  }
-
-  virtual void
-  setInTerminal(bool inTerminal)
-  {
-    m_inTerminal = inTerminal;
-  }
-
-  virtual bool
-  getInTerminal() const
-  {
-    return m_inTerminal;
-  }
-
-  virtual bool
-  isLocked()
-  {
-    return false;
-  }
-
-  virtual bool
-  unlockTpm(const char* password, size_t passwordLength, bool usePassword)
-  {
-    return !isLocked();
-  }
-
-  virtual void
-  generateKeyPairInTpm(const Name& keyName, const KeyParams& params);
-
-  virtual void
-  deleteKeyPairInTpm(const Name& keyName);
-
-  virtual shared_ptr<PublicKey>
-  getPublicKeyFromTpm(const Name&  keyName);
-
-  virtual Block
-  signInTpm(const uint8_t* data, size_t dataLength,
-            const Name& keyName, DigestAlgorithm digestAlgorithm);
-
-  virtual ConstBufferPtr
-  decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
-
-  virtual ConstBufferPtr
-  encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
-
-  virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params);
-
-  virtual bool
-  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
-
-  virtual bool
-  generateRandomBlock(uint8_t* res, size_t size);
-
-  virtual void
-  addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
-  {
-  }
-
-protected:
-  ////////////////////////////////
-  // From TrustedPlatformModule //
-  ////////////////////////////////
-  virtual std::string
-  getScheme();
-
-  virtual ConstBufferPtr
-  exportPrivateKeyPkcs8FromTpm(const Name& keyName);
-
-  virtual bool
-  importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size);
-
-  virtual bool
-  importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size);
-
-public:
-  static const std::string SCHEME;
-
-private:
-  class Impl;
-  unique_ptr<Impl> m_impl;
-  bool m_inTerminal;
-};
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SEC_TPM_FILE_HPP
diff --git a/src/security/v1/sec-tpm-osx.cpp b/src/security/v1/sec-tpm-osx.cpp
deleted file mode 100644
index a54bf6e..0000000
--- a/src/security/v1/sec-tpm-osx.cpp
+++ /dev/null
@@ -1,1145 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#include "sec-tpm-osx.hpp"
-#include "public-key.hpp"
-
-#include "../../encoding/oid.hpp"
-#include "../../encoding/buffer-stream.hpp"
-#include "cryptopp.hpp"
-
-#include <pwd.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <boost/lexical_cast.hpp>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
-#include <Security/SecRandom.h>
-#include <CoreServices/CoreServices.h>
-
-#include <Security/SecDigestTransform.h>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-using std::string;
-
-const std::string SecTpmOsx::SCHEME("tpm-osxkeychain");
-
-/**
- * @brief Helper class to wrap CoreFoundation object pointers
- *
- * The class is similar in spirit to shared_ptr, but uses CoreFoundation
- * mechanisms to retain/release object.
- *
- * Original implementation by Christopher Hunt and it was borrowed from
- * http://www.cocoabuilder.com/archive/cocoa/130776-auto-cfrelease-and.html
- */
-template<class T>
-class CFReleaser
-{
-public:
-  //////////////////////////////
-  // Construction/destruction //
-
-  CFReleaser()
-    : m_typeRef(nullptr)
-  {
-  }
-
-  CFReleaser(const T& typeRef)
-    : m_typeRef(typeRef)
-  {
-  }
-
-  CFReleaser(const CFReleaser& inReleaser)
-    : m_typeRef(nullptr)
-  {
-    retain(inReleaser.m_typeRef);
-  }
-
-  CFReleaser&
-  operator=(const T& typeRef)
-  {
-    if (typeRef != m_typeRef) {
-      release();
-      m_typeRef = typeRef;
-    }
-    return *this;
-  }
-
-  CFReleaser&
-  operator=(const CFReleaser& inReleaser)
-  {
-    retain(inReleaser.m_typeRef);
-    return *this;
-  }
-
-  ~CFReleaser()
-  {
-    release();
-  }
-
-  ////////////
-  // Access //
-
-  // operator const T&() const
-  // {
-  //   return m_typeRef;
-  // }
-
-  // operator T&()
-  // {
-  //   return m_typeRef;
-  // }
-
-  const T&
-  get() const
-  {
-    return m_typeRef;
-  }
-
-  T&
-  get()
-  {
-    return m_typeRef;
-  }
-
-  ///////////////////
-  // Miscellaneous //
-
-  void
-  retain(const T& typeRef)
-  {
-    if (typeRef != nullptr) {
-      CFRetain(typeRef);
-    }
-    release();
-    m_typeRef = typeRef;
-  }
-
-  void
-  release()
-  {
-    if (m_typeRef != nullptr) {
-      CFRelease(m_typeRef);
-      m_typeRef = nullptr;
-    }
-  }
-
-  bool
-  operator==(std::nullptr_t)
-  {
-    return get() == nullptr;
-  }
-
-  bool
-  operator!=(std::nullptr_t)
-  {
-    return get() != nullptr;
-  }
-
-private:
-  T m_typeRef;
-};
-
-
-class SecTpmOsx::Impl
-{
-public:
-  Impl()
-    : m_passwordSet(false)
-    , m_inTerminal(false)
-  {
-  }
-
-  /**
-   * @brief Convert NDN name of a key to internal name of the key.
-   *
-   * @return the internal key name
-   */
-  std::string
-  toInternalKeyName(const Name& keyName, KeyClass keyClass);
-
-  /**
-   * @brief Get key.
-   *
-   * @returns pointer to the key
-   */
-  CFReleaser<SecKeychainItemRef>
-  getKey(const Name& keyName, KeyClass keyClass);
-
-  /**
-   * @brief Convert keyType to MAC OS symmetric key key type
-   *
-   * @returns MAC OS key type
-   */
-  CFTypeRef
-  getSymKeyType(KeyType keyType);
-
-  /**
-   * @brief Convert keyType to MAC OS asymmetirc key type
-   *
-   * @returns MAC OS key type
-   */
-  CFTypeRef
-  getAsymKeyType(KeyType keyType);
-
-  /**
-   * @brief Convert keyClass to MAC OS key class
-   *
-   * @returns MAC OS key class
-   */
-  CFTypeRef
-  getKeyClass(KeyClass keyClass);
-
-  /**
-   * @brief Convert digestAlgo to MAC OS algorithm id
-   *
-   * @returns MAC OS algorithm id
-   */
-  CFStringRef
-  getDigestAlgorithm(DigestAlgorithm digestAlgo);
-
-  /**
-   * @brief Get the digest size of the corresponding algorithm
-   *
-   * @return digest size
-   */
-  long
-  getDigestSize(DigestAlgorithm digestAlgo);
-
-  ///////////////////////////////////////////////
-  // everything here is public, including data //
-  ///////////////////////////////////////////////
-public:
-  SecKeychainRef m_keyChainRef;
-  bool m_passwordSet;
-  string m_password;
-  bool m_inTerminal;
-};
-
-SecTpmOsx::SecTpmOsx(const std::string& location)
-  : SecTpm(location)
-  , m_impl(new Impl)
-{
-  // TODO: add location support
-  if (m_impl->m_inTerminal)
-    SecKeychainSetUserInteractionAllowed(false);
-  else
-    SecKeychainSetUserInteractionAllowed(true);
-
-  OSStatus res = SecKeychainCopyDefault(&m_impl->m_keyChainRef);
-
-  if (res == errSecNoDefaultKeychain) //If no default key chain, create one.
-    BOOST_THROW_EXCEPTION(Error("No default keychain, please create one first"));
-}
-
-SecTpmOsx::~SecTpmOsx()
-{
-}
-
-void
-SecTpmOsx::setTpmPassword(const uint8_t* password, size_t passwordLength)
-{
-  m_impl->m_passwordSet = true;
-  std::fill(m_impl->m_password.begin(), m_impl->m_password.end(), 0);
-  m_impl->m_password.clear();
-  m_impl->m_password.append(reinterpret_cast<const char*>(password), passwordLength);
-}
-
-void
-SecTpmOsx::resetTpmPassword()
-{
-  m_impl->m_passwordSet = false;
-  std::fill(m_impl->m_password.begin(), m_impl->m_password.end(), 0);
-  m_impl->m_password.clear();
-}
-
-void
-SecTpmOsx::setInTerminal(bool inTerminal)
-{
-  m_impl->m_inTerminal = inTerminal;
-  if (inTerminal)
-    SecKeychainSetUserInteractionAllowed(false);
-  else
-    SecKeychainSetUserInteractionAllowed(true);
-}
-
-bool
-SecTpmOsx::getInTerminal() const
-{
-  return m_impl->m_inTerminal;
-}
-
-bool
-SecTpmOsx::isLocked()
-{
-  SecKeychainStatus keychainStatus;
-
-  OSStatus res = SecKeychainGetStatus(m_impl->m_keyChainRef, &keychainStatus);
-  if (res != errSecSuccess)
-    return true;
-  else
-    return ((kSecUnlockStateStatus & keychainStatus) == 0);
-}
-
-bool
-SecTpmOsx::unlockTpm(const char* password, size_t passwordLength, bool usePassword)
-{
-  OSStatus res;
-
-  // If the default key chain is already unlocked, return immediately.
-  if (!isLocked())
-    return true;
-
-  // If the default key chain is locked, unlock the key chain.
-  if (usePassword) {
-    // Use the supplied password.
-    res = SecKeychainUnlock(m_impl->m_keyChainRef,
-                            passwordLength,
-                            password,
-                            true);
-  }
-  else if (m_impl->m_passwordSet) {
-    // If no password supplied, then use the configured password if exists.
-    SecKeychainUnlock(m_impl->m_keyChainRef,
-                      m_impl->m_password.size(),
-                      m_impl->m_password.c_str(),
-                      true);
-  }
-#ifdef NDN_CXX_HAVE_GETPASS
-  else if (m_impl->m_inTerminal) {
-    // If no configured password, get password from terminal if inTerminal set.
-    bool isLocked = true;
-    const char* fmt = "Password to unlock the default keychain: ";
-    int count = 0;
-
-    while (isLocked) {
-      if (count > 2)
-        break;
-
-      char* getPassword = nullptr;
-      getPassword = getpass(fmt);
-      count++;
-
-      if (!getPassword)
-        continue;
-
-      res = SecKeychainUnlock(m_impl->m_keyChainRef,
-                              strlen(getPassword),
-                              getPassword,
-                              true);
-
-      memset(getPassword, 0, strlen(getPassword));
-
-      if (res == errSecSuccess)
-        break;
-    }
-  }
-#endif // NDN_CXX_HAVE_GETPASS
-  else {
-    // If inTerminal is not set, get the password from GUI.
-    SecKeychainUnlock(m_impl->m_keyChainRef, 0, nullptr, false);
-  }
-
-  return !isLocked();
-}
-
-void
-SecTpmOsx::generateKeyPairInTpmInternal(const Name& keyName,
-                                        const KeyParams& params,
-                                        bool needRetry)
-{
-
-  if (doesKeyExistInTpm(keyName, KeyClass::PUBLIC)) {
-    BOOST_THROW_EXCEPTION(Error("keyName already exists"));
-  }
-
-  string keyNameUri = m_impl->toInternalKeyName(keyName, KeyClass::PUBLIC);
-
-  CFReleaser<CFStringRef> keyLabel =
-    CFStringCreateWithCString(0,
-                              keyNameUri.c_str(),
-                              kCFStringEncodingUTF8);
-
-  CFReleaser<CFMutableDictionaryRef> attrDict =
-    CFDictionaryCreateMutable(0,
-                              3,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              0);
-
-  KeyType keyType = params.getKeyType();
-  uint32_t keySize = 0;
-  switch (keyType) {
-    case KeyType::RSA: {
-      const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
-      keySize = rsaParams.getKeySize();
-      break;
-    }
-
-    case KeyType::EC: {
-      const EcKeyParams& ecParams = static_cast<const EcKeyParams&>(params);
-      keySize = ecParams.getKeySize();
-      break;
-    }
-
-    default:
-      BOOST_THROW_EXCEPTION(Error("Fail to create a key pair: Unsupported key type"));
-  }
-
-  CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(0, kCFNumberIntType, &keySize);
-
-  CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, m_impl->getAsymKeyType(keyType));
-  CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());
-  CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
-
-  CFReleaser<SecKeyRef> publicKey, privateKey;
-  // C-style cast is used as per Apple convention
-  OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict.get(),
-                                    &publicKey.get(), &privateKey.get());
-
-  if (res == errSecSuccess) {
-    return;
-  }
-
-  if (res == errSecAuthFailed && !needRetry) {
-    if (unlockTpm(nullptr, 0, false))
-      generateKeyPairInTpmInternal(keyName, params, true);
-    else
-      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Fail to create a key pair"));
-  }
-}
-
-void
-SecTpmOsx::deleteKeyPairInTpmInternal(const Name& keyName, bool needRetry)
-{
-  CFReleaser<CFStringRef> keyLabel =
-    CFStringCreateWithCString(0,
-                              keyName.toUri().c_str(),
-                              kCFStringEncodingUTF8);
-
-  CFReleaser<CFMutableDictionaryRef> searchDict =
-    CFDictionaryCreateMutable(0, 5,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              &kCFTypeDictionaryValueCallBacks);
-
-  CFDictionaryAddValue(searchDict.get(), kSecClass, kSecClassKey);
-  CFDictionaryAddValue(searchDict.get(), kSecAttrLabel, keyLabel.get());
-  CFDictionaryAddValue(searchDict.get(), kSecMatchLimit, kSecMatchLimitAll);
-  OSStatus res = SecItemDelete(searchDict.get());
-
-  if (res == errSecSuccess)
-    return;
-
-  if (res == errSecAuthFailed && !needRetry) {
-    if (unlockTpm(nullptr, 0, false))
-      deleteKeyPairInTpmInternal(keyName, true);
-  }
-}
-
-void
-SecTpmOsx::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmOsx::generateSymmetricKeyInTpm is not supported"));
-  // if (doesKeyExistInTpm(keyName, KeyClass::SYMMETRIC))
-  //   throw Error("keyName has existed!");
-
-  // string keyNameUri =  m_impl->toInternalKeyName(keyName, KeyClass::SYMMETRIC);
-
-  // CFReleaser<CFMutableDictionaryRef> attrDict =
-  //   CFDictionaryCreateMutable(kCFAllocatorDefault,
-  //                             0,
-  //                             &kCFTypeDictionaryKeyCallBacks,
-  //                             &kCFTypeDictionaryValueCallBacks);
-
-  // CFReleaser<CFStringRef> keyLabel =
-  //   CFStringCreateWithCString(0,
-  //                             keyNameUri.c_str(),
-  //                             kCFStringEncodingUTF8);
-
-  // CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(0, kCFNumberIntType, &keySize);
-
-  // CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, m_impl->getSymKeyType(keyType));
-  // CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());
-  // CFDictionaryAddValue(attrDict.get(), kSecAttrIsPermanent, kCFBooleanTrue);
-  // CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
-
-  // CFErrorRef error = 0;
-
-  // SecKeyRef symmetricKey = SecKeyGenerateSymmetric(attrDict, &error);
-
-  // if (error)
-  //   throw Error("Fail to create a symmetric key");
-}
-
-shared_ptr<PublicKey>
-SecTpmOsx::getPublicKeyFromTpm(const Name& keyName)
-{
-  CFReleaser<SecKeychainItemRef> publicKey = m_impl->getKey(keyName, KeyClass::PUBLIC);
-  if (publicKey == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Requested public key [" + keyName.toUri() + "] does not exist "
-                                "in OSX Keychain"));
-  }
-
-  CFReleaser<CFDataRef> exportedKey;
-  OSStatus res = SecItemExport(publicKey.get(),
-                               kSecFormatOpenSSL,
-                               0,
-                               nullptr,
-                               &exportedKey.get());
-  if (res != errSecSuccess) {
-    BOOST_THROW_EXCEPTION(Error("Cannot export requested public key from OSX Keychain"));
-  }
-
-  shared_ptr<PublicKey> key = make_shared<PublicKey>(CFDataGetBytePtr(exportedKey.get()),
-                                                             CFDataGetLength(exportedKey.get()));
-  return key;
-}
-
-std::string
-SecTpmOsx::getScheme()
-{
-  return SCHEME;
-}
-
-ConstBufferPtr
-SecTpmOsx::exportPrivateKeyPkcs8FromTpmInternal(const Name& keyName, bool needRetry)
-{
-  using namespace CryptoPP;
-
-  CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, KeyClass::PRIVATE);
-  if (privateKey == nullptr) {
-    /// @todo Can this happen because of keychain is locked?
-    BOOST_THROW_EXCEPTION(Error("Private key [" + keyName.toUri() + "] does not exist "
-                                "in OSX Keychain"));
-  }
-
-  shared_ptr<PublicKey> publicKey = getPublicKeyFromTpm(keyName);
-
-  CFReleaser<CFDataRef> exportedKey;
-  OSStatus res = SecItemExport(privateKey.get(),
-                               kSecFormatOpenSSL,
-                               0,
-                               nullptr,
-                               &exportedKey.get());
-
-  if (res != errSecSuccess) {
-    if (res == errSecAuthFailed && !needRetry) {
-      if (unlockTpm(nullptr, 0, false))
-        return exportPrivateKeyPkcs8FromTpmInternal(keyName, true);
-      else
-        return nullptr;
-    }
-    else
-      return nullptr;
-  }
-
-  uint32_t version = 0;
-  Oid algorithm;
-  bool hasParameters = false;
-  Oid algorithmParameter;
-  switch (publicKey->getKeyType()) {
-    case KeyType::RSA: {
-      algorithm = oid::RSA; // "RSA encryption"
-      hasParameters = false;
-      break;
-    }
-
-    case KeyType::EC: {
-      // "ECDSA encryption"
-      StringSource src(publicKey->get().buf(), publicKey->get().size(), true);
-      BERSequenceDecoder subjectPublicKeyInfo(src);
-      {
-        BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
-        {
-          algorithm.decode(algorithmInfo);
-          algorithmParameter.decode(algorithmInfo);
-        }
-      }
-      hasParameters = true;
-      break;
-    }
-
-    default:
-      BOOST_THROW_EXCEPTION(Error("Unsupported key type" +
-                                  boost::lexical_cast<std::string>(publicKey->getKeyType())));
-  }
-
-  OBufferStream pkcs8Os;
-  FileSink sink(pkcs8Os);
-
-  SecByteBlock rawKeyBits;
-  // PrivateKeyInfo ::= SEQUENCE {
-  //   version              INTEGER,
-  //   privateKeyAlgorithm  SEQUENCE,
-  //   privateKey           OCTECT STRING}
-  DERSequenceEncoder privateKeyInfo(sink);
-  {
-    DEREncodeUnsigned<uint32_t>(privateKeyInfo, version, INTEGER);
-    DERSequenceEncoder privateKeyAlgorithm(privateKeyInfo);
-    {
-      algorithm.encode(privateKeyAlgorithm);
-      if (hasParameters)
-        algorithmParameter.encode(privateKeyAlgorithm);
-      else
-        DEREncodeNull(privateKeyAlgorithm);
-    }
-    privateKeyAlgorithm.MessageEnd();
-    DEREncodeOctetString(privateKeyInfo,
-                         CFDataGetBytePtr(exportedKey.get()),
-                         CFDataGetLength(exportedKey.get()));
-  }
-  privateKeyInfo.MessageEnd();
-
-  return pkcs8Os.buf();
-}
-
-#ifdef __GNUC__
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-#pragma GCC diagnostic push
-#endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif // __GNUC__
-
-bool
-SecTpmOsx::importPrivateKeyPkcs8IntoTpmInternal(const Name& keyName,
-                                                const uint8_t* buf, size_t size,
-                                                bool needRetry)
-{
-  using namespace CryptoPP;
-
-  StringSource privateKeySource(buf, size, true);
-  SecByteBlock rawKeyBits;
-  // PrivateKeyInfo ::= SEQUENCE {
-  //   INTEGER,
-  //   SEQUENCE,
-  //   OCTECT STRING}
-  BERSequenceDecoder privateKeyInfo(privateKeySource);
-  {
-    uint32_t versionNum;
-    BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
-    BERSequenceDecoder sequenceDecoder(privateKeyInfo);
-    {
-      Oid keyTypeOid;
-      keyTypeOid.decode(sequenceDecoder);
-
-      if (keyTypeOid == oid::RSA)
-        BERDecodeNull(sequenceDecoder);
-      else if (keyTypeOid == oid::ECDSA) {
-        Oid parameterOid;
-        parameterOid.decode(sequenceDecoder);
-      }
-      else
-        return false; // Unsupported key type;
-    }
-    BERDecodeOctetString(privateKeyInfo, rawKeyBits);
-  }
-  privateKeyInfo.MessageEnd();
-
-  CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(0,
-                                                                  rawKeyBits.BytePtr(),
-                                                                  rawKeyBits.size(),
-                                                                  kCFAllocatorNull);
-
-  SecExternalFormat externalFormat = kSecFormatOpenSSL;
-  SecExternalItemType externalType = kSecItemTypePrivateKey;
-  SecKeyImportExportParameters keyParams;
-  memset(&keyParams, 0, sizeof(keyParams));
-  keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
-  keyParams.keyAttributes = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
-  CFReleaser<SecAccessRef> access;
-  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
-                                                               keyName.toUri().c_str(),
-                                                               kCFStringEncodingUTF8);
-  SecAccessCreate(keyLabel.get(), 0, &access.get());
-  keyParams.accessRef = access.get();
-  CFReleaser<CFArrayRef> outItems;
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif // __clang__
-
-  OSStatus res = SecKeychainItemImport(importedKey.get(),
-                                       0,
-                                       &externalFormat,
-                                       &externalType,
-                                       0,
-                                       &keyParams,
-                                       m_impl->m_keyChainRef,
-                                       &outItems.get());
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif // __clang__
-
-  if (res != errSecSuccess) {
-    if (res == errSecAuthFailed && !needRetry) {
-      if (unlockTpm(nullptr, 0, false))
-        return importPrivateKeyPkcs8IntoTpmInternal(keyName, buf, size, true);
-      else
-        return false;
-    }
-    else
-      return false;
-  }
-
-  // C-style cast is used as per Apple convention
-  SecKeychainItemRef privateKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
-  SecKeychainAttribute attrs[1]; // maximum number of attributes
-  SecKeychainAttributeList attrList = {0, attrs};
-  string keyUri = keyName.toUri();
-  {
-    attrs[attrList.count].tag = kSecKeyPrintName;
-    attrs[attrList.count].length = keyUri.size();
-    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
-    attrList.count++;
-  }
-
-  res = SecKeychainItemModifyAttributesAndData(privateKey,
-                                               &attrList,
-                                               0,
-                                               nullptr);
-
-  if (res != errSecSuccess) {
-    return false;
-  }
-
-  return true;
-}
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-#pragma GCC diagnostic pop
-#endif // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-
-bool
-SecTpmOsx::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
-{
-  CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(0,
-                                                                  buf,
-                                                                  size,
-                                                                  kCFAllocatorNull);
-
-  SecExternalFormat externalFormat = kSecFormatOpenSSL;
-  SecExternalItemType externalType = kSecItemTypePublicKey;
-  CFReleaser<CFArrayRef> outItems;
-
-  OSStatus res = SecItemImport(importedKey.get(),
-                               0,
-                               &externalFormat,
-                               &externalType,
-                               0,
-                               0,
-                               m_impl->m_keyChainRef,
-                               &outItems.get());
-
-  if (res != errSecSuccess)
-    return false;
-
-  // C-style cast is used as per Apple convention
-  SecKeychainItemRef publicKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
-  SecKeychainAttribute attrs[1]; // maximum number of attributes
-  SecKeychainAttributeList attrList = { 0, attrs };
-  string keyUri = keyName.toUri();
-  {
-    attrs[attrList.count].tag = kSecKeyPrintName;
-    attrs[attrList.count].length = keyUri.size();
-    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
-    attrList.count++;
-  }
-
-  res = SecKeychainItemModifyAttributesAndData(publicKey,
-                                               &attrList,
-                                               0,
-                                               0);
-
-  if (res != errSecSuccess)
-    return false;
-
-  return true;
-}
-
-Block
-SecTpmOsx::signInTpmInternal(const uint8_t* data, size_t dataLength,
-                             const Name& keyName, DigestAlgorithm digestAlgorithm, bool needRetry)
-{
-  CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(0,
-                                                              data,
-                                                              dataLength,
-                                                              kCFAllocatorNull);
-
-  CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, KeyClass::PRIVATE);
-  if (privateKey == nullptr) {
-    BOOST_THROW_EXCEPTION(Error("Private key [" + keyName.toUri() + "] does not exist "
-                                "in OSX Keychain"));
-  }
-
-  CFReleaser<CFErrorRef> error;
-  // C-style cast is used as per Apple convention
-  CFReleaser<SecTransformRef> signer = SecSignTransformCreate((SecKeyRef)privateKey.get(),
-                                                              &error.get());
-  if (error != nullptr)
-    BOOST_THROW_EXCEPTION(Error("Fail to create signer"));
-
-  // Set input
-  SecTransformSetAttribute(signer.get(),
-                           kSecTransformInputAttributeName,
-                           dataRef.get(),
-                           &error.get());
-  if (error != nullptr)
-    BOOST_THROW_EXCEPTION(Error("Fail to configure input of signer"));
-
-  // Enable use of padding
-  SecTransformSetAttribute(signer.get(),
-                           kSecPaddingKey,
-                           kSecPaddingPKCS1Key,
-                           &error.get());
-  if (error != nullptr)
-    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
-
-  // Set padding type
-  SecTransformSetAttribute(signer.get(),
-                           kSecDigestTypeAttribute,
-                           m_impl->getDigestAlgorithm(digestAlgorithm),
-                           &error.get());
-  if (error != nullptr)
-    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
-
-  // Set padding attribute
-  long digestSize = m_impl->getDigestSize(digestAlgorithm);
-  CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(0, kCFNumberLongType, &digestSize);
-  SecTransformSetAttribute(signer.get(),
-                           kSecDigestLengthAttribute,
-                           cfDigestSize.get(),
-                           &error.get());
-  if (error != nullptr)
-    BOOST_THROW_EXCEPTION(Error("Fail to configure digest size of signer"));
-
-  // Actually sign
-  // C-style cast is used as per Apple convention
-  CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
-  if (error != nullptr) {
-    if (!needRetry) {
-      if (unlockTpm(nullptr, 0, false))
-        return signInTpmInternal(data, dataLength, keyName, digestAlgorithm, true);
-      else
-        BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
-    }
-    else {
-      CFShow(error.get());
-      BOOST_THROW_EXCEPTION(Error("Fail to sign data"));
-    }
-  }
-
-  if (signature == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Signature is NULL!\n"));
-
-  return Block(tlv::SignatureValue,
-               make_shared<Buffer>(CFDataGetBytePtr(signature.get()),
-                                   CFDataGetLength(signature.get())));
-}
-
-ConstBufferPtr
-SecTpmOsx::decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool sym)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmOsx::decryptInTpm is not supported"));
-
-  // KeyClass keyClass;
-  // if (sym)
-  //   keyClass = KeyClass::SYMMETRIC;
-  // else
-  //   keyClass = KeyClass::PRIVATE;
-
-  // CFDataRef dataRef = CFDataCreate(0,
-  //                                  reinterpret_cast<const unsigned char*>(data),
-  //                                  dataLength
-  //                                  );
-
-  // CFReleaser<SecKeyRef> decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
-  // if (decryptKey == nullptr)
-  //   {
-  //     /// @todo Can this happen because of keychain is locked?
-  //     throw Error("Decruption key [" + ??? + "] does not exist in OSX Keychain");
-  //   }
-
-  // CFErrorRef error;
-  // SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
-  // if (error) throw Error("Fail to create decrypt");
-
-  // Boolean set_res = SecTransformSetAttribute(decrypt,
-  //                                            kSecTransformInputAttributeName,
-  //                                            dataRef,
-  //                                            &error);
-  // if (error) throw Error("Fail to configure decrypt");
-
-  // CFDataRef output = (CFDataRef) SecTransformExecute(decrypt, &error);
-  // if (error)
-  //   {
-  //     CFShow(error);
-  //     throw Error("Fail to decrypt data");
-  //   }
-  // if (!output) throw Error("Output is NULL!\n");
-
-  // return make_shared<Buffer>(CFDataGetBytePtr(output), CFDataGetLength(output));
-}
-
-void
-SecTpmOsx::addAppToAcl(const Name& keyName, KeyClass keyClass, const string& appPath, AclType acl)
-{
-  if (keyClass == KeyClass::PRIVATE && acl == AclType::PRIVATE) {
-    CFReleaser<SecKeychainItemRef> privateKey = m_impl->getKey(keyName, keyClass);
-    if (privateKey == nullptr) {
-      BOOST_THROW_EXCEPTION(Error("Private key [" + keyName.toUri() + "] does not exist "
-                                  "in OSX Keychain"));
-    }
-
-    CFReleaser<SecAccessRef> accRef;
-    SecKeychainItemCopyAccess(privateKey.get(), &accRef.get());
-
-    CFReleaser<CFArrayRef> signACL = SecAccessCopyMatchingACLList(accRef.get(),
-                                                                  kSecACLAuthorizationSign);
-
-    // C-style cast is used as per Apple convention
-    SecACLRef aclRef = (SecACLRef)CFArrayGetValueAtIndex(signACL.get(), 0);
-
-    CFReleaser<CFArrayRef> appList;
-    CFReleaser<CFStringRef> description;
-    SecKeychainPromptSelector promptSelector;
-    SecACLCopyContents(aclRef,
-                       &appList.get(),
-                       &description.get(),
-                       &promptSelector);
-
-    CFReleaser<CFMutableArrayRef> newAppList = CFArrayCreateMutableCopy(0,
-                                                                        0,
-                                                                        appList.get());
-
-    CFReleaser<SecTrustedApplicationRef> trustedApp;
-    SecTrustedApplicationCreateFromPath(appPath.c_str(),
-                                        &trustedApp.get());
-
-    CFArrayAppendValue(newAppList.get(), trustedApp.get());
-
-    SecACLSetContents(aclRef,
-                      newAppList.get(),
-                      description.get(),
-                      promptSelector);
-
-    SecKeychainItemSetAccess(privateKey.get(), accRef.get());
-  }
-}
-
-ConstBufferPtr
-SecTpmOsx::encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool sym)
-{
-  BOOST_THROW_EXCEPTION(Error("SecTpmOsx::encryptInTpm is not supported"));
-
-  // KeyClass keyClass;
-  // if (sym)
-  //   keyClass = KeyClass::SYMMETRIC;
-  // else
-  //   keyClass = KeyClass::PUBLIC;
-
-  // CFDataRef dataRef = CFDataCreate(0,
-  //                                  reinterpret_cast<const unsigned char*>(data),
-  //                                  dataLength
-  //                                  );
-
-  // CFReleaser<SecKeyRef> encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
-  // if (encryptKey == nullptr)
-  //   {
-  //     throw Error("Encryption key [" + ???? + "] does not exist in OSX Keychain");
-  //   }
-
-  // CFErrorRef error;
-  // SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
-  // if (error) throw Error("Fail to create encrypt");
-
-  // Boolean set_res = SecTransformSetAttribute(encrypt,
-  //                                            kSecTransformInputAttributeName,
-  //                                            dataRef,
-  //                                            &error);
-  // if (error) throw Error("Fail to configure encrypt");
-
-  // CFDataRef output = (CFDataRef) SecTransformExecute(encrypt, &error);
-  // if (error) throw Error("Fail to encrypt data");
-
-  // if (!output) throw Error("Output is NULL!\n");
-
-  // return make_shared<Buffer> (CFDataGetBytePtr(output), CFDataGetLength(output));
-}
-
-bool
-SecTpmOsx::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
-{
-  string keyNameUri = m_impl->toInternalKeyName(keyName, keyClass);
-
-  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
-                                                               keyNameUri.c_str(),
-                                                               kCFStringEncodingUTF8);
-
-  CFReleaser<CFMutableDictionaryRef> attrDict =
-    CFDictionaryCreateMutable(0,
-                              4,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              0);
-
-  CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
-  // CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, m_impl->getKeyClass(keyClass));
-  CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
-  CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
-
-  CFReleaser<SecKeychainItemRef> itemRef;
-  // C-style cast is used as per Apple convention
-  OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&itemRef.get());
-
-  if (res == errSecSuccess)
-    return true;
-  else
-    return false;
-
-}
-
-bool
-SecTpmOsx::generateRandomBlock(uint8_t* res, size_t size)
-{
-  return SecRandomCopyBytes(kSecRandomDefault, size, res) == 0;
-}
-
-////////////////////////////////
-// OSXPrivateKeyStorage::Impl //
-////////////////////////////////
-
-CFReleaser<SecKeychainItemRef>
-SecTpmOsx::Impl::getKey(const Name& keyName, KeyClass keyClass)
-{
-  string keyNameUri = toInternalKeyName(keyName, keyClass);
-
-  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(0,
-                                                               keyNameUri.c_str(),
-                                                               kCFStringEncodingUTF8);
-
-  CFReleaser<CFMutableDictionaryRef> attrDict =
-    CFDictionaryCreateMutable(0,
-                              5,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              0);
-
-  CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
-  CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
-  CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, getKeyClass(keyClass));
-  CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
-
-  CFReleaser<SecKeychainItemRef> keyItem;
-  // C-style cast is used as per Apple convention
-  OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&keyItem.get());
-
-  if (res != errSecSuccess)
-    return 0;
-  else
-    return keyItem;
-}
-
-string
-SecTpmOsx::Impl::toInternalKeyName(const Name& keyName, KeyClass keyClass)
-{
-  string keyUri = keyName.toUri();
-
-  if (KeyClass::SYMMETRIC == keyClass)
-    return keyUri + "/symmetric";
-  else
-    return keyUri;
-}
-
-CFTypeRef
-SecTpmOsx::Impl::getAsymKeyType(KeyType keyType)
-{
-  switch (keyType) {
-  case KeyType::RSA:
-    return kSecAttrKeyTypeRSA;
-  case KeyType::EC:
-    return kSecAttrKeyTypeECDSA;
-  default:
-    return 0;
-  }
-}
-
-CFTypeRef
-SecTpmOsx::Impl::getSymKeyType(KeyType keyType)
-{
-  switch (keyType) {
-  case KeyType::AES:
-    return kSecAttrKeyTypeAES;
-  default:
-    return 0;
-  }
-}
-
-CFTypeRef
-SecTpmOsx::Impl::getKeyClass(KeyClass keyClass)
-{
-  switch (keyClass) {
-  case KeyClass::PRIVATE:
-    return kSecAttrKeyClassPrivate;
-  case KeyClass::PUBLIC:
-    return kSecAttrKeyClassPublic;
-  case KeyClass::SYMMETRIC:
-    return kSecAttrKeyClassSymmetric;
-  default:
-    return 0;
-  }
-}
-
-CFStringRef
-SecTpmOsx::Impl::getDigestAlgorithm(DigestAlgorithm digestAlgo)
-{
-  switch (digestAlgo) {
-  case DigestAlgorithm::SHA256:
-    return kSecDigestSHA2;
-  default:
-    return 0;
-  }
-}
-
-long
-SecTpmOsx::Impl::getDigestSize(DigestAlgorithm digestAlgo)
-{
-  switch (digestAlgo) {
-  case DigestAlgorithm::SHA256:
-    return 256;
-  default:
-    return -1;
-  }
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/sec-tpm-osx.hpp b/src/security/v1/sec-tpm-osx.hpp
deleted file mode 100644
index 0c1b4d9..0000000
--- a/src/security/v1/sec-tpm-osx.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_V1_SEC_TPM_OSX_HPP
-#define NDN_SECURITY_V1_SEC_TPM_OSX_HPP
-
-#include "../../common.hpp"
-
-#ifndef NDN_CXX_HAVE_OSX_FRAMEWORKS
-#error "This files should not be compiled ..."
-#endif
-
-#include "sec-tpm.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class SecTpmOsx : public SecTpm
-{
-public:
-  class Error : public SecTpm::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : SecTpm::Error(what)
-    {
-    }
-  };
-
-  explicit
-  SecTpmOsx(const std::string& location = "");
-
-  virtual
-  ~SecTpmOsx();
-
-  // Following methods are inherited from SecTpm
-  virtual void
-  setTpmPassword(const uint8_t* password, size_t passwordLength);
-
-  virtual void
-  resetTpmPassword();
-
-  virtual void
-  setInTerminal(bool inTerminal);
-
-  virtual bool
-  getInTerminal() const;
-
-  virtual bool
-  isLocked();
-
-  virtual bool
-  unlockTpm(const char* password, size_t passwordLength, bool usePassword);
-
-  virtual void
-  generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
-  {
-    generateKeyPairInTpmInternal(keyName, params, false);
-  }
-
-  virtual void
-  deleteKeyPairInTpm(const Name& keyName)
-  {
-    deleteKeyPairInTpmInternal(keyName, false);
-  }
-
-  virtual shared_ptr<v1::PublicKey>
-  getPublicKeyFromTpm(const Name& keyName);
-
-  virtual Block
-  signInTpm(const uint8_t* data, size_t dataLength,
-            const Name& keyName, DigestAlgorithm digestAlgorithm)
-  {
-    return signInTpmInternal(data, dataLength, keyName, digestAlgorithm, false);
-  }
-
-  virtual ConstBufferPtr
-  decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
-
-  virtual ConstBufferPtr
-  encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
-
-  virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params);
-
-  virtual bool
-  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
-
-  virtual bool
-  generateRandomBlock(uint8_t* res, size_t size);
-
-  virtual void
-  addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl);
-
-protected:
-  // Following methods are inherited from SecTpm
-  virtual std::string
-  getScheme();
-
-  virtual ConstBufferPtr
-  exportPrivateKeyPkcs8FromTpm(const Name& keyName)
-  {
-    return exportPrivateKeyPkcs8FromTpmInternal(keyName, false);
-  }
-
-  virtual bool
-  importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
-  {
-    return importPrivateKeyPkcs8IntoTpmInternal(keyName, buf, size, false);
-  }
-
-  virtual bool
-  importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size);
-
-  // Following methods are OSX-specific
-  void
-  generateKeyPairInTpmInternal(const Name& keyName, const KeyParams& params, bool needRetry);
-
-  void
-  deleteKeyPairInTpmInternal(const Name& keyName, bool needRetry);
-
-  ConstBufferPtr
-  exportPrivateKeyPkcs8FromTpmInternal(const Name& keyName, bool needRetry);
-
-  bool
-  importPrivateKeyPkcs8IntoTpmInternal(const Name& keyName,
-                                       const uint8_t* buf, size_t size,
-                                       bool needRetry);
-
-  Block
-  signInTpmInternal(const uint8_t* data, size_t dataLength,
-                    const Name& keyName, DigestAlgorithm digestAlgorithm,
-                    bool needRetry);
-
-public:
-  static const std::string SCHEME;
-
-private:
-  class Impl;
-  shared_ptr<Impl> m_impl;
-};
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SEC_TPM_OSX_HPP
diff --git a/src/security/v1/sec-tpm.cpp b/src/security/v1/sec-tpm.cpp
deleted file mode 100644
index fae3b7e..0000000
--- a/src/security/v1/sec-tpm.cpp
+++ /dev/null
@@ -1,387 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#include "sec-tpm.hpp"
-
-#include "../../encoding/oid.hpp"
-#include "../../encoding/buffer-stream.hpp"
-#include "cryptopp.hpp"
-#include <unistd.h>
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-SecTpm::SecTpm(const std::string& location)
-  : m_location(location)
-{
-}
-
-SecTpm::~SecTpm()
-{
-}
-
-std::string
-SecTpm::getTpmLocator()
-{
-  return this->getScheme() + ":" + m_location;
-}
-
-ConstBufferPtr
-SecTpm::exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& passwordStr)
-{
-  using namespace CryptoPP;
-
-  uint8_t salt[8] = {0};
-  uint8_t iv[8] = {0};
-
-  // derive key
-  if (!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
-    BOOST_THROW_EXCEPTION(Error("Cannot generate salt or iv"));
-
-  uint32_t iterationCount = 2048;
-
-  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
-  size_t derivedLen = 24; // For DES-EDE3-CBC-PAD
-  byte derived[24] = {0};
-  byte purpose = 0;
-
-  try {
-    keyGenerator.DeriveKey(derived, derivedLen, purpose,
-                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
-                           salt, 8, iterationCount);
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot derived the encryption key"));
-  }
-
-  // encrypt
-  CBC_Mode< DES_EDE3 >::Encryption e;
-  e.SetKeyWithIV(derived, derivedLen, iv);
-
-  ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);
-
-  if (pkcs8PrivateKey == nullptr)
-    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #1"));
-
-  OBufferStream encryptedOs;
-  try {
-    StringSource stringSource(pkcs8PrivateKey->buf(), pkcs8PrivateKey->size(), true,
-                              new StreamTransformationFilter(e, new FileSink(encryptedOs)));
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #2"));
-  }
-
-  // encode
-  Oid pbes2Id("1.2.840.113549.1.5.13");
-  Oid pbkdf2Id("1.2.840.113549.1.5.12");
-  Oid pbes2encsId("1.2.840.113549.3.7");
-
-  OBufferStream pkcs8Os;
-  try {
-    FileSink sink(pkcs8Os);
-
-    // EncryptedPrivateKeyInfo ::= SEQUENCE {
-    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
-    //   encryptedData        OCTET STRING }
-    DERSequenceEncoder encryptedPrivateKeyInfo(sink);
-    {
-      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
-      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
-      //   parameters     SEQUENCE {{PBES2-params}} }
-      DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
-      {
-        pbes2Id.encode(encryptionAlgorithm);
-        // PBES2-params ::= SEQUENCE {
-        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
-        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
-        DERSequenceEncoder pbes2Params(encryptionAlgorithm);
-        {
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
-          //   parameters     SEQUENCE {{PBKDF2-params}} }
-          DERSequenceEncoder pbes2KDFs(pbes2Params);
-          {
-            pbkdf2Id.encode(pbes2KDFs);
-            // AlgorithmIdentifier ::= SEQUENCE {
-            //   salt           OCTET STRING,
-            //   iterationCount INTEGER (1..MAX),
-            //   keyLength      INTEGER (1..MAX) OPTIONAL,
-            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
-            DERSequenceEncoder pbkdf2Params(pbes2KDFs);
-            {
-              DEREncodeOctetString(pbkdf2Params, salt, 8);
-              DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
-            }
-            pbkdf2Params.MessageEnd();
-          }
-          pbes2KDFs.MessageEnd();
-
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
-          //   parameters  OCTET STRING} {{iv}} }
-          DERSequenceEncoder pbes2Encs(pbes2Params);
-          {
-            pbes2encsId.encode(pbes2Encs);
-            DEREncodeOctetString(pbes2Encs, iv, 8);
-          }
-          pbes2Encs.MessageEnd();
-        }
-        pbes2Params.MessageEnd();
-      }
-      encryptionAlgorithm.MessageEnd();
-
-      DEREncodeOctetString(encryptedPrivateKeyInfo,
-                           encryptedOs.buf()->buf(), encryptedOs.buf()->size());
-    }
-    encryptedPrivateKeyInfo.MessageEnd();
-
-    return pkcs8Os.buf();
-  }
-  catch (const CryptoPP::Exception& e) {
-    BOOST_THROW_EXCEPTION(Error("Cannot export the private key, #3"));
-  }
-}
-
-bool
-SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName,
-                                     const uint8_t* buf, size_t size,
-                                     const std::string& passwordStr)
-{
-  using namespace CryptoPP;
-
-  Oid pbes2Id;
-  Oid pbkdf2Id;
-  SecByteBlock saltBlock;
-  uint32_t iterationCount;
-  Oid pbes2encsId;
-  SecByteBlock ivBlock;
-  SecByteBlock encryptedDataBlock;
-
-  try {
-    // decode some decoding processes are not necessary for now,
-    // because we assume only one encryption scheme.
-    StringSource source(buf, size, true);
-
-    // EncryptedPrivateKeyInfo ::= SEQUENCE {
-    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
-    //   encryptedData        OCTET STRING }
-    BERSequenceDecoder encryptedPrivateKeyInfo(source);
-    {
-      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
-      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
-      //   parameters     SEQUENCE {{PBES2-params}} }
-      BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
-      {
-        pbes2Id.decode(encryptionAlgorithm);
-        // PBES2-params ::= SEQUENCE {
-        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
-        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
-        BERSequenceDecoder pbes2Params(encryptionAlgorithm);
-        {
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
-          //   parameters     SEQUENCE {{PBKDF2-params}} }
-          BERSequenceDecoder pbes2KDFs(pbes2Params);
-          {
-            pbkdf2Id.decode(pbes2KDFs);
-            // AlgorithmIdentifier ::= SEQUENCE {
-            //   salt           OCTET STRING,
-            //   iterationCount INTEGER (1..MAX),
-            //   keyLength      INTEGER (1..MAX) OPTIONAL,
-            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
-            BERSequenceDecoder pbkdf2Params(pbes2KDFs);
-            {
-              BERDecodeOctetString(pbkdf2Params, saltBlock);
-              BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
-            }
-            pbkdf2Params.MessageEnd();
-          }
-          pbes2KDFs.MessageEnd();
-
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
-          //   parameters  OCTET STRING} {{iv}} }
-          BERSequenceDecoder pbes2Encs(pbes2Params);
-          {
-            pbes2encsId.decode(pbes2Encs);
-            BERDecodeOctetString(pbes2Encs, ivBlock);
-          }
-          pbes2Encs.MessageEnd();
-        }
-        pbes2Params.MessageEnd();
-      }
-      encryptionAlgorithm.MessageEnd();
-
-      BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
-    }
-    encryptedPrivateKeyInfo.MessageEnd();
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-
-  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
-  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
-  byte derived[24] = {0};
-  byte purpose = 0;
-
-  try {
-    keyGenerator.DeriveKey(derived, derivedLen,
-                           purpose,
-                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
-                           saltBlock.BytePtr(), saltBlock.size(),
-                           iterationCount);
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-
-  //decrypt
-  CBC_Mode< DES_EDE3 >::Decryption d;
-  d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
-
-  OBufferStream privateKeyOs;
-  try {
-    StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
-                                 new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-
-  if (!importPrivateKeyPkcs8IntoTpm(keyName,
-                                    privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
-    return false;
-
-  // determine key type
-  StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);
-
-  KeyType publicKeyType = KeyType::NONE;
-  SecByteBlock rawKeyBits;
-  // PrivateKeyInfo ::= SEQUENCE {
-  //   INTEGER,
-  //   SEQUENCE,
-  //   OCTECT STRING}
-  BERSequenceDecoder privateKeyInfo(privateKeySource);
-  {
-    uint32_t versionNum;
-    BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
-    BERSequenceDecoder sequenceDecoder(privateKeyInfo);
-    {
-      Oid keyTypeOid;
-      keyTypeOid.decode(sequenceDecoder);
-      if (keyTypeOid == oid::RSA)
-        publicKeyType = KeyType::RSA;
-      else if (keyTypeOid == oid::ECDSA)
-        publicKeyType = KeyType::EC;
-      else
-        return false; // Unsupported key type;
-    }
-  }
-
-
-  // derive public key
-  OBufferStream publicKeyOs;
-
-  try {
-    switch (publicKeyType) {
-      case KeyType::RSA: {
-        RSA::PrivateKey privateKey;
-        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
-        RSAFunction publicKey(privateKey);
-
-        FileSink publicKeySink(publicKeyOs);
-        publicKey.DEREncode(publicKeySink);
-        publicKeySink.MessageEnd();
-        break;
-      }
-
-      case KeyType::EC: {
-        ECDSA<ECP, SHA256>::PrivateKey privateKey;
-        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
-
-        ECDSA<ECP, SHA256>::PublicKey publicKey;
-        privateKey.MakePublicKey(publicKey);
-        publicKey.AccessGroupParameters().SetEncodeAsOID(true);
-
-        FileSink publicKeySink(publicKeyOs);
-        publicKey.DEREncode(publicKeySink);
-        publicKeySink.MessageEnd();
-        break;
-      }
-
-      default:
-        return false;
-    }
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-
-  if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
-    return false;
-
-  return true;
-}
-
-bool
-SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
-{
-  bool isInitialized = false;
-
-#ifdef NDN_CXX_HAVE_GETPASS
-  char* pw0 = nullptr;
-
-  pw0 = getpass(prompt.c_str());
-  if (pw0 == nullptr)
-    return false;
-  std::string password1 = pw0;
-  memset(pw0, 0, strlen(pw0));
-
-  pw0 = getpass("Confirm:");
-  if (pw0 == nullptr) {
-    std::fill(password1.begin(), password1.end(), 0);
-    return false;
-  }
-
-  if (password1.compare(pw0) == 0) {
-    isInitialized = true;
-    password.swap(password1);
-  }
-
-  std::fill(password1.begin(), password1.end(), 0);
-  memset(pw0, 0, strlen(pw0));
-
-  if (password.empty())
-    return false;
-
-#endif // NDN_CXX_HAVE_GETPASS
-
-  return isInitialized;
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/sec-tpm.hpp b/src/security/v1/sec-tpm.hpp
deleted file mode 100644
index 5acb0c3..0000000
--- a/src/security/v1/sec-tpm.hpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- *
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_SECURITY_V1_SEC_TPM_HPP
-#define NDN_SECURITY_V1_SEC_TPM_HPP
-
-#include "../../common.hpp"
-#include "../security-common.hpp"
-#include "../../name.hpp"
-#include "../../data.hpp"
-#include "../key-params.hpp"
-#include "public-key.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-/**
- * @brief SecTpm is the base class of the TPM classes.
- *
- * It specifies the interfaces of private/secret key related operations.
- */
-class SecTpm : noncopyable
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  explicit
-  SecTpm(const std::string& location);
-
-  virtual
-  ~SecTpm();
-
-  std::string
-  getTpmLocator();
-
-  /**
-   * @brief set password of TPM
-   *
-   * Password is used to unlock TPM when it is locked.
-   * You should be cautious when using this method, because remembering password is kind of
-   * dangerous.
-   *
-   * @param password The password
-   * @param passwordLength The length of password
-   */
-  virtual void
-  setTpmPassword(const uint8_t* password, size_t passwordLength) = 0;
-
-  /**
-   * @brief reset password of TPM
-   */
-  virtual void
-  resetTpmPassword() = 0;
-
-  /**
-   * @brief Set inTerminal flag to @p inTerminal
-   *
-   * If the inTerminal flag is set, and password is not set, TPM may ask for password via terminal.
-   * inTerminal flag is set by default.
-   */
-  virtual void
-  setInTerminal(bool inTerminal) = 0;
-
-  /**
-   * @brief Get value of inTerminal flag
-   */
-  virtual bool
-  getInTerminal() const = 0;
-
-  /**
-   * @brief Check if TPM is locked
-   */
-  virtual bool
-  isLocked() = 0;
-
-  /**
-   * @brief Unlock the TPM
-   *
-   * @param password The password.
-   * @param passwordLength The password size. 0 indicates no password.
-   * @param usePassword True if we want to use the supplied password to unlock the TPM.
-   * @return true if TPM is unlocked, otherwise false.
-   */
-  virtual bool
-  unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
-
-  /**
-   * @brief Generate a pair of asymmetric keys.
-   *
-   * @param keyName The name of the key pair.
-   * @param params The parameters of key.
-   * @throws SecTpm::Error if fails.
-   */
-  virtual void
-  generateKeyPairInTpm(const Name& keyName, const KeyParams& params) = 0;
-
-  /**
-   * @brief Delete a key pair of asymmetric keys.
-   *
-   * @param keyName The name of the key pair.
-   */
-  virtual void
-  deleteKeyPairInTpm(const Name& keyName) = 0;
-
-  /**
-   * @brief Get a public key.
-   *
-   * @param keyName The public key name.
-   * @return The public key.
-   * @throws SecTpm::Error if public key does not exist in TPM.
-   */
-  virtual shared_ptr<v1::PublicKey>
-  getPublicKeyFromTpm(const Name& keyName) = 0;
-
-  /**
-   * @brief Sign data.
-   *
-   * @param data Pointer to the byte array to be signed.
-   * @param dataLength The length of data.
-   * @param keyName The name of the signing key.
-   * @param digestAlgorithm the digest algorithm.
-   * @return The signature block.
-   * @throws SecTpm::Error if signing fails.
-   */
-  virtual Block
-  signInTpm(const uint8_t* data, size_t dataLength,
-            const Name& keyName,
-            DigestAlgorithm digestAlgorithm) = 0;
-
-  /**
-   * @brief Decrypt data.
-   *
-   * @param data Pointer to the byte arry to be decrypted.
-   * @param dataLength The length of data.
-   * @param keyName The name of the decrypting key.
-   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
-   * @return The decrypted data.
-   * @throws SecTpm::Error if decryption fails.
-   */
-  virtual ConstBufferPtr
-  decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
-
-  /**
-   * @brief Encrypt data.
-   *
-   * @param data Pointer to the byte arry to be decrypted.
-   * @param dataLength The length of data.
-   * @param keyName The name of the encrypting key.
-   * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric encryption.
-   * @return The encrypted data.
-   * @throws SecTpm::Error if encryption fails.
-   */
-  virtual ConstBufferPtr
-  encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric) = 0;
-
-  /**
-   * @brief Generate a symmetric key.
-   *
-   * @param keyName The name of the key.
-   * @param params The parameter of the key.
-   * @throws SecTpm::Error if key generating fails.
-   */
-  virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params) = 0;
-
-  /**
-   * @brief Check if a particular key exists.
-   *
-   * @param keyName The name of the key.
-   * @param keyClass The class of the key, e.g. KeyClass::PUBLIC, KeyClass::PRIVATE.
-   * @return True if the key exists, otherwise false.
-   */
-  virtual bool
-  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;
-
-  /**
-   * @brief Generate a random block
-   *
-   * @param res The pointer to the generated block
-   * @param size The random block size
-   * @return true for success, otherwise false
-   */
-  virtual bool
-  generateRandomBlock(uint8_t* res, size_t size) = 0;
-
-  /**
-   * @brief Add the application into the ACL of a particular key
-   *
-   * @param keyName the name of key
-   * @param keyClass the class of key, e.g. Private Key
-   * @param appPath the absolute path to the application
-   * @param acl the new acl of the key
-   */
-  virtual void
-  addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
-
-  /**
-   * @brief Export a private key in PKCS#5 format
-   *
-   * @param keyName  The private key name
-   * @param password The password to encrypt the private key
-   * @return The private key info (in PKCS8 format) if exist
-   * @throws SecTpm::Error if private key cannot be exported
-   */
-  ConstBufferPtr
-  exportPrivateKeyPkcs5FromTpm(const Name& keyName, const std::string& password);
-
-  /**
-   * @brief Import a private key in PKCS#5 formatted buffer of size @p bufferSize
-   *
-   * Also recover the public key and installed it in TPM.
-   *
-   * @param keyName    The private key name
-   * @param buffer     Pointer to the first byte of the buffer containing PKCS#5-encoded
-   *                   private key info
-   * @param bufferSize Size of the buffer
-   * @param password   The password to encrypt the private key
-   * @return false if import fails
-   */
-  bool
-  importPrivateKeyPkcs5IntoTpm(const Name& keyName,
-                               const uint8_t* buffer, size_t bufferSize,
-                               const std::string& password);
-
-protected:
-  virtual std::string
-  getScheme() = 0;
-
-  /**
-   * @brief Export a private key in PKCS#8 format.
-   *
-   * @param keyName The private key name.
-   * @return The private key info (in PKCS#8 format) if exist, otherwise a NULL pointer.
-   */
-  virtual ConstBufferPtr
-  exportPrivateKeyPkcs8FromTpm(const Name& keyName) = 0;
-
-  /**
-   * @brief Import a private key from PKCS#8 formatted buffer of size @p bufferSize
-   *
-   * @param keyName    The private key name.
-   * @param buffer     Pointer to the first byte of the buffer containing PKCS#8-encoded
-   *                   private key info
-   * @param bufferSize Size of the buffer
-   * @return false if import fails
-   */
-  virtual bool
-  importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
-
-  /**
-   * @brief Import a public key in PKCS#1 formatted buffer of size @p bufferSize
-   *
-   * @param keyName    The public key name
-   * @param buffer     Pointer to the first byte of the buffer containing PKCS#1-encoded
-   *                   private key info
-   * @param bufferSize Size of the buffer
-   * @return false if import fails
-   */
-  virtual bool
-  importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buffer, size_t bufferSize) = 0;
-
-  /**
-   * @brief Get import/export password.
-   *
-   * @param password On return, the password.
-   * @param prompt Prompt for password, i.e., "Password for key:"
-   * @return true if password has been obtained.
-   */
-  virtual bool
-  getImpExpPassWord(std::string& password, const std::string& prompt);
-
-protected:
-  std::string m_location;
-};
-
-} // namespace v1
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-using v1::SecTpm;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace security
-
-#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
-using security::v1::SecTpm;
-#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SEC_TPM_HPP
diff --git a/src/security/v1/secured-bag.cpp b/src/security/v1/secured-bag.cpp
deleted file mode 100644
index 8fccbc6..0000000
--- a/src/security/v1/secured-bag.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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.
- */
-
-#include "secured-bag.hpp"
-#include "../../encoding/tlv-security.hpp"
-#include "../../util/concepts.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<SecuredBag>));
-BOOST_CONCEPT_ASSERT((WireEncodable<SecuredBag>));
-BOOST_CONCEPT_ASSERT((WireDecodable<SecuredBag>));
-static_assert(std::is_base_of<tlv::Error, SecuredBag::Error>::value,
-              "SecuredBag::Error must inherit from tlv::Error");
-
-SecuredBag::SecuredBag()
-  : m_wire(tlv::security::IdentityPackage)
-{
-}
-
-SecuredBag::SecuredBag(const Block& wire)
-{
-  this->wireDecode(wire);
-}
-
-SecuredBag::SecuredBag(const IdentityCertificate& cert, ConstBufferPtr key)
-  : m_cert(cert)
-  , m_key(key)
-  , m_wire(tlv::security::IdentityPackage)
-{
-  Block wireKey(tlv::security::KeyPackage, m_key);
-  Block wireCert(tlv::security::CertificatePackage, cert.wireEncode());
-  m_wire.push_back(wireCert);
-  m_wire.push_back(wireKey);
-}
-
-SecuredBag::~SecuredBag()
-{
-}
-
-void
-SecuredBag::wireDecode(const Block& wire)
-{
-  m_wire = wire;
-  m_wire.parse();
-
-  m_cert.wireDecode(m_wire.get(tlv::security::CertificatePackage).blockFromValue());
-
-  Block wireKey = m_wire.get(tlv::security::KeyPackage);
-  shared_ptr<Buffer> key = make_shared<Buffer>(wireKey.value(), wireKey.value_size());
-  m_key = key;
-}
-
-const Block&
-SecuredBag::wireEncode() const
-{
-  m_wire.encode();
-  return m_wire;
-}
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
diff --git a/src/security/v1/secured-bag.hpp b/src/security/v1/secured-bag.hpp
deleted file mode 100644
index fbfb151..0000000
--- a/src/security/v1/secured-bag.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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_SECURITY_V1_SECURED_BAG_HPP
-#define NDN_SECURITY_V1_SECURED_BAG_HPP
-
-#include "../../common.hpp"
-#include "identity-certificate.hpp"
-
-namespace ndn {
-namespace security {
-namespace v1 {
-
-class SecuredBag
-{
-public:
-  class Error : public tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : tlv::Error(what)
-    {
-    }
-  };
-
-  SecuredBag();
-
-  explicit
-  SecuredBag(const Block& wire);
-
-  SecuredBag(const IdentityCertificate& cert,
-             ConstBufferPtr key);
-
-  virtual
-  ~SecuredBag();
-
-  void
-  wireDecode(const Block& wire);
-
-  const Block&
-  wireEncode() const;
-
-  const IdentityCertificate&
-  getCertificate() const
-  {
-    return m_cert;
-  }
-
-  ConstBufferPtr
-  getKey() const
-  {
-    return m_key;
-  }
-
-private:
-  IdentityCertificate m_cert;
-  ConstBufferPtr m_key;
-
-  mutable Block m_wire;
-};
-
-} // namespace v1
-} // namespace security
-} // namespace ndn
-
-#endif // NDN_SECURITY_V1_SECURED_BAG_HPP
diff --git a/src/security/v2/key-chain.hpp b/src/security/v2/key-chain.hpp
index e564326..59bf8fb 100644
--- a/src/security/v2/key-chain.hpp
+++ b/src/security/v2/key-chain.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -502,6 +502,9 @@
 } ndnCxxAuto ## TpmType ## TpmRegistrationVariable
 
 } // namespace v2
+
+using v2::KeyChain;
+
 } // namespace security
 
 using security::v2::KeyChain;
diff --git a/src/security/validation-request.hpp b/src/security/validation-request.hpp
deleted file mode 100644
index a48e365..0000000
--- a/src/security/validation-request.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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_SECURITY_VALIDATION_REQUEST_HPP
-#define NDN_SECURITY_VALIDATION_REQUEST_HPP
-
-#include "../interest.hpp"
-
-namespace ndn {
-namespace security {
-
-/// @brief Callback to report a successful Interest validation.
-typedef function<void(const shared_ptr<const Interest>&)> OnInterestValidated;
-
-/// @brief Callback to report a failed Interest validation.
-typedef function<void(const shared_ptr<const Interest>&,
-                      const std::string&)> OnInterestValidationFailed;
-
-/// @brief Callback to report a successful Data validation.
-typedef function<void(const shared_ptr<const Data>&)> OnDataValidated;
-
-/// @brief Callback to report a failed Data validation.
-typedef function<void(const shared_ptr<const Data>&,
-                      const std::string&)> OnDataValidationFailed;
-
-/**
- * @brief ValidationRequest contains information related to further validation.
- *
- * During a validation process, validator may not have retrieved the corresponding public
- * key of the signature in a packet. ValidationRequest contains the interest for the
- * certificate that carries the public key and also contains the context for the certificate
- * including how to proceed when the public key is authenticated or not, the number of
- * validation steps that have been performed, and how to handle interest timeout.
- */
-class ValidationRequest
-{
-public:
-  ValidationRequest(const Interest& interest,
-                    const OnDataValidated& onDataValidated,
-                    const OnDataValidationFailed& onDataValidationFailed,
-                    int nRetries, int nSteps,
-                    uint64_t requesterFaceId = 0)
-    : m_interest(interest)
-    , m_onDataValidated(onDataValidated)
-    , m_onDataValidationFailed(onDataValidationFailed)
-    , m_nRetries(nRetries)
-    , m_nSteps(nSteps)
-    , m_requesterFaceId(requesterFaceId)
-  {
-  }
-
-  /// @brief the Interest for the requested data/certificate.
-  Interest m_interest;
-  /// @brief callback when the retrieved certificate is authenticated.
-  OnDataValidated m_onDataValidated;
-  /// @brief callback when the retrieved certificate cannot be authenticated.
-  OnDataValidationFailed m_onDataValidationFailed;
-  /// @brief the number of retries when the interest times out.
-  int m_nRetries;
-  /// @brief the number of validation steps that have been performed.
-  int m_nSteps;
-  /// @brief the incoming face id of the origin packet.
-  uint64_t m_requesterFaceId;
-};
-
-} // namespace security
-
-using security::ValidationRequest;
-using security::OnInterestValidated;
-using security::OnInterestValidationFailed;
-using security::OnDataValidated;
-using security::OnDataValidationFailed;
-
-} // namespace ndn
-
-#endif //NDN_SECURITY_VALIDATION_REQUEST_HPP
diff --git a/src/security/validator.cpp b/src/security/validator.cpp
deleted file mode 100644
index bb8ffda..0000000
--- a/src/security/validator.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2017 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.
- */
-
-#include "validator.hpp"
-#include "../lp/tags.hpp"
-#include "../util/sha256.hpp"
-
-#include "v1/cryptopp.hpp"
-
-namespace ndn {
-namespace security {
-
-static Oid SECP256R1("1.2.840.10045.3.1.7");
-static Oid SECP384R1("1.3.132.0.34");
-
-Validator::Validator(Face* face)
-  : m_face(face)
-  , m_wantDirectCertFetch(false)
-{
-}
-
-Validator::Validator(Face& face)
-  : Validator(&face)
-{
-}
-
-Validator::~Validator() = default;
-
-void
-Validator::validate(const Interest& interest,
-                    const OnInterestValidated& onValidated,
-                    const OnInterestValidationFailed& onValidationFailed,
-                    int nSteps)
-{
-  std::vector<shared_ptr<ValidationRequest> > nextSteps;
-  checkPolicy(interest, nSteps, onValidated, onValidationFailed, nextSteps);
-
-  if (nextSteps.empty()) {
-    // If there is no nextStep,
-    // that means InterestPolicy has already been able to verify the Interest.
-    // No more further processes.
-    return;
-  }
-
-  OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
-  afterCheckPolicy(nextSteps, onFailure);
-}
-
-void
-Validator::validate(const Data& data,
-                    const OnDataValidated& onValidated,
-                    const OnDataValidationFailed& onValidationFailed,
-                    int nSteps)
-{
-  std::vector<shared_ptr<ValidationRequest> > nextSteps;
-  checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
-
-  if (nextSteps.empty()) {
-    // If there is no nextStep,
-    // that means Data Policy has already been able to verify the Interest.
-    // No more further processes.
-    return;
-  }
-
-  OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
-  afterCheckPolicy(nextSteps, onFailure);
-}
-
-void
-Validator::onData(const Interest& interest,
-                  const Data& data,
-                  const shared_ptr<ValidationRequest>& nextStep)
-{
-  shared_ptr<const Data> certificateData = preCertificateValidation(data);
-
-  if (!static_cast<bool>(certificateData))
-    return nextStep->m_onDataValidationFailed(data.shared_from_this(),
-                                              "Cannot decode cert: " + data.getName().toUri());
-
-  validate(*certificateData,
-           nextStep->m_onDataValidated, nextStep->m_onDataValidationFailed,
-           nextStep->m_nSteps);
-}
-
-bool
-Validator::verifySignature(const Data& data, const v1::PublicKey& key)
-{
-  if (!data.getSignature().hasKeyLocator())
-    return false;
-
-  return verifySignature(data.wireEncode().value(),
-                         data.wireEncode().value_size() -
-                         data.getSignature().getValue().size(),
-                         data.getSignature(), key);
-}
-
-bool
-Validator::verifySignature(const Interest& interest, const v1::PublicKey& key)
-{
-  const Name& name = interest.getName();
-
-  if (name.size() < signed_interest::MIN_SIZE)
-    return false;
-
-  Signature sig;
-  try {
-    sig.setInfo(name[signed_interest::POS_SIG_INFO].blockFromValue());
-    sig.setValue(name[signed_interest::POS_SIG_VALUE].blockFromValue());
-  }
-  catch (const tlv::Error&) {
-    return false;
-  }
-
-  if (!sig.hasKeyLocator())
-    return false;
-
-  const Block& nameWire = name.wireEncode();
-  return verifySignature(nameWire.value(),
-                         nameWire.value_size() - name[signed_interest::POS_SIG_VALUE].size(),
-                         sig, key);
-}
-
-bool
-Validator::verifySignature(const uint8_t* buf,
-                           const size_t size,
-                           const Signature& sig,
-                           const v1::PublicKey& key)
-{
-  try {
-    using namespace CryptoPP;
-
-    switch (sig.getType()) {
-      case tlv::SignatureSha256WithRsa: {
-        if (key.getKeyType() != KeyType::RSA)
-          return false;
-
-        RSA::PublicKey publicKey;
-        ByteQueue queue;
-
-        queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-        publicKey.Load(queue);
-
-        RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
-        return verifier.VerifyMessage(buf, size,
-                                      sig.getValue().value(), sig.getValue().value_size());
-      }
-
-      case tlv::SignatureSha256WithEcdsa: {
-        if (key.getKeyType() != KeyType::EC)
-          return false;
-
-        ECDSA<ECP, SHA256>::PublicKey publicKey;
-        ByteQueue queue;
-
-        queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-        publicKey.Load(queue);
-
-        ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
-
-        uint32_t length = 0;
-        StringSource src(key.get().buf(), key.get().size(), true);
-        BERSequenceDecoder subjectPublicKeyInfo(src);
-        {
-          BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
-          {
-            Oid algorithm;
-            algorithm.decode(algorithmInfo);
-
-            Oid curveId;
-            curveId.decode(algorithmInfo);
-
-            if (curveId == SECP256R1)
-              length = 256;
-            else if (curveId == SECP384R1)
-              length = 384;
-            else
-              return false;
-          }
-        }
-
-        switch (length) {
-          case 256: {
-            uint8_t buffer[64];
-            size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363,
-                                                        sig.getValue().value(),
-                                                        sig.getValue().value_size(),
-                                                        DSA_DER);
-            return verifier.VerifyMessage(buf, size, buffer, usedSize);
-          }
-
-          case 384: {
-            uint8_t buffer[96];
-            size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363,
-                                                        sig.getValue().value(),
-                                                        sig.getValue().value_size(),
-                                                        DSA_DER);
-            return verifier.VerifyMessage(buf, size, buffer, usedSize);
-          }
-
-          default:
-            return false;
-        }
-      }
-
-      default:
-        // Unsupported sig type
-        return false;
-    }
-  }
-  catch (const CryptoPP::Exception& e) {
-    return false;
-  }
-}
-
-bool
-Validator::verifySignature(const uint8_t* buf, const size_t size, const DigestSha256& sig)
-{
-  try {
-    ConstBufferPtr buffer = util::Sha256::computeDigest(buf, size);
-    const Block& sigValue = sig.getValue();
-
-    if (buffer->size() == sigValue.value_size() &&
-        buffer->size() == util::Sha256::DIGEST_SIZE) {
-      const uint8_t* p1 = buffer->buf();
-      const uint8_t* p2 = sigValue.value();
-
-      return 0 == memcmp(p1, p2, util::Sha256::DIGEST_SIZE);
-    }
-    else
-      return false;
-  }
-  catch (const util::Sha256::Error&) {
-    return false;
-  }
-}
-
-void
-Validator::onNack(const Interest& interest,
-                  const lp::Nack& nack,
-                  int remainingRetries,
-                  const OnFailure& onFailure,
-                  const shared_ptr<ValidationRequest>& validationRequest)
-{
-  if (remainingRetries > 0) {
-    Interest newInterest = Interest(interest);
-    newInterest.refreshNonce();
-
-    //Express the same interest with different nonce and decremented remainingRetries.
-    m_face->expressInterest(newInterest,
-                            bind(&Validator::onData, this, _1, _2, validationRequest),
-                            bind(&Validator::onNack, this, _1, _2,
-                                 remainingRetries - 1, onFailure, validationRequest),
-                            bind(&Validator::onTimeout, this, _1,
-                                 remainingRetries - 1, onFailure, validationRequest));
-  }
-  else {
-    onFailure("Cannot fetch cert: " + interest.getName().toUri());
-  }
-}
-
-void
-Validator::onTimeout(const Interest& interest,
-                     int remainingRetries,
-                     const OnFailure& onFailure,
-                     const shared_ptr<ValidationRequest>& validationRequest)
-{
-  if (remainingRetries > 0) {
-    Interest newInterest = Interest(interest);
-    newInterest.refreshNonce();
-
-    // Express the same interest with different nonce and decremented remainingRetries.
-    m_face->expressInterest(newInterest,
-                            bind(&Validator::onData, this, _1, _2, validationRequest),
-                            bind(&Validator::onNack, this, _1, _2,
-                                 remainingRetries - 1, onFailure, validationRequest),
-                            bind(&Validator::onTimeout, this, _1,
-                                 remainingRetries - 1, onFailure, validationRequest));
-  }
-  else {
-    onFailure("Cannot fetch cert: " + interest.getName().toUri());
-  }
-}
-
-void
-Validator::afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest>>& nextSteps,
-                            const OnFailure& onFailure)
-{
-  if (m_face == nullptr) {
-    onFailure("Require more information to validate the packet!");
-    return;
-  }
-
-  for (shared_ptr<ValidationRequest> step : nextSteps) {
-    if (m_wantDirectCertFetch && step->m_requesterFaceId != 0) {
-      Interest directFetchInterest(step->m_interest);
-      directFetchInterest.refreshNonce();
-      directFetchInterest.setTag(make_shared<lp::NextHopFaceIdTag>(step->m_requesterFaceId));
-      m_face->expressInterest(directFetchInterest, nullptr, nullptr, nullptr);
-    }
-    m_face->expressInterest(step->m_interest,
-                            bind(&Validator::onData, this, _1, _2, step),
-                            bind(&Validator::onNack, this, _1, _2,
-                                 step->m_nRetries, onFailure, step),
-                            bind(&Validator::onTimeout,
-                                 this, _1, step->m_nRetries,
-                                 onFailure,
-                                 step));
-  }
-}
-
-void
-Validator::setDirectCertFetchEnabled(bool isEnabled)
-{
-  m_wantDirectCertFetch = isEnabled;
-}
-
-} // namespace security
-} // namespace ndn
diff --git a/src/security/validator.hpp b/src/security/validator.hpp
deleted file mode 100644
index bb401b9..0000000
--- a/src/security/validator.hpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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_SECURITY_VALIDATOR_HPP
-#define NDN_SECURITY_VALIDATOR_HPP
-
-#include "../face.hpp"
-#include "signature-sha256-with-rsa.hpp"
-#include "signature-sha256-with-ecdsa.hpp"
-#include "digest-sha256.hpp"
-#include "validation-request.hpp"
-#include "v1/public-key.hpp"
-#include "v1/identity-certificate.hpp"
-
-namespace ndn {
-namespace security {
-
-/**
- * @brief provides the interfaces for packet validation.
- */
-class Validator
-{
-public:
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-    }
-  };
-
-  /**
-   * @brief Validator constructor
-   *
-   * @param face Pointer to face through which validator may retrieve certificates.
-   *             Passing a null pointer implies the validator is in offline mode.
-   *
-   * @note Make sure the lifetime of the passed Face is longer than validator.
-   */
-  explicit
-  Validator(Face* face = nullptr);
-
-  /// @deprecated Use the constructor taking Face* as parameter.
-  explicit
-  Validator(Face& face);
-
-  virtual
-  ~Validator();
-
-  /**
-   * @brief Validate Data and call either onValidated or onValidationFailed.
-   *
-   * @param data The Data with the signature to check.
-   * @param onValidated If the Data is validated, this calls onValidated(data).
-   * @param onValidationFailed If validation fails, this calls onValidationFailed(data).
-   */
-  void
-  validate(const Data& data,
-           const OnDataValidated& onValidated,
-           const OnDataValidationFailed& onValidationFailed)
-  {
-    validate(data, onValidated, onValidationFailed, 0);
-  }
-
-  /**
-   * @brief Validate Interest and call either onValidated or onValidationFailed.
-   *
-   * @param interest The Interest with the signature to check.
-   * @param onValidated If the Interest is validated, this calls onValidated(interest).
-   * @param onValidationFailed If validation fails, this calls onValidationFailed(interest).
-   */
-  void
-  validate(const Interest& interest,
-           const OnInterestValidated& onValidated,
-           const OnInterestValidationFailed& onValidationFailed)
-  {
-    validate(interest, onValidated, onValidationFailed, 0);
-  }
-
-  /**
-   * @brief Enable or disable the direct certificate fetch feature.
-   *
-   * When enabled, the validator will attempt to fetch the certificate that signs an Interest from
-   * the sender of that Interest, as identified by IncomingFaceId field, in addition to fetching
-   * from the infrastructure.
-   *
-   * Prior to enabling this feature, the application must enable NextHopFaceId privilege on the face
-   * used by this validator.
-   *
-   * @note Current implementation can only fetch the Interest signer certificate from the
-   * Interest sender; the issuer certificate of that certificate is only fetched from the
-   * infrastructure.
-   *
-   * @note Currently, this feature can only be used with ValidatorConfig.
-   *
-   * @param isEnabled Set true to enable the feature or false to disable.
-   */
-  void
-  setDirectCertFetchEnabled(bool isEnabled);
-
-  /*****************************************
-   *      verifySignature method set       *
-   *****************************************/
-
-  /// @brief Verify the data using the publicKey.
-  static bool
-  verifySignature(const Data& data, const v1::PublicKey& publicKey);
-
-  /**
-   * @brief Verify the signed Interest using the publicKey.
-   *
-   * (Note the signature covers the first n-2 name components).
-   */
-  static bool
-  verifySignature(const Interest& interest, const v1::PublicKey& publicKey);
-
-  /// @brief Verify the blob using the publicKey against the signature.
-  static bool
-  verifySignature(const Buffer& blob, const Signature& sig, const v1::PublicKey& publicKey)
-  {
-    return verifySignature(blob.buf(), blob.size(), sig, publicKey);
-  }
-
-  /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
-  static bool
-  verifySignature(const Data& data,
-                  const Signature& sig,
-                  const v1::PublicKey& publicKey)
-  {
-    return verifySignature(data.wireEncode().value(),
-                           data.wireEncode().value_size() - data.getSignature().getValue().size(),
-                           sig, publicKey);
-  }
-
-  /** @brief Verify the interest using the publicKey against the SHA256-RSA signature.
-   *
-   * (Note the signature covers the first n-2 name components).
-   */
-  static bool
-  verifySignature(const Interest& interest,
-                  const Signature& sig,
-                  const v1::PublicKey& publicKey)
-  {
-    if (interest.getName().size() < 2)
-      return false;
-
-    const Name& name = interest.getName();
-
-    return verifySignature(name.wireEncode().value(),
-                           name.wireEncode().value_size() - name[-1].size(),
-                           sig, publicKey);
-  }
-
-  /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
-  static bool
-  verifySignature(const uint8_t* buf,
-                  const size_t size,
-                  const Signature& sig,
-                  const v1::PublicKey& publicKey);
-
-
-  /// @brief Verify the data against the SHA256 signature.
-  static bool
-  verifySignature(const Data& data, const DigestSha256& sig)
-  {
-    return verifySignature(data.wireEncode().value(),
-                           data.wireEncode().value_size() -
-                           data.getSignature().getValue().size(),
-                           sig);
-  }
-
-  /** @brief Verify the interest against the SHA256 signature.
-   *
-   * (Note the signature covers the first n-2 name components).
-   */
-  static bool
-  verifySignature(const Interest& interest, const DigestSha256& sig)
-  {
-    if (interest.getName().size() < 2)
-      return false;
-
-    const Name& name = interest.getName();
-
-    return verifySignature(name.wireEncode().value(),
-                           name.wireEncode().value_size() - name[-1].size(),
-                           sig);
-  }
-
-  /// @brief Verify the blob against the SHA256 signature.
-  static bool
-  verifySignature(const Buffer& blob, const DigestSha256& sig)
-  {
-    return verifySignature (blob.buf(), blob.size(), sig);
-  }
-
-  /// @brief Verify the blob against the SHA256 signature.
-  static bool
-  verifySignature(const uint8_t* buf, const size_t size, const DigestSha256& sig);
-
-protected:
-  /**
-   * @brief Check the Data against policy and return the next validation step if necessary.
-   *
-   * If there is no next validation step, that validation MUST have been done.
-   * i.e., either onValidated or onValidationFailed callback is invoked.
-   *
-   * @param data               The Data to check.
-   * @param nSteps             The number of validation steps that have been done.
-   * @param onValidated        If the Data is validated, this calls onValidated(data)
-   * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
-   * @param nextSteps          On return, contains the next validation step
-   */
-  virtual void
-  checkPolicy(const Data& data,
-              int nSteps,
-              const OnDataValidated& onValidated,
-              const OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) = 0;
-
-  /**
-   * @brief Check the Interest against validation policy and return the next validation step
-   *        if necessary.
-   *
-   * If there is no next validation step, that validation MUST have been done.
-   * i.e., either onValidated or onValidationFailed callback is invoked.
-   *
-   * @param interest           The Interest to check.
-   * @param nSteps             The number of validation steps that have been done.
-   * @param onValidated        If the Interest is validated, this calls onValidated(data)
-   * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
-   * @param nextSteps          On return, contains the next validation step
-   */
-  virtual void
-  checkPolicy(const Interest& interest,
-              int nSteps,
-              const OnInterestValidated& onValidated,
-              const OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) = 0;
-
-  typedef function<void(const std::string&)> OnFailure;
-
-  /// @brief Process the received certificate.
-  void
-  onData(const Interest& interest,
-         const Data& data,
-         const shared_ptr<ValidationRequest>& nextStep);
-
-  void
-  validate(const Data& data,
-           const OnDataValidated& onValidated,
-           const OnDataValidationFailed& onValidationFailed,
-           int nSteps);
-
-  void
-  validate(const Interest& interest,
-           const OnInterestValidated& onValidated,
-           const OnInterestValidationFailed& onValidationFailed,
-           int nSteps);
-
-  /// Hooks
-
-  /**
-   * @brief trigger before validating requested certificate.
-   *
-   * The Data:
-   * - matches the interest in the validation-request.
-   * - may be certificate or a data encapsulating certificate.
-   *
-   * This method returns a data (actually certificate) that is will be passed as Data into:
-   * Validator::validate(const Data& data,
-   *                     const OnDataValidated& onValidated,
-   *                     const OnDataValidationFailed& onValidationFailed,
-   *                     int nSteps);
-   */
-  virtual shared_ptr<const Data>
-  preCertificateValidation(const Data& data)
-  {
-    return data.shared_from_this();
-  }
-
-  /**
-   * @brief trigger when interest retrieves a Nack.
-   *
-   * Validator can decide how to handle a Nack, either call onFailure, or retry.
-   *
-   * @param interest The interest that retrieves a Nack.
-   * @param nack The Nack that is retrieved.
-   * @param nRemainingRetries The number of retries left.
-   * @param onFailure Failure callback when there is no more retries remaining.
-   * @param validationRequest The validationRequest containing the context of the interest.
-   */
-  virtual void
-  onNack(const Interest& interest,
-         const lp::Nack& nack,
-         int nRemainingRetries,
-         const OnFailure& onFailure,
-         const shared_ptr<ValidationRequest>& validationRequest);
-
-  /**
-   * @brief trigger when interest for certificate times out.
-   *
-   * Validator can decide how to handle the timeout, either call onFailure, or retry.
-   *
-   * @param interest The interest that times out.
-   * @param nRemainingRetries The number of retries left.
-   * @param onFailure Failure callback when there is no more retries remaining.
-   * @param validationRequest The validationRequest containing the context of the interest.
-   */
-  virtual void
-  onTimeout(const Interest& interest,
-            int nRemainingRetries,
-            const OnFailure& onFailure,
-            const shared_ptr<ValidationRequest>& validationRequest);
-
-  /**
-   * @brief trigger after checkPolicy is done.
-   *
-   * Validator can decide how to handle the set of validation requests according to
-   * the trust model.
-   *
-   * @param nextSteps A set of validation request made by checkPolicy.
-   * @param onFailure Failure callback when errors happen in processing nextSteps.
-   */
-  virtual void
-  afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest>>& nextSteps,
-                   const OnFailure& onFailure);
-
-protected:
-  Face* m_face;
-  bool m_wantDirectCertFetch;
-};
-
-} // namespace security
-
-using security::Validator;
-
-} // namespace ndn
-
-#endif // NDN_SECURITY_VALIDATOR_HPP
