diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
new file mode 100644
index 0000000..58c3570
--- /dev/null
+++ b/src/security/key-chain.cpp
@@ -0,0 +1,323 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (c) 2013-2014,  Regents of the University of California.
+ * All rights reserved.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * This file licensed under New BSD License.  See COPYING for detailed information about
+ * ndn-cxx library copyright, permissions, and redistribution restrictions.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#include "key-chain.hpp"
+
+#include "sec-public-info-sqlite3.hpp"
+#include "sec-tpm-file.hpp"
+
+#ifdef NDN_CXX_HAVE_OSX_SECURITY
+#include "sec-tpm-osx.hpp"
+#endif
+
+#include "../util/random.hpp"
+#include "../util/config-file.hpp"
+
+namespace ndn {
+
+KeyChain::KeyChain()
+  : m_pib(0)
+  , m_tpm(0)
+{
+
+  ConfigFile config;
+  const ConfigFile::Parsed& parsed = config.getParsedConfiguration();
+
+  std::string pibName;
+  try
+    {
+      pibName = parsed.get<std::string>("pib");
+    }
+  catch (boost::property_tree::ptree_bad_path& error)
+    {
+      // pib is not specified, take the default
+    }
+  catch (boost::property_tree::ptree_bad_data& error)
+    {
+      throw ConfigFile::Error(error.what());
+    }
+
+  std::string tpmName;
+  try
+    {
+      tpmName = parsed.get<std::string>("tpm");
+    }
+  catch (boost::property_tree::ptree_bad_path& error)
+    {
+      // tpm is not specified, take the default
+    }
+  catch (boost::property_tree::ptree_bad_data& error)
+    {
+      throw ConfigFile::Error(error.what());
+    }
+
+
+  if (pibName.empty() || pibName == "sqlite3")
+    m_pib = new SecPublicInfoSqlite3;
+  else
+    throw Error("PIB type '" + pibName + "' is not supported");
+
+  if (tpmName.empty())
+#if defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+    m_tpm = new SecTpmOsx();
+#else
+    m_tpm = new SecTpmFile();
+#endif // defined(NDN_CXX_HAVE_OSX_SECURITY) and defined(NDN_CXX_WITH_OSX_KEYCHAIN)
+  else if (tpmName == "osx-keychain")
+#if defined(NDN_CXX_HAVE_OSX_SECURITY)
+    m_tpm = new SecTpmOsx();
+#else
+    throw Error("TPM type '" + tpmName + "' is not supported on this platform");
+#endif // NDN_CXX_HAVE_OSX_SECURITY
+  else if (tpmName == "file")
+    m_tpm = new SecTpmFile();
+  else
+    throw Error("TPM type '" + tpmName + "' is not supported");
+}
+
+KeyChain::KeyChain(const std::string& pibName,
+                   const std::string& tpmName)
+  : m_pib(0)
+  , m_tpm(0)
+{
+  if (pibName == "sqlite3")
+    m_pib = new SecPublicInfoSqlite3;
+  else
+    throw Error("PIB type '" + pibName + "' is not supported");
+
+  if (tpmName == "file")
+    m_tpm = new SecTpmFile;
+#if defined(NDN_CXX_HAVE_OSX_SECURITY)
+  else if (tpmName == "osx-keychain")
+    m_tpm = new SecTpmOsx();
+#endif //NDN_CXX_HAVE_OSX_SECURITY
+  else
+    throw Error("TPM type '" + tpmName + "' is not supported");
+}
+
+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)
+{
+  if (keyName.size() < 1)
+    return shared_ptr<IdentityCertificate>();
+
+  std::string keyIdPrefix = keyName.get(-1).toEscapedString().substr(0, 4);
+  if (keyIdPrefix != "ksk-" && keyIdPrefix != "dsk-")
+    return shared_ptr<IdentityCertificate>();
+
+  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
+  Name certName;
+
+  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();
+    }
+
+  certificate->setName(certName);
+  certificate->setNotBefore(notBefore);
+  certificate->setNotAfter(notAfter);
+
+  shared_ptr<PublicKey> publicKey;
+  try
+    {
+      publicKey = m_pib->getPublicKey(keyName);
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      return shared_ptr<IdentityCertificate>();
+    }
+  certificate->setPublicKeyInfo(*publicKey);
+
+  if (subjectDescription.empty())
+    {
+      CertificateSubjectDescription subjectName("2.5.4.41", 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;
+}
+
+Signature
+KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+{
+  if (!m_pib->doesCertificateExist(certificateName))
+    throw SecPublicInfo::Error("Requested certificate ["
+                               + certificateName.toUri() + "] doesn't exist");
+
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
+
+  SignatureSha256WithRsa signature;
+  // implicit conversion should take care
+  signature.setKeyLocator(certificateName.getPrefix(-1));
+
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue(m_tpm->signInTpm(buffer, bufferLength, keyName, DIGEST_ALGORITHM_SHA256));
+  return signature;
+}
+
+shared_ptr<IdentityCertificate>
+KeyChain::selfSign(const Name& keyName)
+{
+  shared_ptr<PublicKey> pubKey;
+  try
+    {
+      pubKey = m_pib->getPublicKey(keyName); // may throw an exception.
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      return shared_ptr<IdentityCertificate>();
+    }
+
+  shared_ptr<IdentityCertificate> 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("2.5.4.41", keyName.toUri()));
+  certificate->encode();
+
+  selfSign(*certificate);
+  return certificate;
+}
+
+void
+KeyChain::selfSign(IdentityCertificate& cert)
+{
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert.getName());
+  if (!m_tpm->doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
+    throw SecTpm::Error("private key does not exist!");
+
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
+
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signPacketWrapper(cert, signature, keyName, DIGEST_ALGORITHM_SHA256);
+}
+
+shared_ptr<SecuredBag>
+KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
+{
+  if (!m_pib->doesIdentityExist(identity))
+    throw SecPublicInfo::Error("Identity does not exist!");
+
+  Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
+
+  ConstBufferPtr pkcs5;
+  try
+    {
+      pkcs5 = m_tpm->exportPrivateKeyPkcs5FromTpm(keyName, passwordStr);
+    }
+  catch (SecTpm::Error& e)
+    {
+      throw SecPublicInfo::Error("Fail to export PKCS5 of private key");
+    }
+
+  shared_ptr<IdentityCertificate> cert;
+  try
+    {
+      cert = m_pib->getCertificate(m_pib->getDefaultCertificateNameForKey(keyName));
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      cert = selfSign(keyName);
+      m_pib->addCertificateAsIdentityDefault(*cert);
+    }
+
+  shared_ptr<SecuredBag> secureBag = make_shared<SecuredBag>(boost::cref(*cert),
+                                                             boost::cref(pkcs5));
+
+  return secureBag;
+}
+
+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->addPublicKey(keyName, KEY_TYPE_RSA, *pubKey);
+  m_pib->setDefaultKeyNameForIdentity(keyName);
+
+  // Add cert
+  m_pib->addCertificateAsIdentityDefault(securedBag.getCertificate());
+}
+
+void
+KeyChain::setDefaultCertificateInternal()
+{
+  m_pib->refreshDefaultCertificate();
+
+  if (!static_cast<bool>(m_pib->defaultCertificate()))
+    {
+      Name defaultIdentity;
+      try
+        {
+          defaultIdentity = m_pib->getDefaultIdentity();
+        }
+      catch (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();
+    }
+}
+
+}
