diff --git a/tools/ndnsec/cert-dump.hpp b/tools/ndnsec/cert-dump.hpp
new file mode 100644
index 0000000..fd1313a
--- /dev/null
+++ b/tools/ndnsec/cert-dump.hpp
@@ -0,0 +1,206 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_CERT_DUMP_HPP
+#define NDN_TOOLS_NDNSEC_CERT_DUMP_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_cert_dump(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string name;
+  bool isKeyName = false;
+  bool isIdentityName = false;
+  bool isCertName = true;
+  // bool isFileName = false;
+  bool isPretty = false;
+  bool isStdOut = true;
+  bool isRepoOut = false;
+  std::string repoHost;
+  std::string repoPort;
+  // bool isDnsOut = false;
+
+  po::options_description description("General Usage\n"
+                                      "  ndnsec cert-dump [-h] [-p] [-d] [-r [-H repo-host] "
+                                         "[-P repo-port] ] [-i|k|f] name\n"
+                                      "General options");
+  description.add_options()
+    ("help,h",     "produce help message")
+    ("pretty,p",   "display certificate in human readable format")
+    ("identity,i", "treat the name parameter as identity name (e.g., /ndn/edu/ucla/alice")
+    ("key,k",      "treat the name parameter as key name "
+                   "(e.g., /ndn/edu/ucla/alice/ksk-123456789)")
+    ("file,f",     "treat the name parameter as file name with base64 encoded certificate, "
+                   "- for stdin")
+    ("repo-output,r", "publish the certificate to the repo-ng")
+    ("repo-host,H", po::value<std::string>(&repoHost)->default_value("localhost"),
+                   "the repo host if repo-output is specified")
+    ("repo-port,P", po::value<std::string>(&repoPort)->default_value("7376"),
+                   "the repo port if repo-output is specified")
+    // ("dns-output,d", "published the certificate to NDNS")
+    ("name,n", po::value<std::string>(&name),
+                   "unless overridden with --identity or --key parameter, the certificate name, "
+                   "for example, /ndn/edu/ucla/KEY/cs/alice/ksk-1234567890"
+                                "/ID-CERT/%FD%FF%FF%FF%FF%FF%FF%FF")
+    ;
+
+  po::positional_options_description p;
+  p.add("name", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("name") == 0)
+    {
+      std::cerr << "identity_name must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("key") != 0)
+    {
+      isCertName = false;
+      isKeyName = true;
+    }
+  else if (vm.count("identity") != 0)
+    {
+      isCertName = false;
+      isIdentityName = true;
+    }
+  else if (vm.count("file") != 0)
+    {
+      isCertName = false;
+      // isFileName = true;
+    }
+
+  if (vm.count("pretty") != 0)
+    isPretty = true;
+
+  if (vm.count("repo-output") != 0)
+    {
+      isRepoOut = true;
+      isStdOut = false;
+    }
+  else if (vm.count("dns-output") != 0)
+    {
+      // isDnsOut = true;
+      isStdOut = false;
+      std::cerr << "Error: DNS output is not supported yet!" << std::endl;
+      return 1;
+    }
+
+  if (isPretty && !isStdOut)
+    {
+      std::cerr << "Error: pretty option can only be specified when other "
+                << "output option is specified" << std::endl;
+      return 1;
+    }
+
+  shared_ptr<IdentityCertificate> certificate;
+
+  KeyChain keyChain;
+
+  if (isIdentityName || isKeyName || isCertName)
+    {
+      if (isIdentityName)
+        {
+          Name certName = keyChain.getDefaultCertificateNameForIdentity(name);
+          certificate = keyChain.getCertificate(certName);
+        }
+      else if (isKeyName)
+        {
+          Name certName = keyChain.getDefaultCertificateNameForKey(name);
+          certificate = keyChain.getCertificate(certName);
+        }
+      else
+        certificate = keyChain.getCertificate(name);
+
+      if (!static_cast<bool>(certificate))
+        {
+          std::cerr << "No certificate found!" << std::endl;
+          return 1;
+        }
+    }
+  else
+    {
+      certificate = getIdentityCertificate(name);
+      if (!static_cast<bool>(certificate))
+        {
+          std::cerr << "No certificate read!" << std::endl;
+          return 1;
+        }
+    }
+
+  if (isPretty)
+    {
+      std::cout << *certificate << std::endl;
+    }
+  else
+    {
+      if (isStdOut)
+        {
+          io::save(*certificate, std::cout);
+          return 0;
+        }
+      if (isRepoOut)
+        {
+          using namespace boost::asio::ip;
+          tcp::iostream request_stream;
+          request_stream.expires_from_now(boost::posix_time::milliseconds(3000));
+          request_stream.connect(repoHost, repoPort);
+          if (!request_stream)
+            {
+              std::cerr << "fail to open the stream!" << std::endl;
+              return 1;
+            }
+          request_stream.write(reinterpret_cast<const char*>(certificate->wireEncode().wire()),
+                               certificate->wireEncode().size());
+
+          return 0;
+        }
+    }
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_CERT_DUMP_HPP
diff --git a/tools/ndnsec/cert-gen.hpp b/tools/ndnsec/cert-gen.hpp
new file mode 100644
index 0000000..64e7469
--- /dev/null
+++ b/tools/ndnsec/cert-gen.hpp
@@ -0,0 +1,235 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_CERT_GEN_HPP
+#define NDN_TOOLS_NDNSEC_CERT_GEN_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_cert_gen(int argc, char** argv)
+{
+  using boost::tokenizer;
+  using boost::escaped_list_separator;
+
+  using namespace ndn;
+  using namespace ndn::time;
+  namespace po = boost::program_options;
+
+  KeyChain keyChain;
+
+  std::string notBeforeStr;
+  std::string notAfterStr;
+  std::string subjectName;
+  std::string requestFile("-");
+  Name signId;
+  std::string subjectInfo;
+  std::vector<std::string> signedInfo;
+  Name certPrefix = KeyChain::DEFAULT_PREFIX; // to avoid displaying the default value
+
+  po::options_description description(
+    "General Usage\n"
+    "  ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] "
+        "[-s sign-id] [-p cert-prefix] request\n"
+    "General options");
+
+  description.add_options()
+    ("help,h", "produce help message")
+    ("not-before,S",   po::value<std::string>(&notBeforeStr),
+                       "certificate starting date, YYYYMMDDhhmmss (default: now)")
+    ("not-after,E",    po::value<std::string>(&notAfterStr),
+                       "certificate ending date, YYYYMMDDhhmmss (default: now + 365 days)")
+    ("subject-name,N", po::value<std::string>(&subjectName),
+                       "subject name")
+    ("subject-info,I", po::value<std::string>(&subjectInfo),
+                       "(deprecated, uses 'signed-info') subject info, pairs of OID and string "
+                       " description: \"2.5.4.10 'University of California, Los Angeles'\"")
+    ("signed-info",    po::value<std::vector<std::string> >(&signedInfo),
+                       "a pair of OID and string (must be separated by a single space), e.g., "
+                       "\"2.5.4.10 University of California, Los Angeles\". "
+                       "May be repeated multiple times")
+    ("sign-id,s",      po::value<Name>(&signId)->default_value(keyChain.getDefaultIdentity()),
+                       "signing identity")
+    ("cert-prefix,p",  po::value<Name>(&certPrefix),
+                       "cert prefix, which is the part of certificate name before "
+                       "KEY component")
+    ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
+                       "request file name, - for stdin")
+    ;
+
+  po::positional_options_description p;
+  p.add("request", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cout << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("subject-name") == 0)
+    {
+      std::cerr << "ERROR: subject name must be specified" << std::endl
+                << std::endl
+                << description << std::endl;
+      return 1;
+    }
+
+  std::vector<CertificateSubjectDescription> subjectDescription;
+  subjectDescription.push_back(CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName));
+
+  // 'subjectInfo' is deprecated and the following block will be removed eventually
+  tokenizer<escaped_list_separator<char> > subjectInfoItems
+    (subjectInfo, escaped_list_separator<char>("\\", " \t", "'\""));
+
+  tokenizer<escaped_list_separator<char> >::iterator it =
+    subjectInfoItems.begin();
+
+  while (it != subjectInfoItems.end())
+    {
+      std::string oid = *it;
+
+      it++;
+      if (it == subjectInfoItems.end())
+        {
+          std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl;
+          return 1;
+        }
+
+      std::string value = *it;
+
+      subjectDescription.push_back(CertificateSubjectDescription(OID(oid), value));
+
+      it++;
+    }
+
+  // new 'signedInfo' processing
+  for (std::vector<std::string>::const_iterator info = signedInfo.begin();
+       info != signedInfo.end(); ++info) {
+    size_t pos = info->find(" ");
+    if (pos == std::string::npos) {
+      std::cerr << "ERROR: incorrectly formatted signed info block [" << *info << "]" << std::endl;
+      return 1;
+    }
+    OID oid(info->substr(0, pos));
+    std::string value = info->substr(pos + 1);
+
+    subjectDescription.push_back(CertificateSubjectDescription(oid, value));
+  }
+
+  system_clock::TimePoint notBefore;
+  system_clock::TimePoint notAfter;
+
+  if (vm.count("not-before") == 0)
+    {
+      notBefore = system_clock::now();
+    }
+  else
+    {
+      notBefore = fromIsoString(notBeforeStr.substr(0, 8) + "T" +
+                                notBeforeStr.substr(8, 6));
+    }
+
+  if (vm.count("not-after") == 0)
+    {
+      notAfter = notBefore + days(365);
+    }
+  else
+    {
+      notAfter = fromIsoString(notAfterStr.substr(0, 8) + "T" +
+                               notAfterStr.substr(8, 6));
+
+      if (notAfter < notBefore)
+        {
+          std::cerr << "ERROR: not-before cannot be later than not-after" << std::endl
+                    << std::endl
+                    << description << std::endl;
+          return 1;
+        }
+    }
+
+  if (vm.count("request") == 0)
+    {
+      std::cerr << "ERROR: request file must be specified" << std::endl
+                << std::endl
+                << description << std::endl;
+      return 1;
+    }
+
+  shared_ptr<IdentityCertificate> selfSignedCertificate
+    = getIdentityCertificate(requestFile);
+
+  if (!static_cast<bool>(selfSignedCertificate))
+    {
+      std::cerr << "ERROR: input error" << std::endl;
+      return 1;
+    }
+
+  Name keyName = selfSignedCertificate->getPublicKeyName();
+
+  shared_ptr<IdentityCertificate> certificate =
+    keyChain.prepareUnsignedIdentityCertificate(keyName, selfSignedCertificate->getPublicKeyInfo(),
+                                                signId, notBefore, notAfter,
+                                                subjectDescription, certPrefix);
+
+  if (!static_cast<bool>(certificate))
+    {
+      std::cerr << "ERROR: key name is not formated correctly or does not match certificate name"
+                << std::endl;
+      return 1;
+    }
+
+  keyChain.createIdentity(signId);
+  Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signId);
+  keyChain.sign(*certificate, signingCertificateName);
+
+  Block wire = certificate->wireEncode();
+
+  try
+    {
+      using namespace CryptoPP;
+      StringSource ss(wire.wire(), wire.size(), true,
+                      new Base64Encoder(new FileSink(std::cout), true, 64));
+    }
+  catch (const CryptoPP::Exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_CERT_GEN_HPP
diff --git a/tools/ndnsec/cert-install.hpp b/tools/ndnsec/cert-install.hpp
new file mode 100644
index 0000000..94a73a7
--- /dev/null
+++ b/tools/ndnsec/cert-install.hpp
@@ -0,0 +1,235 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_CERT_INSTALL_HPP
+#define NDN_TOOLS_NDNSEC_CERT_INSTALL_HPP
+
+#include "util.hpp"
+
+
+class HttpException : public std::runtime_error
+{
+public:
+  explicit
+  HttpException(const std::string& what)
+    : std::runtime_error(what)
+  {
+  }
+};
+
+ndn::shared_ptr<ndn::IdentityCertificate>
+getCertificateHttp(const std::string& host, const std::string& port, const std::string& path)
+{
+  using namespace boost::asio::ip;
+  tcp::iostream requestStream;
+
+  requestStream.expires_from_now(boost::posix_time::milliseconds(3000));
+
+  requestStream.connect(host, port);
+  if (!static_cast<bool>(requestStream))
+    {
+      throw HttpException("HTTP connection error");
+    }
+  requestStream << "GET " << path << " HTTP/1.0\r\n";
+  requestStream << "Host: " << host << "\r\n";
+  requestStream << "Accept: */*\r\n";
+  requestStream << "Cache-Control: no-cache\r\n";
+  requestStream << "Connection: close\r\n\r\n";
+  requestStream.flush();
+
+  std::string statusLine;
+  std::getline(requestStream, statusLine);
+  if (!static_cast<bool>(requestStream))
+    {
+      throw HttpException("HTTP communication error");
+    }
+
+  std::stringstream responseStream(statusLine);
+  std::string httpVersion;
+  responseStream >> httpVersion;
+  unsigned int statusCode;
+  responseStream >> statusCode;
+  std::string statusMessage;
+
+  std::getline(responseStream, statusMessage);
+  if (!static_cast<bool>(requestStream) || httpVersion.substr(0, 5) != "HTTP/")
+    {
+      throw HttpException("HTTP communication error");
+    }
+  if (statusCode != 200)
+    {
+      throw HttpException("HTTP server error");
+    }
+  std::string header;
+  while (std::getline(requestStream, header) && header != "\r")
+    ;
+
+  ndn::OBufferStream os;
+  {
+    using namespace CryptoPP;
+    FileSource ss2(requestStream, true, new Base64Decoder(new FileSink(os)));
+  }
+
+  ndn::shared_ptr<ndn::IdentityCertificate> identityCertificate =
+    ndn::make_shared<ndn::IdentityCertificate>();
+  identityCertificate->wireDecode(ndn::Block(os.buf()));
+
+  return identityCertificate;
+}
+
+int
+ndnsec_cert_install(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string certFileName;
+  bool isSystemDefault = true;
+  bool isIdentityDefault = false;
+  bool isKeyDefault = false;
+
+  po::options_description description("General Usage\n  ndnsec cert-install [-h] [-I|K|N] cert-file\nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("cert-file,f", po::value<std::string>(&certFileName), "file name of the ceritificate, - for stdin. "
+                                                      "If starts with http://, will try to fetch "
+                                                      "the certificate using HTTP GET request")
+    ("identity-default,I", "optional, if specified, the certificate will be set as the default certificate of the identity")
+    ("key-default,K", "optional, if specified, the certificate will be set as the default certificate of the key")
+    ("no-default,N", "optional, if specified, the certificate will be simply installed")
+    ;
+  po::positional_options_description p;
+  p.add("cert-file", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("cert-file") == 0)
+    {
+      std::cerr << "cert_file must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("identity-default") != 0)
+    {
+      isIdentityDefault = true;
+      isSystemDefault = false;
+    }
+  else if (vm.count("key-default") != 0)
+    {
+      isKeyDefault = true;
+      isSystemDefault = false;
+    }
+  else if (vm.count("no-default") != 0)
+    {
+      // noDefault = true;
+      isSystemDefault = false;
+    }
+
+  shared_ptr<IdentityCertificate> cert;
+
+  if (certFileName.find("http://") == 0)
+    {
+      std::string host;
+      std::string port;
+      std::string path;
+
+      size_t pos = 7; // offset of "http://"
+      size_t posSlash = certFileName.find("/", pos);
+
+      if (posSlash == std::string::npos)
+        throw HttpException("Request line is not correctly formatted");
+
+      size_t posPort = certFileName.find(":", pos);
+
+      if (posPort != std::string::npos && posPort < posSlash) // port is specified
+        {
+          port = certFileName.substr(posPort + 1, posSlash - posPort - 1);
+          host = certFileName.substr(pos, posPort - pos);
+        }
+      else
+        {
+          port = "80";
+          host = certFileName.substr(pos, posSlash - pos);
+        }
+
+      path = certFileName.substr(posSlash, certFileName.size () - posSlash);
+
+      cert = getCertificateHttp(host, port, path);
+    }
+  else
+    {
+      cert = getIdentityCertificate(certFileName);
+    }
+
+  if (!static_cast<bool>(cert))
+    return 1;
+
+  KeyChain keyChain;
+
+  if (isSystemDefault)
+    {
+      keyChain.addCertificateAsIdentityDefault(*cert);
+      Name keyName = cert->getPublicKeyName();
+      Name identity = keyName.getSubName(0, keyName.size()-1);
+      keyChain.setDefaultIdentity(identity);
+    }
+  else if (isIdentityDefault)
+    {
+      keyChain.addCertificateAsIdentityDefault(*cert);
+    }
+  else if (isKeyDefault)
+    {
+      keyChain.addCertificateAsKeyDefault(*cert);
+    }
+  else
+    {
+      keyChain.addCertificate(*cert);
+    }
+
+  std::cerr << "OK: certificate with name ["
+            << cert->getName().toUri()
+            << "] has been successfully installed"
+            << std::endl;
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_CERT_INSTALL_HPP
diff --git a/tools/ndnsec/cert-revoke.hpp b/tools/ndnsec/cert-revoke.hpp
new file mode 100644
index 0000000..7056ca6
--- /dev/null
+++ b/tools/ndnsec/cert-revoke.hpp
@@ -0,0 +1,191 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_CERT_REVOKE_HPP
+#define NDN_TOOLS_NDNSEC_CERT_REVOKE_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_cert_revoke(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  KeyChain keyChain;
+
+  std::string requestFile("-");
+  Name signId = keyChain.getDefaultIdentity();
+  bool hasSignId = false;
+  Name certPrefix = KeyChain::DEFAULT_PREFIX;
+
+  po::options_description description("General Usage\n  ndnsec cert-revoke [-h] request\n"
+                                      "General options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("sign-id,s",     po::value<Name>(&signId),
+                      "signing identity (default: use the same as in the revoked certificate)")
+    ("cert-prefix,p", po::value<Name>(&certPrefix),
+                      "cert prefix, which is the part of certificate name before "
+                      "KEY component (default: use the same as in the revoked certificate)")
+    ("request,r",     po::value<std::string>(&requestFile)->default_value("-"),
+                      "request file name, - for stdin")
+    ;
+
+  po::positional_options_description p;
+  p.add("request", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  hasSignId = (vm.count("sign-id") != 0);
+
+  if (vm.count("request") == 0)
+    {
+      std::cerr << "request file must be specified" << std::endl;
+      return 1;
+    }
+
+  shared_ptr<IdentityCertificate> revokedCertificate
+    = getIdentityCertificate(requestFile);
+
+  if (!static_cast<bool>(revokedCertificate))
+    {
+      std::cerr << "ERROR: input error" << std::endl;
+      return 1;
+    }
+
+  Block wire;
+
+  try
+    {
+      Name keyName;
+
+      if (hasSignId) {
+        keyName = keyChain.getDefaultKeyNameForIdentity(signId);
+      }
+      else {
+        const Signature& signature = revokedCertificate->getSignature();
+        if (!signature.hasKeyLocator() ||
+            signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name)
+          {
+            std::cerr << "ERROR: Invalid certificate to revoke" << std::endl;
+            return 1;
+          }
+
+        keyName = IdentityCertificate::certificateNameToPublicKeyName(
+                    signature.getKeyLocator().getName());
+      }
+
+      Name certName;
+      if (certPrefix == KeyChain::DEFAULT_PREFIX) {
+        certName = revokedCertificate->getName().getPrefix(-1);
+      }
+      else {
+        Name revokedKeyName = revokedCertificate->getPublicKeyName();
+
+        if (certPrefix.isPrefixOf(revokedKeyName) && certPrefix != revokedKeyName) {
+          certName.append(certPrefix)
+            .append("KEY")
+            .append(revokedKeyName.getSubName(certPrefix.size()))
+            .append("ID-CERT");
+        }
+        else {
+          std::cerr << "ERROR: certificate prefix does not match the revoked certificate"
+                    << std::endl;
+          return 1;
+        }
+      }
+      certName
+        .appendVersion()
+        .append("REVOKED");
+
+      Data revocationCert;
+      revocationCert.setName(certName);
+
+      if (keyChain.doesPublicKeyExist(keyName))
+        {
+          Name signingCertificateName = keyChain.getDefaultCertificateNameForKey(keyName);
+          keyChain.sign(revocationCert, signingCertificateName);
+        }
+      else
+        {
+          std::cerr << "ERROR: Cannot find the signing key!" << std::endl;
+          return 1;
+        }
+
+      wire = revocationCert.wireEncode();
+    }
+  catch (Signature::Error& e)
+    {
+      std::cerr << "ERROR: No valid signature!" << std::endl;
+      return 1;
+    }
+  catch (KeyLocator::Error& e)
+    {
+      std::cerr << "ERROR: No valid KeyLocator!" << std::endl;
+      return 1;
+    }
+  catch (IdentityCertificate::Error& e)
+    {
+      std::cerr << "ERROR: Cannot determine the signing key!" << std::endl;
+      return 1;
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: Incomplete or corrupted PIB (" << e.what() << ")" << std::endl;
+      return 1;
+    }
+
+  try
+    {
+      using namespace CryptoPP;
+      StringSource ss(wire.wire(), wire.size(), true,
+                      new Base64Encoder(new FileSink(std::cout), true, 64));
+    }
+  catch (const CryptoPP::Exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_CERT_REVOKE_HPP
diff --git a/tools/ndnsec/delete.hpp b/tools/ndnsec/delete.hpp
new file mode 100644
index 0000000..629440f
--- /dev/null
+++ b/tools/ndnsec/delete.hpp
@@ -0,0 +1,111 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_DELETE_HPP
+#define NDN_TOOLS_NDNSEC_DELETE_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_delete(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  // bool deleteId = true;
+  bool isDeleteKey = false;
+  bool isDeleteCert = false;
+  std::string name;
+
+  po::options_description description("General Usage\n  ndnsec delete [-h] [-k|c] name\nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("delete-key,k", "(Optional) delete a key if specified.")
+    ("delete-key2,K", "(Optional) delete a key if specified.")
+    ("delete-cert,c", "(Optional) delete a certificate if specified.")
+    ("delete-cert2,C", "(Optional) delete a certificate if specified.")
+    ("name,n", po::value<std::string>(&name), "By default, it refers to an identity."
+     "If -k is specified, it refers to a key."
+     "If -c is specified, it refers to a certificate.");
+    ;
+
+  po::positional_options_description p;
+  p.add("name", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;;
+      return 0;
+    }
+
+  if (vm.count("name") == 0)
+    {
+      std::cerr << "ERROR: name must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0)
+    {
+      isDeleteCert = true;
+      // deleteId = false;
+    }
+  else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0)
+    {
+      isDeleteKey = true;
+      // deleteId = false;
+    }
+
+  KeyChain keyChain;
+
+  if (isDeleteCert)
+    {
+      keyChain.deleteCertificate(name);
+    }
+  else if (isDeleteKey)
+    {
+      keyChain.deleteKey(name);
+    }
+  else
+    {
+      keyChain.deleteIdentity(name);
+    }
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_DELETE_HPP
diff --git a/tools/ndnsec/dsk-gen.hpp b/tools/ndnsec/dsk-gen.hpp
new file mode 100644
index 0000000..c07afab
--- /dev/null
+++ b/tools/ndnsec/dsk-gen.hpp
@@ -0,0 +1,184 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_DSK_GEN_HPP
+#define NDN_TOOLS_NDNSEC_DSK_GEN_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_dsk_gen(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string identityName;
+  char keyType = 'r';
+
+  po::options_description description("General Usage\n"
+                                      "  ndnsec dsk-gen [-h] [-t keyType] identity\n"
+                                      "General options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("identity,i", po::value<std::string>(&identityName),
+     "identity name, for example, /ndn/ucla.edu/alice")
+    ("type,t", po::value<char>(&keyType)->default_value('r'),
+     "optional, key type, r for RSA key (default), e for ECDSA key.")
+    // ("size,s", po::value<int>(&keySize)->default_value(2048),
+    //  "optional, key size, 2048 (default)")
+    ;
+
+  po::positional_options_description p;
+  p.add("identity", 1);
+
+  po::variables_map vm;
+  try {
+    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cerr << description << std::endl;
+    return 0;
+  }
+
+  if (vm.count("identity") == 0) {
+    std::cerr << "identity must be specified" << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  shared_ptr<IdentityCertificate> kskCert;
+  Name signingCertName;
+
+  KeyChain keyChain;
+
+  try {
+    Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
+    bool isDefaultDsk = false;
+    std::string keyUsageTag = defaultCertName.get(-3).toUri().substr(0,4);
+    if (keyUsageTag == "ksk-")
+      isDefaultDsk = false;
+    else if (keyUsageTag == "dsk-")
+      isDefaultDsk = true;
+    else {
+      std::cerr << "ERROR: Unknown key usage tag: " << keyUsageTag << std::endl;
+      return 1;
+    }
+
+    if (isDefaultDsk) {
+      shared_ptr<IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
+
+      if (static_cast<bool>(dskCert)) {
+        SignatureSha256WithRsa sha256sig(dskCert->getSignature());
+
+        Name keyLocatorName = sha256sig.getKeyLocator().getName();
+
+        Name kskName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+        Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
+        signingCertName = kskCertName;
+        kskCert = keyChain.getCertificate(kskCertName);
+      }
+      else {
+        std::cerr << "ERROR: The default certificate is missing." << std::endl;
+        return 1;
+      }
+    }
+    else {
+      signingCertName = defaultCertName;
+      kskCert = keyChain.getCertificate(defaultCertName);
+    }
+
+    if (!static_cast<bool>(kskCert)) {
+      std::cerr << "ERROR: KSK certificate is missing." << std::endl;
+      return 1;
+    }
+
+    Name newKeyName;
+    switch (keyType) {
+    case 'r':
+      {
+        RsaKeyParams params;
+        newKeyName = keyChain.generateRsaKeyPair(Name(identityName), false, params.getKeySize());
+        if (0 == newKeyName.size()) {
+          std::cerr << "ERROR: Fail to generate RSA key!" << std::endl;
+          return 1;
+        }
+        break;
+      }
+    case 'e':
+      {
+        EcdsaKeyParams params;
+        newKeyName = keyChain.generateEcdsaKeyPair(Name(identityName), false, params.getKeySize());
+        if (0 == newKeyName.size()) {
+          std::cerr << "ERROR: Fail to generate ECDSA key!" << std::endl;
+          return 1;
+        }
+        break;
+      }
+    default:
+      std::cerr << "ERROR: Unrecongized key type" << "\n";
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+    Name certName = newKeyName.getPrefix(-1);
+    certName.append("KEY")
+      .append(newKeyName.get(-1))
+      .append("ID-CERT")
+      .appendVersion();
+
+    shared_ptr<IdentityCertificate> certificate =
+      keyChain.prepareUnsignedIdentityCertificate(newKeyName,
+                                                  Name(identityName),
+                                                  kskCert->getNotBefore(),
+                                                  kskCert->getNotAfter(),
+                                                  kskCert->getSubjectDescriptionList());
+
+    if (static_cast<bool>(certificate))
+      certificate->encode();
+    else {
+      std::cerr << "ERROR: Cannot format the certificate of the requested dsk." << "\n";
+      return 1;
+    }
+
+    keyChain.sign(*certificate, signingCertName);
+
+    keyChain.addCertificateAsIdentityDefault(*certificate);
+
+    std::cerr << "OK: dsk certificate with name [" << certificate->getName() <<
+      "] has been successfully installed\n";
+    return 0;
+  }
+  catch (std::runtime_error& e) {
+    std::cerr << "ERROR: other runtime errors: " << e.what() << "\n";
+    return 1;
+  }
+}
+
+#endif // NDN_TOOLS_NDNSEC_DSK_GEN_HPP
diff --git a/tools/ndnsec/export.hpp b/tools/ndnsec/export.hpp
new file mode 100644
index 0000000..aab60ae
--- /dev/null
+++ b/tools/ndnsec/export.hpp
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_EXPORT_HPP
+#define NDN_TOOLS_NDNSEC_EXPORT_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_export(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string identityStr;
+  std::string output;
+  std::string exportPassword;
+  bool isPrivateExport = false;
+
+  po::options_description description("General Usage\n  ndnsec export [-h] [-o output] [-p] identity \nGeneral options");
+  description.add_options()
+    ("help,h", "Produce help message")
+    ("output,o", po::value<std::string>(&output), "(Optional) output file, stdout if not specified")
+    ("private,p", "export info contains private key")
+    ("identity,i", po::value<std::string>(&identityStr), "Identity to export")
+    ;
+
+  po::positional_options_description p;
+  p.add("identity", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("identity") == 0)
+    {
+      std::cerr << "ERROR: identity must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("private") != 0)
+    isPrivateExport = true;
+
+  if (vm.count("output") == 0)
+    output = "-";
+
+  Name identity(identityStr);
+  if (!isPrivateExport)
+    {
+      KeyChain keyChain;
+      shared_ptr<IdentityCertificate> cert
+        = keyChain.getCertificate(keyChain.getDefaultCertificateNameForIdentity(identity));
+
+      if (output == "-")
+        io::save(*cert, std::cout);
+      else
+        io::save(*cert, output);
+
+      return 0;
+    }
+  else
+    {
+      Block wire;
+      try
+        {
+          KeyChain keyChain;
+
+          int count = 3;
+          while (!getPassword(exportPassword, "Passphrase for the private key: "))
+            {
+              count--;
+              if (count <= 0)
+                {
+                  std::cerr << "ERROR: invalid password" << std::endl;
+                  memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+                  return 1;
+                }
+            }
+          shared_ptr<SecuredBag> securedBag = keyChain.exportIdentity(identity, exportPassword);
+          memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+
+          if (output == "-")
+            io::save(*securedBag, std::cout);
+          else
+            io::save(*securedBag, output);
+
+          return 0;
+        }
+      catch (const std::runtime_error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+          return 1;
+        }
+    }
+}
+
+#endif // NDN_TOOLS_NDNSEC_EXPORT_HPP
diff --git a/tools/ndnsec/get-default.hpp b/tools/ndnsec/get-default.hpp
new file mode 100644
index 0000000..9af33cb
--- /dev/null
+++ b/tools/ndnsec/get-default.hpp
@@ -0,0 +1,148 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_GET_DEFAULT_HPP
+#define NDN_TOOLS_NDNSEC_GET_DEFAULT_HPP
+
+#include "util.hpp"
+
+
+int
+ndnsec_get_default(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  bool isGetDefaultId = true;
+  bool isGetDefaultKey = false;
+  bool isGetDefaultCert = false;
+  bool isQuiet = false;
+  std::string identityString;
+  std::string keyName;
+
+  po::options_description description("General Usage\n  ndnsec get-default [-h] [-k|c] [-i identity|-K key] [-q]\nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("default_key,k", "get default key")
+    ("default_cert,c", "get default certificate")
+    ("identity,i", po::value<std::string>(&identityString), "target identity")
+    ("key,K", po::value<std::string>(&keyName), "target key")
+    ("quiet,q", "don't output trailing newline")
+    ;
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::parse_command_line(argc, argv, description), vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;;
+      return 0;
+    }
+
+  if (vm.count("default_cert") != 0)
+    {
+      isGetDefaultCert = true;
+      isGetDefaultId = false;
+    }
+  else if (vm.count("default_key") != 0)
+    {
+      isGetDefaultKey = true;
+      isGetDefaultId = false;
+    }
+
+  if (vm.count("quiet") != 0)
+    {
+      isQuiet = true;
+    }
+
+  KeyChain keyChain;
+
+  if (vm.count("key") != 0)
+    {
+      Name keyNdnName(keyName);
+      if (isGetDefaultCert)
+        {
+          std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName);
+          if (!isQuiet) std::cout << std::endl;
+          return 0;
+        }
+      return 1;
+    }
+  else if (vm.count("identity") != 0)
+    {
+      Name identity(identityString);
+
+      if (isGetDefaultKey)
+        {
+          std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+          if (!isQuiet)
+            std::cout << std::endl;
+
+          return 0;
+        }
+      if (isGetDefaultCert)
+        {
+          std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+          if (!isQuiet)
+            std::cout << std::endl;
+
+          return 0;
+        }
+      return 1;
+    }
+  else
+    {
+      Name identity = keyChain.getDefaultIdentity();
+      if (isGetDefaultId)
+        {
+          std::cout << identity;
+          if (!isQuiet) std::cout << std::endl;
+          return 0;
+        }
+      if (isGetDefaultKey)
+        {
+          std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+          if (!isQuiet) std::cout << std::endl;
+          return 0;
+        }
+      if (isGetDefaultCert)
+        {
+          std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+          if (!isQuiet) std::cout << std::endl;
+          return 0;
+        }
+      return 1;
+    }
+}
+
+#endif // NDN_TOOLS_NDNSEC_GET_DEFAULT_HPP
diff --git a/tools/ndnsec/import.hpp b/tools/ndnsec/import.hpp
new file mode 100644
index 0000000..f8bfedf
--- /dev/null
+++ b/tools/ndnsec/import.hpp
@@ -0,0 +1,115 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_IMPORT_HPP
+#define NDN_TOOLS_NDNSEC_IMPORT_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_import(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string input("-");
+  std::string importPassword;
+  bool isPrivateImport = false;
+
+  po::options_description description("General Usage\n  ndnsec import [-h] [-p] input \nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("private,p", "import info contains private key")
+    ("input,i", po::value<std::string>(&input), "input source, stdin if -")
+    ;
+
+  po::positional_options_description p;
+  p.add("input", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("private") != 0)
+    isPrivateImport = true;
+
+  if (!isPrivateImport)
+    {
+      std::cerr << "You are trying to import certificate!\n"
+                << "Please use ndnsec cert-install!" << std::endl;
+      return 1;
+    }
+  else
+    {
+      try
+        {
+          KeyChain keyChain;
+
+          shared_ptr<SecuredBag> securedBag;
+          if (input == "-")
+            securedBag = io::load<SecuredBag>(std::cin);
+          else
+            securedBag = io::load<SecuredBag>(input);
+
+          int count = 3;
+          while (!getPassword(importPassword, "Passphrase for the private key: "))
+            {
+              count--;
+              if (count <= 0)
+                {
+                  std::cerr << "ERROR: Fail to get password" << std::endl;
+                  memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+                  return 1;
+                }
+            }
+          keyChain.importIdentity(*securedBag, importPassword);
+          memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+        }
+      catch (const std::runtime_error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+          return 1;
+        }
+
+      return 0;
+    }
+}
+
+#endif // NDN_TOOLS_NDNSEC_IMPORT_HPP
diff --git a/tools/ndnsec/key-gen.hpp b/tools/ndnsec/key-gen.hpp
new file mode 100644
index 0000000..1633855
--- /dev/null
+++ b/tools/ndnsec/key-gen.hpp
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_KEY_GEN_HPP
+#define NDN_TOOLS_NDNSEC_KEY_GEN_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_key_gen(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string identityName;
+  bool isDefault = true;
+  char keyType = 'r';
+  std::string outputFilename;
+
+  po::options_description description("General Usage\n"
+                                      "  ndnsec key-gen [-h] [-n] identity\n"
+                                      "General options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("identity,i", po::value<std::string>(&identityName),
+     "identity name, for example, /ndn/edu/ucla/alice")
+    ("not_default,n",
+     "optional, if not specified, the target identity will be set as "
+     "the default identity of the system")
+    ("dsk,d", "generate Data-Signing-Key (DSK) instead of the default Key-Signing-Key (KSK)")
+    ("type,t", po::value<char>(&keyType)->default_value('r'),
+    "optional, key type, r for RSA key (default), e for ECDSA key")
+    // ("size,s", po::value<int>(&keySize)->default_value(2048),
+    // "optional, key size, 2048 (default)")
+    ;
+
+  po::positional_options_description p;
+  p.add("identity", 1);
+
+  po::variables_map vm;
+  try {
+    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+              vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cerr << description << std::endl;
+    return 0;
+  }
+
+  if (vm.count("identity") == 0) {
+    std::cerr << "identity must be specified" << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  if (vm.count("not_default") != 0)
+    isDefault = false;
+
+  bool isKsk = (vm.count("dsk") == 0);
+
+  KeyChain keyChain;
+  Name keyName;
+
+  try {
+    switch (keyType) {
+    case 'r':
+      keyName = keyChain.generateRsaKeyPair(Name(identityName), isKsk, RsaKeyParams().getKeySize());
+      break;
+    case 'e':
+      keyName = keyChain.generateEcdsaKeyPair(Name(identityName), isKsk,
+                                              EcdsaKeyParams().getKeySize());
+      break;
+    default:
+      std::cerr << "Unrecongized key type" << "\n";
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+    if (0 == keyName.size()) {
+      std::cerr << "Error: failed to generate key" << "\n";
+      return 1;
+    }
+
+    keyChain.setDefaultKeyNameForIdentity(keyName);
+
+    shared_ptr<IdentityCertificate> identityCert = keyChain.selfSign(keyName);
+
+    if (isDefault)
+      keyChain.setDefaultIdentity(Name(identityName));
+
+    io::save(*identityCert, std::cout);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "Error: " << e.what() << std::endl;
+  }
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_KEY_GEN_HPP
diff --git a/tools/ndnsec/list.hpp b/tools/ndnsec/list.hpp
new file mode 100644
index 0000000..f40ab5e
--- /dev/null
+++ b/tools/ndnsec/list.hpp
@@ -0,0 +1,174 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_LIST_HPP
+#define NDN_TOOLS_NDNSEC_LIST_HPP
+
+#include "util.hpp"
+
+void
+printCertificate(ndn::KeyChain& keyChain,
+                 const ndn::Name& certName,
+                 bool isDefault,
+                 int verboseLevel)
+{
+  if (isDefault)
+    std::cout << "       +->* ";
+  else
+    std::cout << "       +->  ";
+
+  std::cout << certName << std::endl;
+
+  if (verboseLevel >= 3) {
+    ndn::shared_ptr<ndn::IdentityCertificate> certificate = keyChain.getCertificate(certName);
+    if (static_cast<bool>(certificate))
+      certificate->printCertificate(std::cout, "            ");
+  }
+}
+
+void
+printKey(ndn::KeyChain& keyChain,
+         const ndn::Name& keyName,
+         bool isDefault,
+         int verboseLevel)
+{
+  if (isDefault)
+    std::cout << "  +->* ";
+  else
+    std::cout << "  +->  ";
+
+  std::cout << keyName << std::endl;
+
+  if (verboseLevel >= 2) {
+    std::vector<ndn::Name> defaultCertificates;
+    keyChain.getAllCertificateNamesOfKey(keyName, defaultCertificates, true);
+
+    for (const auto& certName : defaultCertificates)
+      printCertificate(keyChain, certName, true, verboseLevel);
+
+    std::vector<ndn::Name> otherCertificates;
+    keyChain.getAllCertificateNamesOfKey(keyName, otherCertificates, false);
+    for (const auto& certName : otherCertificates)
+      printCertificate(keyChain, certName, false, verboseLevel);
+  }
+}
+
+void
+printIdentity(ndn::KeyChain& keyChain,
+              const ndn::Name& identity,
+              bool isDefault,
+              int verboseLevel)
+{
+  if (isDefault)
+    std::cout << "* ";
+  else
+    std::cout << "  ";
+
+  std::cout << identity << std::endl;
+
+  if (verboseLevel >= 1) {
+    std::vector<ndn::Name> defaultKeys;
+    keyChain.getAllKeyNamesOfIdentity(identity, defaultKeys, true);
+    for (const auto& keyName : defaultKeys)
+      printKey(keyChain, keyName, true, verboseLevel);
+
+    std::vector<ndn::Name> otherKeys;
+    keyChain.getAllKeyNamesOfIdentity(identity, otherKeys, false);
+    for (const auto& keyName : otherKeys) {
+      printKey(keyChain, keyName, false, verboseLevel);
+    }
+
+    std::cout << std::endl;
+  }
+}
+
+int
+ndnsec_list(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  int verboseLevel = 0; // 0 print identity only
+                        // 1 print key name
+                        // 2 print cert name
+                        // 3 print cert content
+
+  po::options_description options("General Usage\n  ndnsec list [-h] [-k|c]\nGeneral options");
+  options.add_options()
+    ("help,h",    "produce help message")
+    ("key,k",     "granularity: key")
+    ("cert,c",    "granularity: certificate")
+    ("verbose,v", accumulator<int>(&verboseLevel),
+                  "verbose mode: -v is equivalent to -k, -vv is equivalent to -c")
+    ;
+
+  po::options_description oldOptions;
+  oldOptions.add_options()
+    ("key2,K",         "granularity: key")
+    ("cert2,C",        "granularity: certificate");
+
+  po::options_description allOptions;
+  allOptions.add(options).add(oldOptions);
+
+  po::variables_map vm;
+  try {
+    po::store(po::parse_command_line(argc, argv, allOptions), vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << options << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cerr << options << std::endl;;
+    return 0;
+  }
+
+  int tmpVerboseLevel = 0;
+  if (vm.count("cert") != 0 || vm.count("cert2") != 0)
+    tmpVerboseLevel = 2;
+  else if(vm.count("key") != 0 || vm.count("key2") != 0)
+    tmpVerboseLevel = 1;
+
+  verboseLevel = std::max(verboseLevel, tmpVerboseLevel);
+
+  KeyChain keyChain;
+
+  std::vector<Name> defaultIdentities;
+  keyChain.getAllIdentities(defaultIdentities, true);
+  for (const auto& identity : defaultIdentities) {
+    printIdentity(keyChain, identity, true, verboseLevel);
+  }
+
+  std::vector<Name> otherIdentities;
+  keyChain.getAllIdentities(otherIdentities, false);
+  for (const auto& identity : otherIdentities) {
+    printIdentity(keyChain, identity, false, verboseLevel);
+  }
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_LIST_HPP
diff --git a/tools/ndnsec/main.cpp b/tools/ndnsec/main.cpp
new file mode 100644
index 0000000..ae81752
--- /dev/null
+++ b/tools/ndnsec/main.cpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#include "version.hpp"
+
+#include "util.hpp"
+#include "list.hpp"
+#include "get-default.hpp"
+#include "set-default.hpp"
+#include "key-gen.hpp"
+#include "dsk-gen.hpp"
+#include "sign-req.hpp"
+#include "cert-gen.hpp"
+#include "cert-revoke.hpp"
+#include "cert-dump.hpp"
+#include "cert-install.hpp"
+#include "export.hpp"
+#include "import.hpp"
+#include "delete.hpp"
+#include "sig-verify.hpp"
+#include "set-acl.hpp"
+#include "unlock-tpm.hpp"
+#include "op-tool.hpp"
+
+using namespace ndn;
+
+std::string ndnsec_helper("\
+  help         Show all commands.\n\
+  version      Show version and exit.\n\
+  list         Display information in PublicInfo.\n\
+  get-default  Get default setting info.\n\
+  set-default  Configure default setting.\n\
+  key-gen      Generate a Key-Signing-Key for an identity.\n\
+  dsk-gen      Generate a Data-Signing-Key for an identity.\n\
+  sign-req     Generate a certificate signing request.\n\
+  cert-gen     Generate an identity certificate.\n\
+  cert-revoke  Revoke an identity certificate.\n\
+  cert-dump    Dump a certificate from PublicInfo.\n\
+  cert-install Install a certificate into PublicInfo.\n\
+  delete       Delete identity/key/certificate.\n\
+  export       Export an identity package.\n\
+  import       Import an identity package.\n\
+  sig-verify   Verify the signature of a Data packet.\n\
+  set-acl      Configure ACL of a private key.\n\
+  unlock-tpm   Unlock Tpm.\n\
+  op-tool      Operator tool.\n\
+");
+
+int
+main(int argc, char** argv)
+{
+  if (argc < 2)
+    {
+      std::cerr << ndnsec_helper << std::endl;
+      return 1;
+    }
+
+  std::string command(argv[1]);
+
+  try
+    {
+      if (command == "help")              { std::cout << ndnsec_helper << std::endl; }
+      else if (command == "version")      { std::cout << NDN_CXX_VERSION_BUILD_STRING
+                                                      << std::endl; }
+      else if (command == "list")         { return ndnsec_list(argc - 1, argv + 1); }
+      else if (command == "get-default")  { return ndnsec_get_default(argc - 1, argv + 1); }
+      else if (command == "set-default")  { return ndnsec_set_default(argc - 1, argv + 1); }
+      else if (command == "key-gen")      { return ndnsec_key_gen(argc - 1, argv + 1); }
+      else if (command == "dsk-gen")      { return ndnsec_dsk_gen(argc - 1, argv + 1); }
+      else if (command == "sign-req")     { return ndnsec_sign_req(argc - 1, argv + 1); }
+      else if (command == "cert-gen")     { return ndnsec_cert_gen(argc - 1, argv + 1); }
+      else if (command == "cert-revoke")  { return ndnsec_cert_revoke(argc - 1, argv + 1); }
+      else if (command == "cert-dump")    { return ndnsec_cert_dump(argc - 1, argv + 1); }
+      else if (command == "cert-install") { return ndnsec_cert_install(argc - 1, argv + 1); }
+      else if (command == "delete")       { return ndnsec_delete(argc - 1, argv + 1); }
+      else if (command == "export")       { return ndnsec_export(argc - 1, argv + 1); }
+      else if (command == "import")       { return ndnsec_import(argc - 1, argv + 1); }
+      else if (command == "sig-verify")   { return ndnsec_sig_verify(argc - 1, argv + 1); }
+      else if (command == "set-acl")      { return ndnsec_set_acl(argc - 1, argv + 1); }
+      else if (command == "unlock-tpm")   { return ndnsec_unlock_tpm(argc - 1, argv + 1); }
+      else if (command == "op-tool")      { return ndnsec_op_tool(argc - 1, argv + 1); }
+      else {
+        std::cerr << ndnsec_helper << std::endl;
+        return 1;
+      }
+    }
+  catch (const std::runtime_error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/tools/ndnsec/op-tool.hpp b/tools/ndnsec/op-tool.hpp
new file mode 100644
index 0000000..d04d886
--- /dev/null
+++ b/tools/ndnsec/op-tool.hpp
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_OP_TOOL_HPP
+#define NDN_TOOLS_NDNSEC_OP_TOOL_HPP
+
+#include "util.hpp"
+
+using namespace std;
+
+int
+ndnsec_op_tool(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string command;
+
+  po::options_description description("General options");
+  description.add_options()
+    ("help,h", "produce this help message")
+    ("command", po::value<std::string>(&command), "command")
+    ;
+
+  po::positional_options_description p;
+  p.add("command", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return -1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("command") == 0)
+    {
+      std::cerr << "command must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (command == "sign") // the content to be signed from stdin
+    {
+      KeyChain keyChain;
+
+      Buffer dataToSign((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
+
+      Signature signature = keyChain.sign(dataToSign.buf(), dataToSign.size(),
+                                          keyChain.getDefaultCertificateName());
+
+      if (signature.getValue().value_size() == 0)
+        {
+          std::cerr << "Error signing with default key" << std::endl;
+          return -1;
+        }
+
+      std::cout.write(reinterpret_cast<const char*>(signature.getValue().wire()),
+                      signature.getValue().size());
+    }
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_OP_TOOL_HPP
diff --git a/tools/ndnsec/set-acl.hpp b/tools/ndnsec/set-acl.hpp
new file mode 100644
index 0000000..d373223
--- /dev/null
+++ b/tools/ndnsec/set-acl.hpp
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_SET_ACL_HPP
+#define NDN_TOOLS_NDNSEC_SET_ACL_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_set_acl(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string keyName;
+  std::string appPath;
+
+  po::options_description description("General Usage\n  ndnsec set-acl [-h] keyName appPath \nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("keyName,k", po::value<std::string>(&keyName), "Key name.")
+    ("appPath,p", po::value<std::string>(&appPath), "Application path.")
+    ;
+
+  po::positional_options_description p;
+  p.add("keyName", 1);
+  p.add("appPath", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("keyName") == 0)
+    {
+      std::cerr << "ERROR: keyName is required!" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("appPath") == 0)
+    {
+      std::cerr << "ERROR: appPath is required!" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  KeyChain keyChain;
+  keyChain.addAppToAcl(keyName, KEY_CLASS_PRIVATE, appPath, ACL_TYPE_PRIVATE);
+
+  return 0;
+}
+
+#endif // NDN_TOOLS_NDNSEC_SET_ACL_HPP
diff --git a/tools/ndnsec/set-default.hpp b/tools/ndnsec/set-default.hpp
new file mode 100644
index 0000000..765471d
--- /dev/null
+++ b/tools/ndnsec/set-default.hpp
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_SET_DEFAULT_HPP
+#define NDN_TOOLS_NDNSEC_SET_DEFAULT_HPP
+
+int
+ndnsec_set_default(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string certFileName;
+  bool isSetDefaultId = true;
+  bool isSetDefaultKey = false;
+  bool isSetDefaultCert = false;
+  std::string name;
+
+  po::options_description description("General Usage\n  ndnsec set-default [-h] [-k|c] name\nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("default_key,k", "set default key of the identity")
+    ("default_cert,c", "set default certificate of the key")
+    ("name,n", po::value<std::string>(&name), "the name to set")
+    ;
+
+  po::positional_options_description p;
+  p.add("name", 1);
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("name") == 0)
+    {
+      std::cerr << "ERROR: name is required!" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  KeyChain keyChain;
+
+  if (vm.count("default_key") != 0)
+    {
+      isSetDefaultKey = true;
+      isSetDefaultId = false;
+    }
+  else if (vm.count("default_cert") != 0)
+    {
+      isSetDefaultCert = true;
+      isSetDefaultId = false;
+    }
+
+  if (isSetDefaultId)
+    {
+      Name idName(name);
+      keyChain.setDefaultIdentity(idName);
+      return 0;
+    }
+  if (isSetDefaultKey)
+    {
+      Name keyName(name);
+      keyChain.setDefaultKeyNameForIdentity(keyName);
+      return 0;
+    }
+
+  if (isSetDefaultCert)
+    {
+      keyChain.setDefaultCertificateNameForKey(name);
+      return 0;
+    }
+
+  return 1;
+}
+#endif // NDN_TOOLS_NDNSEC_SET_DEFAULT_HPP
diff --git a/tools/ndnsec/sig-verify.hpp b/tools/ndnsec/sig-verify.hpp
new file mode 100644
index 0000000..e49387a
--- /dev/null
+++ b/tools/ndnsec/sig-verify.hpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_SIG_VERIFY_HPP
+#define NDN_TOOLS_NDNSEC_SIG_VERIFY_HPP
+
+#include "util.hpp"
+
+// using namespace ndn;
+// namespace po = boost::program_options;
+
+// shared_ptr<IdentityCertificate>
+// getCertificate(const std::string& certString)
+// {
+//   std::string decoded;
+//   CryptoPP::StringSource ss2(reinterpret_cast<const unsigned char *>(certString.c_str()), certString.size(), true,
+//                              new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
+
+//   Data data;
+//   data.wireDecode(Block(make_shared<Buffer>(decoded.begin(), decoded.end())));
+
+//   shared_ptr<IdentityCertificate> identityCertificate = make_shared<IdentityCertificate>(data);
+
+//   return identityCertificate;
+// }
+
+// bool
+// verifySignature(shared_ptr<IdentityCertificate> certificate, bool isDataPacket)
+// {
+//   throw std::runtime_error("Not supported yet");
+//   // if(isDataPacket)
+//   //   {
+//   //     std::string decoded;
+//   //     CryptoPP::FileSource ss2(cin, true,
+//   //                              new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
+
+//   //     Data data;
+//   //     data.wireDecode(make_shared<Buffer>(decoded.c_str(), decoded.size()));
+//   //     return PolicyManager::verifySignature(data, certificate->getPublicKeyInfo());
+//   //   }
+//   // else
+//   //   {
+//   //     // The first two bytes indicates the boundary of the of the signed data and signature.
+//   //     // for example, if the size of the signed data is 300, then the boundary should be 300, so the first two bytes should be: 0x01 0x2C
+//   //     shared_ptr<Blob> input = shared_ptr<Blob>(new Blob ((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>()));
+//   //     size_t size = input->at(0);
+//   //     size = ((size << 8) + input->at(1));
+
+//   //     Blob signedBlob(input->buf()+2, size);
+//   //     Blob signature(input->buf()+2+size, input->size()-2-size);
+
+//   //     return PolicyManager::verifySignature(signedBlob, signature, certificate->getPublicKeyInfo());
+//   //   }
+// }
+
+int
+ndnsec_sig_verify(int argc, char** argv)
+{
+  std::cerr << "Not supported yet" << std::endl;
+  return 1;
+  // bool isDataPacket = false;
+  // std::string certString;
+
+  // po::options_description desc("General Usage\n  ndn-sig-verify [-h] [-d] certificate\nGeneral options");
+  // desc.add_options()
+  //   ("help,h", "produce help message")
+  //   ("data,d", "if specified, input from stdin will be treated as a Data packet, otherwise binary data")
+  //   ("certificate,c", po::value<std::string>(&certString), "the certificate bits")
+  //   ;
+
+  // po::positional_options_description p;
+  // p.add("certificate", 1);
+
+  // po::variables_map vm;
+  // try
+  //   {
+  //     po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+  //     po::notify(vm);
+  //   }
+  // catch( const std::exception& e)
+  //   {
+  //     std::cerr << e.what() << std::endl;
+  //     std::cerr << desc << std::endl;
+  //     return 1;
+  //   }
+
+  // if (vm.count("help") || vm.count("certificate")==0)
+  //   {
+  //     std::cerr << desc << std::endl;
+  //     return 1;
+  //   }
+  // if (vm.count("data"))
+  //   isDataPacket = true;
+
+  // try
+  //   {
+  //     shared_ptr<IdentityCertificate> certificate = getCertificate(certString);
+  //     bool res = verifySignature(certificate, isDataPacket);
+  //     return (res ? 0 : 1);
+  //   }
+  // catch(const std::exception &e)
+  //   {
+  //     std::cerr << "ERROR: " << e.what() << std::endl;
+  //     return 1;
+  //   }
+}
+
+#endif // NDN_TOOLS_NDNSEC_SIG_VERIFY_HPP
diff --git a/tools/ndnsec/sign-req.hpp b/tools/ndnsec/sign-req.hpp
new file mode 100644
index 0000000..e0db0f3
--- /dev/null
+++ b/tools/ndnsec/sign-req.hpp
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_SIGN_REQ_HPP
+#define NDN_TOOLS_NDNSEC_SIGN_REQ_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_sign_req(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string name;
+  bool isKeyName = false;
+
+  po::options_description description("General Usage\n  ndnsec sign-req [-h] [-k] name\nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("key,k", "optional, if specified, name is keyName (e.g. /ndn/edu/ucla/alice/ksk-123456789), otherwise identity name")
+    ("name,n", po::value<std::string>(&name), "name, for example, /ndn/edu/ucla/alice")
+    ;
+
+  po::positional_options_description p;
+  p.add("name", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
+                vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  if (vm.count("name") == 0)
+    {
+      std::cerr << "ERROR: name must be specified" << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("key") != 0)
+    isKeyName = true;
+
+  shared_ptr<IdentityCertificate> selfSignCert;
+
+  KeyChain keyChain;
+
+  if (isKeyName)
+    selfSignCert = keyChain.selfSign(name);
+  else {
+    Name keyName = keyChain.getDefaultKeyNameForIdentity(name);
+    selfSignCert = keyChain.selfSign(keyName);
+  }
+
+  if (static_cast<bool>(selfSignCert)) {
+    io::save(*selfSignCert, std::cout);
+    return 0;
+  }
+  else {
+    std::cerr << "ERROR: Public key does not exist" << std::endl;
+    return 1;
+  }
+}
+
+#endif // NDN_TOOLS_NDNSEC_SIGN_REQ_HPP
diff --git a/tools/ndnsec/unlock-tpm.hpp b/tools/ndnsec/unlock-tpm.hpp
new file mode 100644
index 0000000..7d2043b
--- /dev/null
+++ b/tools/ndnsec/unlock-tpm.hpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_UNLOCK_TPM_HPP
+#define NDN_TOOLS_NDNSEC_UNLOCK_TPM_HPP
+
+#include "util.hpp"
+
+int
+ndnsec_unlock_tpm(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string keyName;
+
+  po::options_description description("General Usage\n  ndnsec unlock-tpm [-h] \nGeneral options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ;
+
+  po::variables_map vm;
+
+  try
+    {
+      po::store(po::parse_command_line(argc, argv, description), vm);
+      po::notify(vm);
+    }
+  catch (const std::exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      std::cerr << description << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help") != 0)
+    {
+      std::cerr << description << std::endl;
+      return 0;
+    }
+
+  bool isUnlocked = false;
+
+  KeyChain keyChain;
+
+  char* password;
+  password = getpass("Password to unlock the TPM: ");
+  isUnlocked = keyChain.unlockTpm(password, strlen(password), true);
+  memset(password, 0, strlen(password));
+
+  if (isUnlocked)
+    {
+      std::cerr << "OK: TPM is unlocked" << std::endl;
+      return 0;
+    }
+  else
+    {
+      std::cerr << "ERROR: TPM is still locked" << std::endl;
+      return 1;
+    }
+}
+
+#endif // NDN_TOOLS_NDNSEC_UNLOCK_TPM_HPP
diff --git a/tools/ndnsec/util.hpp b/tools/ndnsec/util.hpp
new file mode 100644
index 0000000..56cbaa6
--- /dev/null
+++ b/tools/ndnsec/util.hpp
@@ -0,0 +1,225 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ */
+
+#ifndef NDN_TOOLS_NDNSEC_UTIL_HPP
+#define NDN_TOOLS_NDNSEC_UTIL_HPP
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cstring>
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/asio.hpp>
+#include <boost/exception/all.hpp>
+
+
+#include "security/cryptopp.hpp"
+
+#include "security/key-chain.hpp"
+#include "util/io.hpp"
+
+bool
+getPassword(std::string& password, const std::string& prompt)
+{
+  bool isReady = false;
+
+  char* pw0 = 0;
+
+  pw0 = getpass(prompt.c_str());
+  if (!pw0)
+    return false;
+  std::string password1 = pw0;
+  memset(pw0, 0, strlen(pw0));
+
+  pw0 = getpass("Confirm:");
+  if (!pw0)
+    {
+      char* pw1 = const_cast<char*>(password1.c_str());
+      memset(pw1, 0, password1.size());
+      return false;
+    }
+
+  if (!password1.compare(pw0))
+    {
+      isReady = true;
+      password.swap(password1);
+    }
+
+  char* pw1 = const_cast<char*>(password1.c_str());
+  memset(pw1, 0, password1.size());
+  memset(pw0, 0, strlen(pw0));
+
+  if (password.empty())
+    return false;
+
+  return isReady;
+}
+
+ndn::shared_ptr<ndn::IdentityCertificate>
+getIdentityCertificate(const std::string& fileName)
+{
+
+  if (fileName == "-")
+    return ndn::io::load<ndn::IdentityCertificate>(std::cin);
+  else
+    return ndn::io::load<ndn::IdentityCertificate>(fileName);
+}
+
+
+/**
+ * @brief An accumulating option value to handle multiple incrementing options.
+ *
+ * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
+ * @sa http://benjaminwolsey.de/node/103
+ */
+template<typename T>
+class AccumulatorType : public boost::program_options::value_semantic
+{
+public:
+  explicit
+  AccumulatorType(T* store)
+    : m_store(store)
+    , m_interval(1)
+    , m_default(0)
+  {
+  }
+
+  virtual
+  ~AccumulatorType()
+  {
+  }
+
+  /// @brief Set the default value for this option.
+  AccumulatorType*
+  setDefaultValue(const T& t)
+  {
+    m_default = t;
+    return this;
+  }
+
+  /**
+   * @brief Set the interval for this option.
+   *
+   * Unlike for program_options::value, this specifies a value
+   * to be applied on each occurrence of the option.
+   */
+  AccumulatorType*
+  setInterval(const T& t) {
+    m_interval = t;
+    return this;
+  }
+
+  virtual std::string
+  name() const
+  {
+    return std::string();
+  }
+
+  // There are no tokens for an AccumulatorType
+  virtual unsigned
+  min_tokens() const
+  {
+    return 0;
+  }
+
+  virtual unsigned
+  max_tokens() const
+  {
+    return 0;
+  }
+
+  // Accumulating from different sources is silly.
+  virtual bool
+  is_composing() const
+  {
+    return false;
+  }
+
+  // Requiring one or more appearances is unlikely.
+  virtual bool
+  is_required() const
+  {
+    return false;
+  }
+
+  /**
+   * @brief Parse options
+   *
+   * Every appearance of the option simply increments the value
+   * There should never be any tokens.
+   */
+  virtual void
+  parse(boost::any& value_store,
+        const std::vector<std::string>& new_tokens,
+        bool utf8) const
+  {
+    if (value_store.empty())
+      value_store = T();
+    boost::any_cast<T&>(value_store) += m_interval;
+  }
+
+  /**
+   * @brief If the option doesn't appear, this is the default value.
+   */
+  virtual bool
+  apply_default(boost::any& value_store) const
+  {
+    value_store = m_default;
+    return true;
+  }
+
+  /**
+   * @brief Notify the user function with the value of the value store.
+   */
+  virtual void
+  notify(const boost::any& value_store) const
+  {
+    const T* val = boost::any_cast<T>(&value_store);
+    if (m_store)
+      *m_store = *val;
+  }
+
+private:
+    T* m_store;
+    T m_interval;
+    T m_default;
+};
+
+template<typename T>
+AccumulatorType<T>* accumulator()
+{
+  return new AccumulatorType<T>(0);
+}
+
+template<typename T>
+AccumulatorType<T>* accumulator(T* store)
+{
+  return new AccumulatorType<T>(store);
+}
+
+#endif // NDN_TOOLS_NDNSEC_UTIL_HPP
