diff --git a/src/common-pch.hpp b/src/common-pch.hpp
index 16bd531..58c4513 100644
--- a/src/common-pch.hpp
+++ b/src/common-pch.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).
@@ -50,7 +50,4 @@
 #include <boost/range/algorithm/copy.hpp>
 #include <boost/regex.hpp>
 
-// Other useful headers to precompile
-#include "security/v1/cryptopp.hpp"
-
 #endif // NDN_COMMON_PCH_HPP
diff --git a/src/encoding/cryptopp/asn_ext.cpp b/src/encoding/cryptopp/asn_ext.cpp
deleted file mode 100644
index 96010c4..0000000
--- a/src/encoding/cryptopp/asn_ext.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2014 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 Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#include "asn_ext.hpp"
-#include "../../util/time.hpp"
-
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-
-using namespace CryptoPP;
-
-namespace ndn {
-
-size_t
-DEREncodeGeneralTime(CryptoPP::BufferedTransformation& bt,
-                     const time::system_clock::TimePoint& time)
-{
-  std::string str = time::toIsoString(time);
-  // For example, 20131226T232254
-  // 20131226T232254.100000
-  BOOST_ASSERT(str.size() >= 15);
-  std::string asn1time = str.substr(0, 8) + str.substr(9,6) + "Z";
-
-  bt.Put(GENERALIZED_TIME);
-  size_t lengthBytes = DERLengthEncode(bt, asn1time.size());
-  bt.Put(reinterpret_cast<const uint8_t*>(asn1time.c_str()), asn1time.size());
-  return 1+lengthBytes+asn1time.size();
-}
-
-void
-BERDecodeTime(CryptoPP::BufferedTransformation& bt,
-              time::system_clock::TimePoint& time)
-{
-  byte b;
-  if (!bt.Get(b) || (b != GENERALIZED_TIME && b != UTC_TIME))
-    BERDecodeError();
-
-  size_t bc;
-  if (!BERLengthDecode(bt, bc))
-    BERDecodeError();
-
-  SecByteBlock time_str(bc);
-  if (bc != bt.Get(time_str, bc))
-    BERDecodeError();
-
-  std::string str;
-  str.assign (time_str.begin(), time_str.end());
-
-  if (b == UTC_TIME) {
-    if (boost::lexical_cast<int>(str.substr(0,2)) < 50)
-      str = "20" + str;
-    else
-      str = "19" + str;
-  }
-
-  time = time::fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6));
-}
-
-} // namespace ndn
diff --git a/src/encoding/cryptopp/asn_ext.hpp b/src/encoding/cryptopp/asn_ext.hpp
deleted file mode 100644
index 359aa8b..0000000
--- a/src/encoding/cryptopp/asn_ext.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.
- *
- * @author: Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- * @author: Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
- */
-
-#ifndef NDN_ASN_EXT_HPP
-#define NDN_ASN_EXT_HPP
-
-#include "../../common.hpp"
-#include "../../security/v1/cryptopp.hpp"
-
-#include "../../util/time.hpp"
-
-namespace ndn {
-
-size_t
-DEREncodeGeneralTime(CryptoPP::BufferedTransformation& bt,
-                     const time::system_clock::TimePoint& time);
-
-void
-BERDecodeTime(CryptoPP::BufferedTransformation& bt,
-              time::system_clock::TimePoint& time);
-
-} // namespace ndn
-
-#endif // NDN_ASN_EXT_HPP
diff --git a/src/encoding/oid.cpp b/src/encoding/oid.cpp
deleted file mode 100644
index da5ee5c..0000000
--- a/src/encoding/oid.cpp
+++ /dev/null
@@ -1,173 +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 "oid.hpp"
-
-#include "../security/v1/cryptopp.hpp"
-
-#include <sstream>
-
-namespace ndn {
-
-static const int OID_MAGIC_NUMBER = 40;
-
-Oid::Oid(const char* oid)
-  : Oid(std::string(oid))
-{
-}
-
-Oid::Oid(const std::string& oid)
-{
-  std::string str = oid + ".";
-
-  size_t pos = 0;
-  size_t ppos = 0;
-
-  while (std::string::npos != pos) {
-    ppos = pos;
-
-    pos = str.find_first_of('.', pos);
-    if (pos == std::string::npos)
-      break;
-
-    m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
-
-    pos++;
-  }
-}
-
-std::string
-Oid::toString() const
-{
-  std::ostringstream convert;
-
-  for (std::vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
-    if (it != m_oid.begin())
-      convert << ".";
-    convert << *it;
-  }
-
-  return convert.str();
-}
-
-bool
-Oid::equal(const Oid& oid) const
-{
-  std::vector<int>::const_iterator i = m_oid.begin();
-  std::vector<int>::const_iterator j = oid.m_oid.begin();
-
-  for (; i != m_oid.end() && j != oid.m_oid.end(); i++, j++) {
-    if (*i != *j)
-      return false;
-  }
-
-  return (i == m_oid.end() && j == oid.m_oid.end()); // keep parenthesis for readability.
-}
-
-inline void
-encodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32 v)
-{
-  using namespace CryptoPP;
-
-  for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U, BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
-    bt.Put(static_cast<byte>(0x80 | ((v >> i) & 0x7f)));
-  bt.Put(static_cast<byte>(v & 0x7f));
-}
-
-inline size_t
-decodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32& v)
-{
-  using namespace CryptoPP;
-
-  v = 0;
-  size_t i = 0;
-  while (true)
-    {
-      byte b;
-      if (!bt.Get(b))
-        BERDecodeError();
-      i++;
-      if (v >> (8 * sizeof(v) - 7)) // v about to overflow
-        BERDecodeError();
-      v <<= 7;
-      v += b & 0x7f;
-      if ((b & 0x80) == 0)
-        return i;
-    }
-}
-
-void
-Oid::encode(CryptoPP::BufferedTransformation& out) const
-{
-  using namespace CryptoPP;
-
-  BOOST_ASSERT(m_oid.size() >= 2);
-
-  ByteQueue temp;
-  temp.Put(byte(m_oid[0] * OID_MAGIC_NUMBER + m_oid[1]));
-  for (size_t i = 2; i < m_oid.size(); i++)
-    encodeValue(temp, m_oid[i]);
-
-  out.Put(OBJECT_IDENTIFIER);
-  DERLengthEncode(out, temp.CurrentSize());
-  temp.TransferTo(out);
-}
-
-void
-Oid::decode(CryptoPP::BufferedTransformation& in)
-{
-  using namespace CryptoPP;
-
-  byte b;
-  if (!in.Get(b) || b != OBJECT_IDENTIFIER)
-    BERDecodeError();
-
-  size_t length;
-  if (!BERLengthDecode(in, length) || length < 1)
-    BERDecodeError();
-
-  if (!in.Get(b))
-    BERDecodeError();
-
-  length--;
-  m_oid.resize(2);
-  m_oid[0] = b / OID_MAGIC_NUMBER;
-  m_oid[1] = b % OID_MAGIC_NUMBER;
-
-  while (length > 0)
-    {
-      word32 v;
-      size_t valueLen = decodeValue(in, v);
-      if (valueLen > length)
-        BERDecodeError();
-      m_oid.push_back(v);
-      length -= valueLen;
-    }
-}
-
-namespace oid {
-const Oid RSA("1.2.840.113549.1.1.1");
-const Oid ECDSA("1.2.840.10045.2.1");
-
-const Oid ATTRIBUTE_NAME("2.5.4.41");
-} // namespace oid
-
-} // namespace ndn
diff --git a/src/encoding/oid.hpp b/src/encoding/oid.hpp
deleted file mode 100644
index 2eea310..0000000
--- a/src/encoding/oid.hpp
+++ /dev/null
@@ -1,104 +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_ENCODING_OID_HPP
-#define NDN_ENCODING_OID_HPP
-
-#include "../common.hpp"
-
-#include <vector>
-
-namespace CryptoPP {
-class BufferedTransformation;
-} // namespace CryptoPP
-
-namespace ndn {
-
-class Oid
-{
-public:
-  Oid() = default;
-
-  explicit
-  Oid(const char* oid);
-
-  explicit
-  Oid(const std::string& oid);
-
-  explicit
-  Oid(const std::vector<int>& oid)
-    : m_oid(oid)
-  {
-  }
-
-  const std::vector<int>&
-  getIntegerList() const
-  {
-    return m_oid;
-  }
-
-  void
-  setIntegerList(const std::vector<int>& value)
-  {
-    m_oid = value;
-  }
-
-  std::string
-  toString() const;
-
-  bool
-  operator==(const Oid& oid) const
-  {
-    return equal(oid);
-  }
-
-  bool
-  operator!=(const Oid& oid) const
-  {
-    return !equal(oid);
-  }
-
-  void
-  encode(CryptoPP::BufferedTransformation& out) const;
-
-  void
-  decode(CryptoPP::BufferedTransformation& in);
-
-private:
-  bool
-  equal(const Oid& oid) const;
-
-private:
-  std::vector<int> m_oid;
-};
-
-namespace oid {
-// crypto algorithm
-extern const Oid RSA;
-extern const Oid ECDSA;
-
-// certificate entries
-extern const Oid ATTRIBUTE_NAME;
-} // namespace oid
-
-} // namespace ndn
-
-#endif // NDN_ENCODING_OID_HPP
diff --git a/src/mgmt/nfd/command-options.hpp b/src/mgmt/nfd/command-options.hpp
index a387eb7..72cfa1c 100644
--- a/src/mgmt/nfd/command-options.hpp
+++ b/src/mgmt/nfd/command-options.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).
@@ -25,13 +25,6 @@
 #include "../../security/signing-info.hpp"
 
 namespace ndn {
-
-namespace security {
-namespace v1 {
-class IdentityCertificate;
-} // namespace v1
-} // namespace security
-
 namespace nfd {
 
 /** \ingroup management
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
