diff --git a/src/security/v1/key-chain.cpp b/src/security/v1/key-chain.cpp
new file mode 100644
index 0000000..f70bf05
--- /dev/null
+++ b/src/security/v1/key-chain.cpp
@@ -0,0 +1,846 @@
+/* -*- 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/random.hpp"
+#include "../../util/config-file.hpp"
+
+#include "sec-public-info-sqlite3.hpp"
+
+#ifdef NDN_CXX_HAVE_OSX_SECURITY
+#include "sec-tpm-osx.hpp"
+#endif // NDN_CXX_HAVE_OSX_SECURITY
+
+#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_SECURITY) 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_SECURITY) 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_SECURITY
+NDN_CXX_V1_KEYCHAIN_REGISTER_TPM(SecTpmOsx, "tpm-osxkeychain", "osx-keychain");
+#endif // NDN_CXX_HAVE_OSX_SECURITY
+
+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::generateEcdsaKeyPair(const Name& identityName, bool isKsk, uint32_t keySize)
+{
+  EcdsaKeyParams params(keySize);
+  return generateKeyPair(identityName, isKsk, params);
+}
+
+Name
+KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
+{
+  RsaKeyParams params(keySize);
+
+  Name keyName = generateKeyPair(identityName, isKsk, params);
+
+  m_pib->setDefaultKeyNameForIdentity(keyName);
+
+  return keyName;
+}
+
+Name
+KeyChain::generateEcdsaKeyPairAsDefault(const Name& identityName, bool isKsk, uint32_t keySize)
+{
+  EcdsaKeyParams params(keySize);
+
+  Name keyName = generateKeyPair(identityName, isKsk, params);
+
+  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 EcdsaKeyParams defaultEcdsaParams;
+      return defaultEcdsaParams;
+    }
+    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, crypto::computeSha256Digest(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,
+                 crypto::computeSha256Digest(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
new file mode 100644
index 0000000..73aab90
--- /dev/null
+++ b/src/security/v1/key-chain.hpp
@@ -0,0 +1,968 @@
+/* -*- 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/crypto.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  http://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 generateEcdsaKeyPair
+   */
+  Name
+  generateRsaKeyPair(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
+
+  /**
+   * @brief Generate a pair of ECDSA 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
+  generateEcdsaKeyPair(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, generateEcdsaKeyPair, generateEcdsaKeyPairAsDefault
+   */
+  Name
+  generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false, uint32_t keySize = 2048);
+
+  /**
+   * @brief Generate a pair of ECDSA 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, generateEcdsaKeyPair, generateRsaKeyPairAsDefault
+   */
+  Name
+  generateEcdsaKeyPairAsDefault(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/sec-public-info-sqlite3.cpp b/src/security/v1/sec-public-info-sqlite3.cpp
new file mode 100644
index 0000000..efb4e0f
--- /dev/null
+++ b/src/security/v1/sec-public-info-sqlite3.cpp
@@ -0,0 +1,958 @@
+/* -*- 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
new file mode 100644
index 0000000..6e9dfd7
--- /dev/null
+++ b/src/security/v1/sec-public-info-sqlite3.hpp
@@ -0,0 +1,171 @@
+/* -*- 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
new file mode 100644
index 0000000..96c4441
--- /dev/null
+++ b/src/security/v1/sec-public-info.cpp
@@ -0,0 +1,165 @@
+/* -*- 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
new file mode 100644
index 0000000..7ed6ef4
--- /dev/null
+++ b/src/security/v1/sec-public-info.hpp
@@ -0,0 +1,473 @@
+/* -*- 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
new file mode 100644
index 0000000..adda17f
--- /dev/null
+++ b/src/security/v1/sec-tpm-file.cpp
@@ -0,0 +1,593 @@
+/* -*- 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 EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
+
+        CryptoPP::OID curveName;
+        switch (ecdsaParams.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
new file mode 100644
index 0000000..aaaa4ce
--- /dev/null
+++ b/src/security/v1/sec-tpm-file.hpp
@@ -0,0 +1,152 @@
+/* -*- 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
new file mode 100644
index 0000000..f3c3029
--- /dev/null
+++ b/src/security/v1/sec-tpm-osx.cpp
@@ -0,0 +1,1145 @@
+/* -*- 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 EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
+      keySize = ecdsaParams.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
new file mode 100644
index 0000000..7641514
--- /dev/null
+++ b/src/security/v1/sec-tpm-osx.hpp
@@ -0,0 +1,169 @@
+/* -*- 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_SECURITY
+#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
new file mode 100644
index 0000000..fae3b7e
--- /dev/null
+++ b/src/security/v1/sec-tpm.cpp
@@ -0,0 +1,387 @@
+/* -*- 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
new file mode 100644
index 0000000..5acb0c3
--- /dev/null
+++ b/src/security/v1/sec-tpm.hpp
@@ -0,0 +1,319 @@
+/* -*- 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
new file mode 100644
index 0000000..8fccbc6
--- /dev/null
+++ b/src/security/v1/secured-bag.cpp
@@ -0,0 +1,83 @@
+/* -*- 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
new file mode 100644
index 0000000..fbfb151
--- /dev/null
+++ b/src/security/v1/secured-bag.hpp
@@ -0,0 +1,85 @@
+/* -*- 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
