tools: Combine all security tools into one; Add Export/Import/Delete/Unlock/AddACL command

There might be some bugs in the tools combined, but the purpose of this commit is to combine the tools rather than fixing bugs.

Change-Id: I2924067d666eacfc278ebd07e7e178c54a2f7362
diff --git a/tools/ndnsec-cert-dump.hpp b/tools/ndnsec-cert-dump.hpp
new file mode 100644
index 0000000..cbafc61
--- /dev/null
+++ b/tools/ndnsec-cert-dump.hpp
@@ -0,0 +1,208 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_CERT_DUMP_HPP
+#define NDNSEC_CERT_DUMP_HPP
+
+#include "ndnsec-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 = "127.0.0.1";
+  std::string repoPort = "7376";
+  bool isDnsOut = false;
+
+  po::options_description desc("General Usage\n  ndnsec cert-dump [-h] [-p] [-d] [-r [-H repo-host] [-P repor-port] ] [-i|k|f] name\nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ("pretty,p", "optional, if specified, display certificate in human readable format")
+    ("identity,i", "optional, if specified, name is identity name (e.g. /ndn/edu/ucla/alice), otherwise certificate name")
+    ("key,k", "optional, if specified, name is key name (e.g. /ndn/edu/ucla/alice/KSK-123456789), otherwise certificate name")
+    ("file,f", "optional, if specified, name is file name, - for stdin")
+    ("repo-output,r", "optional, if specified, certificate is dumped (published) to repo")
+    ("repo-host,H", po::value<std::string>(&repoHost)->default_value("localhost"), "optional, the repo host if repo-output is specified")
+    ("repo-port,P", po::value<std::string>(&repoPort)->default_value("7376"), "optional, the repo port if repo-output is specified")
+    ("dns-output,d", "optional, if specified, certificate is dumped (published) to DNS")
+    ("name,n", po::value<std::string>(&name), "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;
+  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+  po::notify(vm);
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (0 == vm.count("name"))
+    {
+      std::cerr << "identity_name must be specified" << std::endl;
+      std::cerr << desc << std::endl;
+      return 1;
+    }
+  
+  if (vm.count("key"))
+    {
+      isCertName = false;
+      isKeyName = true;
+    }
+  else if (vm.count("identity"))
+    {
+      isCertName = false;
+      isIdentityName = true;
+    }
+  else if (vm.count("file"))
+    {
+      isCertName = false;
+      isFileName = true;
+    }    
+    
+  if (vm.count("pretty"))
+    isPretty = true;
+
+  if (vm.count("repo-output"))
+    {
+      isRepoOut = true;
+      isStdOut = false;
+    }
+  else if(vm.count("dns-output"))
+    {
+      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;
+
+  try
+    {
+      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(NULL == 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;
+            }
+        }
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+      
+  if(isPretty)
+    {
+      std::cout << *certificate << std::endl;
+      // cout << "Certificate name: " << std::endl;
+      // cout << "  " << certificate->getName() << std::endl;
+      // cout << "Validity: " << std::endl;
+      // cout << "  NotBefore: " << boost::posix_time::to_simple_string(certificate->getNotBefore()) << std::endl;
+      // cout << "  NotAfter: " << boost::posix_time::to_simple_string(certificate->getNotAfter()) << std::endl;
+      // cout << "Subject Description: " << std::endl;
+      // const vector<CertificateSubjectDescription>& SubDescriptionList = certificate->getSubjectDescriptionList();
+      // vector<CertificateSubjectDescription>::const_iterator it = SubDescriptionList.begin();
+      // for(; it != SubDescriptionList.end(); it++)
+      //   cout << "  " << it->getOidStr() << ": " << it->getValue() << std::endl;
+      // cout << "Public key bits: " << std::endl;
+      // const Blob& keyBlob = certificate->getPublicKeygetKeyBlob();
+      // std::string encoded;
+      // CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(keyBlob.buf()), keyBlob.size(), true,
+      //                           new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded), true, 64));
+      // cout << encoded;        
+    }
+  else
+    {
+      if(isStdOut)
+        {
+          try
+            {
+              using namespace CryptoPP;
+              StringSource ss(certificate->wireEncode().wire(), certificate->wireEncode().size(), true,
+                              new Base64Encoder(new FileSink(std::cout), true, 64));
+              return 0;
+            }
+          catch(CryptoPP::Exception& e)
+            {
+              std::cerr << e.what() << std::endl;
+              return 1;
+            }
+        }
+      if(isRepoOut)
+        {
+          using namespace boost::asio::ip;
+          tcp::iostream request_stream;
+#if (BOOST_VERSION >= 104700)
+          request_stream.expires_from_now(boost::posix_time::milliseconds(3000));
+#endif
+          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 //NDNSEC_CERT_DUMP_HPP
diff --git a/tools/ndnsec-certgen.cpp b/tools/ndnsec-cert-gen.hpp
similarity index 70%
rename from tools/ndnsec-certgen.cpp
rename to tools/ndnsec-cert-gen.hpp
index e40e392..023df7e 100644
--- a/tools/ndnsec-certgen.cpp
+++ b/tools/ndnsec-cert-gen.hpp
@@ -1,62 +1,26 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 /*
  * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
  * BSD license, See the LICENSE file for more information
- *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#include <iostream>
-#include <fstream>
+#ifndef NDNSEC_CERT_GEN_HPP
+#define NDNSEC_CERT_GEN_HPP
 
-#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/regex.hpp>
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
+#include "ndnsec-util.hpp"
 
-#include <boost/tokenizer.hpp>
-using boost::tokenizer;
-using boost::escaped_list_separator;
-
-#include "security/key-chain.hpp"
-
-namespace ndn {
-typedef boost::posix_time::ptime Time;
-typedef boost::posix_time::time_duration TimeInterval;
-namespace time {
-const Time UNIX_EPOCH_TIME = Time (boost::gregorian::date (1970, boost::gregorian::Jan, 1));
-} // namespace time
-} // namespace ndn
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-shared_ptr<IdentityCertificate>
-getSelfSignedCertificate(const std::string& fileName)
+int 
+ndnsec_cert_gen(int argc, char** argv)
 {
-  std::istream* ifs;
-  if(fileName == "-")
-    ifs = &std::cin;
-  else
-    ifs = new std::ifstream(fileName.c_str());
+  using boost::tokenizer;
+  using boost::escaped_list_separator;
 
-  std::string decoded;
-  CryptoPP::FileSource ss2(*ifs, true,
-                           new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
+  using namespace ndn;
+  namespace po = boost::program_options;
 
-  shared_ptr<IdentityCertificate> identityCertificate = make_shared<IdentityCertificate>();
-  identityCertificate->wireDecode(Block(make_shared<Buffer>(decoded.c_str(), decoded.size())));
-
-  return identityCertificate;
-}
-
-int main(int argc, char** argv)
-{
+  typedef boost::posix_time::ptime Time;
+  
   std::string notBeforeStr;
   std::string notAfterStr;
   std::string sName;
@@ -66,7 +30,7 @@
   bool isSelfSigned = false;
   bool nack = false;
 
-  po::options_description desc("General Usage\n  ndn-certgen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] [-s sign-id] request\nGeneral options");
+  po::options_description desc("General Usage\n  ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] [-s sign-id] request\nGeneral options");
   desc.add_options()
     ("help,h", "produce help message")
     ("not-before,S", po::value<std::string>(&notBeforeStr), "certificate starting date, YYYYMMDDhhmmss")
@@ -96,7 +60,7 @@
   if (vm.count("help"))
     {
       std::cerr << desc << std::endl;
-      return 1;
+      return 0;
     }
 
   if (0 == vm.count("sign-id"))
@@ -176,12 +140,8 @@
       return 1;
     }
 
-  shared_ptr<IdentityCertificate> selfSignedCertificate;
-  try
-    {
-      selfSignedCertificate = getSelfSignedCertificate(reqFile);
-    }
-  catch(...)
+  shared_ptr<IdentityCertificate> selfSignedCertificate = getIdentityCertificate(reqFile);
+  if(!static_cast<bool>(selfSignedCertificate))
     {
       std::cerr << "ERROR: input error" << std::endl;
       return 1;
@@ -235,8 +195,8 @@
           CertificateSubjectDescription subDescryptName("2.5.4.41", sName);
           IdentityCertificate certificate;
           certificate.setName(certName);
-          certificate.setNotBefore((notBefore-ndn::time::UNIX_EPOCH_TIME).total_milliseconds());
-          certificate.setNotAfter((notAfter-ndn::time::UNIX_EPOCH_TIME).total_milliseconds());
+          certificate.setNotBefore((notBefore-ndn::UNIX_EPOCH_TIME).total_milliseconds());
+          certificate.setNotAfter((notAfter-ndn::UNIX_EPOCH_TIME).total_milliseconds());
           certificate.setPublicKeyInfo(selfSignedCertificate->getPublicKeyInfo());
           certificate.addSubjectDescription(subDescryptName);
           for(int i = 0; i < otherSubDescrypt.size(); i++)
@@ -255,7 +215,12 @@
             }
           wire = certificate.wireEncode();
         }
-      catch(std::exception &e)
+      catch(SecPublicInfo::Error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          return 1;
+        }
+      catch(SecTpm::Error& e)
         {
           std::cerr << "ERROR: " << e.what() << std::endl;
           return 1;
@@ -267,17 +232,40 @@
       // revocationCert.setContent(void*, 0); // empty content
       revocationCert.setName(certName);
 
-      KeyChain keyChain;
-
-      Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(Name(signId));
-
-      keyChain.sign (revocationCert, signingCertificateName);
-      wire = revocationCert.wireEncode();
+      try
+        {
+          KeyChain keyChain;
+          
+          Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(Name(signId));
+          
+          keyChain.sign (revocationCert, signingCertificateName);
+          wire = revocationCert.wireEncode();
+        }
+      catch(SecPublicInfo::Error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          return 1;
+        }
+      catch(SecTpm::Error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          return 1;
+        }
     }
 
-  CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(wire.wire()), wire.size(),
-                            true,
-                            new CryptoPP::Base64Encoder(new CryptoPP::FileSink(std::cout), true, 64));
+  try
+    {
+      using namespace CryptoPP;
+      StringSource ss(wire.wire(), wire.size(), true,
+                      new Base64Encoder(new FileSink(std::cout), true, 64));
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
 
   return 0;
 }
+
+#endif //NDNSEC_CERT_GEN_HPP
diff --git a/tools/ndnsec-install-cert.cpp b/tools/ndnsec-cert-install.hpp
similarity index 66%
rename from tools/ndnsec-install-cert.cpp
rename to tools/ndnsec-cert-install.hpp
index 4bcd4a2..1d3347f 100644
--- a/tools/ndnsec-install-cert.cpp
+++ b/tools/ndnsec-cert-install.hpp
@@ -1,49 +1,15 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 /*
  * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
  * BSD license, See the LICENSE file for more information
- *
  * Author: Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
-#include <iostream>
-#include <fstream>
+#ifndef NDNSEC_CERT_INSTALL_HPP
+#define NDNSEC_CERT_INSTALL_HPP
 
-#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/asio.hpp>
+#include "ndnsec-util.hpp"
 
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
-
-#include "security/key-chain.hpp"
-
-using namespace std;
-using namespace ndn;
-namespace po = boost::program_options;
-
-ptr_lib::shared_ptr<IdentityCertificate>
-getCertificate(const string& fileName)
-{
-  istream* ifs;
-  if(fileName == string("-"))
-    ifs = &cin;
-  else
-    ifs = new ifstream(fileName.c_str());
-
-  string decoded;
-  CryptoPP::FileSource ss2(*ifs, true,
-                           new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
-
-  ptr_lib::shared_ptr<IdentityCertificate> identityCertificate = ptr_lib::make_shared<IdentityCertificate>();
-  identityCertificate->wireDecode(Block(decoded.c_str(), decoded.size()));
-
-  return identityCertificate;
-}
 
 struct HttpException : public std::exception
 {
@@ -64,7 +30,7 @@
   std::string m_reason;
 };
 
-ptr_lib::shared_ptr<IdentityCertificate>
+ndn::shared_ptr<ndn::IdentityCertificate>
 getCertificateHttp(const std::string &host, const std::string &port, const std::string &path)
 {
   using namespace boost::asio::ip;
@@ -110,30 +76,32 @@
   std::string header;
   while (std::getline(request_stream, header) && header != "\r") ;
 
+  ndn::OBufferStream os;
+  CryptoPP::FileSource ss2(request_stream, true, new CryptoPP::Base64Decoder(new CryptoPP::FileSink(os)));
 
-  string decoded;
-  CryptoPP::FileSource ss2(request_stream, true,
-                           new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
-
-  ptr_lib::shared_ptr<IdentityCertificate> identityCertificate = ptr_lib::make_shared<IdentityCertificate>();
-  identityCertificate->wireDecode(Block(decoded.c_str(), decoded.size()));
+  ndn::shared_ptr<ndn::IdentityCertificate> identityCertificate = ndn::make_shared<ndn::IdentityCertificate>();
+  identityCertificate->wireDecode(ndn::Block(os.buf()));
 
   return identityCertificate;
 }
 
-int main(int argc, char** argv)
+int 
+ndnsec_cert_install(int argc, char** argv)
 {
-  string certFileName;
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string certFileName;
   bool systemDefault = true;
   bool identityDefault = false;
   bool keyDefault = false;
   bool noDefault = false;
   bool any = false;
 
-  po::options_description desc("General Usage\n  ndn-install-cert [-h] [-I|K|N] cert-file\nGeneral options");
+  po::options_description desc("General Usage\n  ndnsec cert-install [-h] [-I|K|N] cert-file\nGeneral options");
   desc.add_options()
     ("help,h", "produce help message")
-    ("cert-file,f", po::value<string>(&certFileName), "file name of the ceritificate, - for stdin. "
+    ("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")
@@ -149,22 +117,22 @@
       po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
       po::notify(vm);
     }
-  catch (exception &e)
+  catch (std::exception &e)
     {
-      cerr << "ERROR: " << e.what() << endl;
+      std::cerr << "ERROR: " << e.what() << std::endl;
       return 1;
     }
 
   if (vm.count("help"))
     {
-      cerr << desc << endl;
-      return 1;
+      std::cerr << desc << std::endl;
+      return 0;
     }
 
   if (0 == vm.count("cert-file"))
     {
-      cerr << "cert_file must be specified" << endl;
-      cerr << desc << endl;
+      std::cerr << "cert_file must be specified" << std::endl;
+      std::cerr << desc << std::endl;
       return 1;
     }
 
@@ -186,23 +154,23 @@
 
   try
     {
-      ptr_lib::shared_ptr<IdentityCertificate> cert;
+      shared_ptr<IdentityCertificate> cert;
 
       if(certFileName.find("http://") == 0)
         {
-          string host;
-          string port;
-          string path;
+          std::string host;
+          std::string port;
+          std::string path;
 
           size_t pos = 7;
           size_t posSlash = certFileName.find ("/", pos);
 
-          if (posSlash == string::npos)
+          if (posSlash == std::string::npos)
             throw HttpException("Request line is not correctly formatted");
 
           size_t posPort = certFileName.find (":", pos);
 
-          if (posPort != string::npos && posPort < posSlash) // port is specified
+          if (posPort != std::string::npos && posPort < posSlash) // port is specified
             {
               port = certFileName.substr (posPort + 1, posSlash - posPort - 1);
               host = certFileName.substr (pos, posPort-pos);
@@ -219,9 +187,12 @@
         }
       else
         {
-          cert = getCertificate(certFileName);
+          cert = getIdentityCertificate(certFileName);
         }
 
+      if(!static_cast<bool>(cert))
+        return 1;
+
       KeyChain keyChain;
 
       if(systemDefault)
@@ -244,18 +215,30 @@
           keyChain.addCertificate(*cert);
         }
 
-      cout << "OK: certificate with name [" << cert->getName().toUri() << "] has been successfully installed" << endl;
+      std::cerr << "OK: certificate with name [" << cert->getName().toUri() << "] has been successfully installed" << std::endl;
 
       return 0;
     }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
   catch(std::exception &e)
     {
-      cerr << "ERROR: " << e.what() << endl;
+      std::cerr << "ERROR: " << e.what() << std::endl;
       return 1;
     }
   catch(...)
     {
-      cerr << "ERROR: unknown error" << endl;
+      std::cerr << "ERROR: unknown error" << std::endl;
       return 1;
     }
 }
+
+#endif //NDNSEC_CERT_INSTALL_HPP
diff --git a/tools/ndnsec-delete.hpp b/tools/ndnsec-delete.hpp
new file mode 100644
index 0000000..bced204
--- /dev/null
+++ b/tools/ndnsec-delete.hpp
@@ -0,0 +1,98 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_DELETE_HPP
+#define NDNSEC_DELETE_HPP
+
+#include "ndnsec-util.hpp"
+
+int 
+ndnsec_delete(int argc, char** argv)	
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  bool deleteId = true;
+  bool deleteKey = false;
+  bool deleteCert = false;
+  std::string name;
+
+  po::options_description desc("General Usage\n  ndnsec delete [-h] [-K|C] name\nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ("delete_key,K", "(Optional) delete a key if specified.")
+    ("delete_cert,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(desc).positional(p).run(), vm);
+      po::notify(vm);
+    }
+  catch (std::exception &e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;;
+      return 0;
+    }
+
+  if(vm.count("delete_cert"))
+    {
+      deleteCert = true;
+      deleteId = false;
+    }
+  else if(vm.count("delete_key"))
+    {
+      deleteKey = true;
+      deleteId = false;
+    }
+  
+  try
+    {
+      KeyChain keyChain;
+
+      if(deleteCert)
+        {
+          keyChain.deleteCertificate(name);
+        }
+      else if(deleteKey)
+        {
+          keyChain.deleteKey(name);
+        }
+      else
+        {
+          keyChain.deleteIdentity(name);
+        }
+      
+      return 0;
+      
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+}
+
+#endif //NDNSEC_DELETE_HPP
diff --git a/tools/ndnsec-dsk-gen.hpp b/tools/ndnsec-dsk-gen.hpp
new file mode 100644
index 0000000..b7d95e8
--- /dev/null
+++ b/tools/ndnsec-dsk-gen.hpp
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_DSK_GEN_HPP
+#define NDNSEC_DSK_GEN_HPP
+
+#include "ndnsec-util.hpp"
+
+int 
+ndnsec_dsk_gen(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string identityName;
+  char keyType = 'r';
+  int keySize = 2048;
+
+  po::options_description desc("General Usage\n  ndnsec dsk-gen [-h] identity\nGeneral options");
+  desc.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)")
+    // ("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;
+  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+  po::notify(vm);
+
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (0 == vm.count("identity"))
+    {
+      std::cerr << "identity must be specified" << std::endl;
+      std::cerr << desc << std::endl;
+      return 1;
+    }
+
+  shared_ptr<IdentityCertificate> kskCert;
+  Name signingCertName;
+  try
+    {
+      KeyChain keyChain;
+
+      Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
+      bool isDefaultDsk = false;
+      if(defaultCertName.get(-3).toEscapedString().substr(0,4) == "dsk-")
+        isDefaultDsk = true;
+
+      if(isDefaultDsk)
+        {
+          shared_ptr<IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
+          SignatureSha256WithRsa sha256sig(dskCert->getSignature());
+
+          Name keyLocatorName = sha256sig.getKeyLocator().getName(); // will throw exception if keylocator is absent or it is not a name
+
+          Name kskName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+          Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
+          signingCertName = kskCertName;
+          kskCert = keyChain.getCertificate(kskCertName);
+        }
+      else
+        {
+          signingCertName = defaultCertName;
+          kskCert = keyChain.getCertificate(defaultCertName);
+        }
+    }
+  catch(SignatureSha256WithRsa::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(KeyLocator::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if(!static_cast<bool>(kskCert))
+    {
+      std::cerr << "ERROR: no KSK certificate." << std::endl;
+      return 1;
+    }
+
+  try
+    {
+      KeyChain keyChain;
+      Name newKeyName;
+      switch(keyType)
+        {
+        case 'r':
+          {
+            newKeyName = keyChain.generateRSAKeyPair(Name(identityName), false, keySize);
+            if(0 == newKeyName.size())
+              {
+                std::cerr << "fail to generate key!" << std::endl;
+                return 1;
+              }
+            break;
+          }
+        default:
+          std::cerr << "Unrecongized key type" << "\n";
+          std::cerr << desc << std::endl;
+          return 1;
+        }
+    
+      Name certName = newKeyName.getPrefix(-1);
+      certName.append("KEY").append(newKeyName.get(-1)).append("ID-CERT").appendVersion();
+
+      shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
+      certificate->setName(certName);
+      certificate->setNotBefore(kskCert->getNotBefore());
+      certificate->setNotAfter(kskCert->getNotAfter());
+
+      certificate->setPublicKeyInfo(*keyChain.getPublicKey(newKeyName));
+
+      const std::vector<CertificateSubjectDescription>& subList = kskCert->getSubjectDescriptionList();
+      std::vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
+      for(; it != subList.end(); it++)
+        certificate->addSubjectDescription(*it);
+      
+      certificate->encode();
+
+      keyChain.sign(*certificate, signingCertName);
+
+      keyChain.addCertificateAsIdentityDefault(*certificate);
+
+      return 0;
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+}
+
+#endif //NDNSEC_DSK_GEN_HPP
diff --git a/tools/ndnsec-dskgen.cpp b/tools/ndnsec-dskgen.cpp
deleted file mode 100644
index 61f1fbf..0000000
--- a/tools/ndnsec-dskgen.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options/parsers.hpp>
-#include <cryptopp/base64.h>
-
-#include "security/key-chain.hpp"
-#include "security/signature-sha256-with-rsa.hpp"
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-
-int main(int argc, char** argv)
-{
-  std::string identityName;
-  char keyType = 'r';
-  int keySize = 2048;
-
-  // po::options_description desc("General Usage\n  ndn-keygen [-h] [-d] [-i] [-t type] [-s size] identity\nGeneral options");
-  po::options_description desc("General Usage\n  ndn-keygen [-h] identity\nGeneral options");
-  desc.add_options()
-    ("help,h", "produce help message")
-    ("identity_name,n", 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)")
-    // ("size,s", po::value<int>(&keySize)->default_value(2048), "optional, key size, 2048 (default)")
-    ;
-
-  po::positional_options_description p;
-  p.add("identity_name", 1);
-
-  po::variables_map vm;
-  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
-  po::notify(vm);
-
-  if (vm.count("help"))
-    {
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-
-  if (0 == vm.count("identity_name"))
-    {
-      std::cerr << "identity_name must be specified" << std::endl;
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-
-  KeyChain keyChain;
-
-  Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
-  bool isDefaultDsk = false;
-  if(defaultCertName.get(-3).toEscapedString().substr(0,4) == "dsk-")
-    isDefaultDsk = true;
-
-  Name signingCertName;
-  shared_ptr<IdentityCertificate> kskCert;
-  if(isDefaultDsk)
-    {
-      shared_ptr<IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
-      SignatureSha256WithRsa sha256sig(dskCert->getSignature());
-
-      Name keyLocatorName = sha256sig.getKeyLocator().getName(); // will throw exception if keylocator is absent or it is not a name
-
-      Name kskName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-      Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
-      signingCertName = kskCertName;
-      kskCert = keyChain.getCertificate(kskCertName);
-    }
-  else
-    {
-      signingCertName = defaultCertName;
-      kskCert = keyChain.getCertificate(defaultCertName);
-    }
-
-  Name newKeyName;
-  // if (vm.count("type"))
-  if (true)
-    {
-      switch(keyType)
-      {
-      case 'r':
-        {
-          try
-            {
-              newKeyName = keyChain.generateRSAKeyPair(Name(identityName), false, keySize);
-
-              if(0 == newKeyName.size())
-                {
-		  std::cerr << "fail to generate key!" << std::endl;
-                  return 1;
-                }
-	      break;
-            }
-          catch(std::exception &e)
-            {
-              std::cerr << "ERROR: " << e.what() << std::endl;
-              return 1;
-            }
-        }
-      default:
-        std::cerr << "Unrecongized key type" << "\n";
-        std::cerr << desc << std::endl;
-        return 1;
-      }
-    }
-
-
-  Name certName = newKeyName.getPrefix(newKeyName.size()-1);
-  certName.append("KEY").append(newKeyName.get(-1)).append("ID-CERT").appendVersion ();
-
-  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
-  certificate->setName(certName);
-  certificate->setNotBefore(kskCert->getNotBefore());
-  certificate->setNotAfter(kskCert->getNotAfter());
-
-  certificate->setPublicKeyInfo(*keyChain.getPublicKey(newKeyName));
-
-  const std::vector<CertificateSubjectDescription>& subList = kskCert->getSubjectDescriptionList();
-  std::vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
-  for(; it != subList.end(); it++)
-      certificate->addSubjectDescription(*it);
-
-  certificate->encode();
-
-  keyChain.sign(*certificate, signingCertName);
-
-  keyChain.addCertificateAsIdentityDefault(*certificate);
-
-  return 0;
-}
diff --git a/tools/ndnsec-dump-certificate.cpp b/tools/ndnsec-dump-certificate.cpp
deleted file mode 100644
index bb322d0..0000000
--- a/tools/ndnsec-dump-certificate.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#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/asio.hpp>
-
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
-
-#include "security/key-chain.hpp"
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-shared_ptr<IdentityCertificate>
-getIdentityCertificate(const std::string& fileName)
-{
-  std::istream* ifs;
-  if(fileName == "-")
-    ifs = &std::cin;
-  else
-    ifs = new std::ifstream(fileName.c_str());
-
-  std::string decoded;
-  CryptoPP::FileSource ss2(*ifs, true,
-                           new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
-
-  ptr_lib::shared_ptr<IdentityCertificate> identityCertificate = ptr_lib::make_shared<IdentityCertificate>();
-  identityCertificate->wireDecode(Block(decoded.c_str(), decoded.size()));
-
-  return identityCertificate;
-}
-
-int main(int argc, char** argv)	
-{
-  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 = "127.0.0.1";
-  std::string repoPort = "7376";
-  bool isDnsOut = false;
-
-  po::options_description desc("General Usage\n  ndn-dump-certificate [-h] [-p] [-d] [-r [-H repo-host] [-P repor-port] ] [-i|k|f] certName\nGeneral options");
-  desc.add_options()
-    ("help,h", "produce help message")
-    ("pretty,p", "optional, if specified, display certificate in human readable format")
-    ("identity,i", "optional, if specified, name is identity name (e.g. /ndn/edu/ucla/alice), otherwise certificate name")
-    ("key,k", "optional, if specified, name is key name (e.g. /ndn/edu/ucla/alice/KSK-123456789), otherwise certificate name")
-    ("file,f", "optional, if specified, name is file name, - for stdin")
-    ("repo-output,r", "optional, if specified, certificate is dumped (published) to repo")
-    ("repo-host,H", po::value<std::string>(&repoHost)->default_value("localhost"), "optional, the repo host if repo-output is specified")
-    ("repo-port,P", po::value<std::string>(&repoPort)->default_value("7376"), "optional, the repo port if repo-output is specified")
-    ("dns-output,d", "optional, if specified, certificate is dumped (published) to DNS")
-    ("name,n", po::value<std::string>(&name), "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;
-  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
-  po::notify(vm);
-
-  if (vm.count("help")) 
-    {
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-
-  if (0 == vm.count("name"))
-    {
-      std::cerr << "identity_name must be specified" << std::endl;
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-  
-  if (vm.count("key"))
-    {
-      isCertName = false;
-      isKeyName = true;
-    }
-  else if (vm.count("identity"))
-    {
-      isCertName = false;
-      isIdentityName = true;
-    }
-  else if (vm.count("file"))
-    {
-      isCertName = false;
-      isFileName = true;
-    }    
-    
-  if (vm.count("pretty"))
-    isPretty = true;
-
-  if (vm.count("repo-output"))
-    {
-      isRepoOut = true;
-      isStdOut = false;
-    }
-  else if(vm.count("dns-output"))
-    {
-      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;
-    }
-
-  KeyChain keyChain;
-  shared_ptr<IdentityCertificate> certificate;
-
-  try{
-    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(NULL == certificate)
-          {
-            std::cerr << "No certificate found!" << std::endl;
-            return 1;
-          }
-      }
-    else
-      {
-        certificate = getIdentityCertificate(name);
-        if(NULL == certificate)
-          {
-            std::cerr << "No certificate read!" << std::endl;
-            return 1;
-          }
-      }
-
-    if(isPretty)
-      {
-        std::cout << *certificate << std::endl;
-        // cout << "Certificate name: " << std::endl;
-        // cout << "  " << certificate->getName() << std::endl;
-        // cout << "Validity: " << std::endl;
-        // cout << "  NotBefore: " << boost::posix_time::to_simple_string(certificate->getNotBefore()) << std::endl;
-        // cout << "  NotAfter: " << boost::posix_time::to_simple_string(certificate->getNotAfter()) << std::endl;
-        // cout << "Subject Description: " << std::endl;
-        // const vector<CertificateSubjectDescription>& SubDescriptionList = certificate->getSubjectDescriptionList();
-        // vector<CertificateSubjectDescription>::const_iterator it = SubDescriptionList.begin();
-        // for(; it != SubDescriptionList.end(); it++)
-        //   cout << "  " << it->getOidStr() << ": " << it->getValue() << std::endl;
-        // cout << "Public key bits: " << std::endl;
-        // const Blob& keyBlob = certificate->getPublicKeygetKeyBlob();
-        // std::string encoded;
-        // CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(keyBlob.buf()), keyBlob.size(), true,
-        //                           new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded), true, 64));
-        // cout << encoded;        
-      }
-    else
-      {
-        if(isStdOut)
-          {
-            CryptoPP::StringSource ss(certificate->wireEncode().wire(), certificate->wireEncode().size(),
-                                      true,
-                                      new CryptoPP::Base64Encoder(new CryptoPP::FileSink(std::cout), true, 64));
-            return 0;
-          }
-        if(isRepoOut)
-          {
-            using namespace boost::asio::ip;
-            tcp::iostream request_stream;
-#if (BOOST_VERSION >= 104700)
-            request_stream.expires_from_now(boost::posix_time::milliseconds(3000));
-#endif
-            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;
-          }
-      }
-  }
-  catch(std::exception & e){
-    std::cerr << e.what() << std::endl;
-    return 1;
-  }
-  return 0;
-}
diff --git a/tools/ndnsec-export.hpp b/tools/ndnsec-export.hpp
new file mode 100644
index 0000000..c7753f3
--- /dev/null
+++ b/tools/ndnsec-export.hpp
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_EXPORT_HPP
+#define NDNSEC_EXPORT_HPP
+
+#include "ndnsec-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;
+
+  po::options_description desc("General Usage\n  ndnsec export [-h] [-o output] identity \nGeneral options");
+  desc.add_options()
+    ("help,h", "Produce help message")
+    ("output,o", po::value<std::string>(&output), "(Optional) output file, stdout if not specified")
+    ("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(desc).positional(p).run(), vm);
+      po::notify(vm);
+    }
+  catch (std::exception &e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (!vm.count("output"))
+    output = "-";
+
+  Block wire;
+  Name identity(identityStr);
+
+  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;
+            }
+        }
+      wire = keyChain.exportIdentity(identity, exportPassword);
+      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+      wire.encode();
+    }
+  catch(Block::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+      return 1;
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+      return 1;
+    }
+
+  std::ostream* ofs;
+  std::ostream* ffs = 0;
+  if(output == "-")
+    ofs = &std::cout;
+  else
+    {
+      ofs = new std::ofstream(output.c_str());
+      ffs = ofs;
+    }
+
+  try
+    {
+      using namespace CryptoPP;
+
+      StringSource ss(wire.wire(), wire.size(), true,
+                      new Base64Encoder(new FileSink(*ofs), true, 64));
+      if(ffs)
+        delete ffs;
+      ffs = 0;
+      ofs = 0;
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      if(ffs)
+        delete ffs;
+      ffs = 0;
+      ofs = 0;
+
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  return 0;
+}
+
+#endif //NDNSEC_EXPORT_HPP
diff --git a/tools/ndnsec-get-default.cpp b/tools/ndnsec-get-default.cpp
deleted file mode 100644
index d263d2b..0000000
--- a/tools/ndnsec-get-default.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#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 <cryptopp/base64.h>
-
-#include "security/key-chain.hpp"
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-int main(int argc, char** argv)	
-{
-  bool getDefaultId = true;
-  bool getDefaultKey = false;
-  bool getDefaultCert = false;
-  bool quiet = false;
-  std::string idName;
-  std::string keyName;
-
-  po::options_description desc("General Usage\n  ndn-get-default [-h] [-K|C] [-i identity|-k key]\nGeneral options");
-  desc.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>(&idName), "target identity")
-    ("key,k", po::value<std::string>(&keyName), "target key")
-    ("quiet,q", "don't output trailing newline")
-    ;
-
-  po::variables_map vm;
-  po::store(po::parse_command_line(argc, argv, desc), vm);
-  po::notify(vm);
-
-  if (vm.count("help")) 
-    {
-      std::cerr << desc << std::endl;;
-      return 1;
-    }
-
-  if(vm.count("default_cert"))
-    {
-      getDefaultCert = true;
-      getDefaultId = false;
-    }
-  else if(vm.count("default_key"))
-    {
-      getDefaultKey = true;
-      getDefaultId = false;
-    }
-
-  if(vm.count("quiet"))
-    {
-      quiet = true;
-    }
-  
-  KeyChain keyChain;
-  bool ok = false;
-
-  if(vm.count("key"))
-    {
-      Name keyNdnName(keyName);
-      if(getDefaultCert)
-	{
-	  std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName);
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-      return 1;
-    }
-  else if(vm.count("identity"))
-    {
-      Name idNdnName(idName);
-
-      if(getDefaultKey)
-	{
-	  std::cout << keyChain.getDefaultKeyNameForIdentity(idNdnName);
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-      if(getDefaultCert)
-	{
-	  std::cout << keyChain.getDefaultCertificateNameForIdentity(idNdnName);
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-      return 1;
-    }
-  else
-    {
-      Name idNdnName = keyChain.getDefaultIdentity();
-      if(getDefaultId)
-	{
-	  std::cout << idNdnName;
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-      if(getDefaultKey)
-	{
-	  std::cout << keyChain.getDefaultKeyNameForIdentity(idNdnName);
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-      if(getDefaultCert)
-	{
-	  std::cout << keyChain.getDefaultCertificateNameForIdentity(idNdnName);
-          if (!quiet) std::cout << std::endl;
-	  return 0;
-	}
-    }
-
-
-}
diff --git a/tools/ndnsec-get-default.hpp b/tools/ndnsec-get-default.hpp
new file mode 100644
index 0000000..7827d6a
--- /dev/null
+++ b/tools/ndnsec-get-default.hpp
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_GET_DEFAULT_HPP
+#define NDNSEC_GET_DEFAULT_HPP
+
+#include "ndnsec-util.hpp"
+
+
+int 
+ndnsec_get_default(int argc, char** argv)	
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  bool getDefaultId = true;
+  bool getDefaultKey = false;
+  bool getDefaultCert = false;
+  bool quiet = false;
+  std::string idName;
+  std::string keyName;
+
+  po::options_description desc("General Usage\n  ndnsec get-default [-h] [-K|C] [-i identity|-k key] [-q]\nGeneral options");
+  desc.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>(&idName), "target identity")
+    ("key,k", po::value<std::string>(&keyName), "target key")
+    ("quiet,q", "don't output trailing newline")
+    ;
+
+  po::variables_map vm;
+  po::store(po::parse_command_line(argc, argv, desc), vm);
+  po::notify(vm);
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;;
+      return 0;
+    }
+
+  if(vm.count("default_cert"))
+    {
+      getDefaultCert = true;
+      getDefaultId = false;
+    }
+  else if(vm.count("default_key"))
+    {
+      getDefaultKey = true;
+      getDefaultId = false;
+    }
+
+  if(vm.count("quiet"))
+    {
+      quiet = true;
+    }
+  
+  try
+    {
+      KeyChain keyChain;
+
+      if(vm.count("key"))
+        {
+          Name keyNdnName(keyName);
+          if(getDefaultCert)
+            {
+              std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName);
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          return 1;
+        }
+      else if(vm.count("identity"))
+        {
+          Name idNdnName(idName);
+          
+          if(getDefaultKey)
+            {
+              std::cout << keyChain.getDefaultKeyNameForIdentity(idNdnName);
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          if(getDefaultCert)
+            {
+              std::cout << keyChain.getDefaultCertificateNameForIdentity(idNdnName);
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          return 1;
+        }
+      else
+        {
+          Name idNdnName = keyChain.getDefaultIdentity();
+          if(getDefaultId)
+            {
+              std::cout << idNdnName;
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          if(getDefaultKey)
+            {
+              std::cout << keyChain.getDefaultKeyNameForIdentity(idNdnName);
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          if(getDefaultCert)
+            {
+              std::cout << keyChain.getDefaultCertificateNameForIdentity(idNdnName);
+              if (!quiet) std::cout << std::endl;
+              return 0;
+            }
+          return 1;
+        }
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+}
+
+#endif //NDNSEC_GET_DEFAULT_HPP
diff --git a/tools/ndnsec-import.hpp b/tools/ndnsec-import.hpp
new file mode 100644
index 0000000..b73e1cf
--- /dev/null
+++ b/tools/ndnsec-import.hpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_IMPORT_HPP
+#define NDNSEC_IMPORT_HPP
+
+#include "ndnsec-util.hpp"
+
+int 
+ndnsec_import(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string input; 
+  std::string importPassword;
+
+  po::options_description desc("General Usage\n  ndnsec import [-h] input \nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ("input,i", po::value<std::string>(&input), "input source, stdin if not specified")
+    ;
+
+  po::positional_options_description p;
+  p.add("input", 1);
+
+  po::variables_map vm;
+  try
+    {
+      po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+      po::notify(vm);
+    }
+  catch (std::exception &e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (!vm.count("input"))
+    input = "-";
+
+  KeyChain keyChain;
+
+  OBufferStream os;
+  std::istream* ifs;
+  if(input == "-")
+    ifs = &std::cin;
+  else
+    ifs = new std::ifstream(input.c_str());
+
+  {  
+    using namespace CryptoPP;
+    FileSource ss(*ifs, true, new Base64Decoder(new FileSink(os)));
+  }
+
+  try
+    {
+      Block wire(os.buf());
+      
+      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(wire, importPassword);
+      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+    }
+  catch(Block::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+      return 1;
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+      return 1;
+    }
+
+  return 0;
+}
+
+#endif //NDNSEC_IMPORT_HPP
diff --git a/tools/ndnsec-key-gen.hpp b/tools/ndnsec-key-gen.hpp
new file mode 100644
index 0000000..3df9c6b
--- /dev/null
+++ b/tools/ndnsec-key-gen.hpp
@@ -0,0 +1,119 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_KEY_GEN_HPP
+#define NDNSEC_KEY_GEN_HPP
+
+#include "ndnsec-util.hpp"
+
+int 
+ndnsec_key_gen(int argc, char** argv)	
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string identityName;
+  bool notDefault = false;
+  char keyType = 'r';
+  int keySize = 2048;
+  std::string outputFilename;
+
+  po::options_description desc("General Usage\n  ndnsec key-gen [-h] [-n] identity\nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ("identity,i", po::value<std::string>(&identityName), "identity name, for example, /ndn/ucla.edu/alice")
+    ("not_default,n", "optional, if not specified, the target identity will be set as the default identity of the system")
+    // ("type,t", po::value<char>(&keyType)->default_value('r'), "optional, key type, r for RSA key (default)")
+    // ("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;
+  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+  po::notify(vm);
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (0 == vm.count("identity"))
+    {
+      std::cerr << "identity must be specified" << std::endl;
+      std::cerr << desc << std::endl;
+      return 1;
+    }
+  
+  if (vm.count("not_default"))
+    notDefault = true;
+  
+  if (true)
+    {
+      switch(keyType)
+        {
+        case 'r':
+          {
+            shared_ptr<IdentityCertificate> idcert;
+            try
+              {
+                KeyChain keyChain;
+                
+                Name keyName = keyChain.generateRSAKeyPair(Name(identityName), true, keySize);            
+                
+                if(0 == keyName.size())
+                  {                  
+                    return 1;
+                  }
+                
+                keyChain.setDefaultKeyNameForIdentity(keyName);
+            
+                idcert = keyChain.selfSign(keyName);
+                
+                if(!notDefault)
+                  {
+                    keyChain.setDefaultIdentity(Name(identityName));
+                  }
+              }
+            catch(const SecPublicInfo::Error& e)
+              {
+                std::cerr << "ERROR: " << e.what() << std::endl;
+                return 1;
+              }
+            catch(const SecTpm::Error& e)
+              {
+                std::cerr << "ERROR: " << e.what() << std::endl;
+                return 1;
+              }
+
+            try
+              {
+                CryptoPP::StringSource ss(idcert->wireEncode().wire(), 
+                                          idcert->wireEncode().size(), 
+                                          true,
+                                          new CryptoPP::Base64Encoder(new CryptoPP::FileSink(std::cout), true, 64));
+                return 0;
+              }
+            catch(const CryptoPP::Exception& e)
+              {
+                std::cerr << "ERROR: " << e.what() << std::endl;
+                return 1;
+              }
+        }
+      default:
+        std::cerr << "Unrecongized key type" << "\n";
+        std::cerr << desc << std::endl;
+        return 1;
+      }
+    }
+
+  return 0;
+}
+
+#endif //NDNSEC_KEY_GEN_HPP
diff --git a/tools/ndnsec-keygen.cpp b/tools/ndnsec-keygen.cpp
deleted file mode 100644
index 48646d1..0000000
--- a/tools/ndnsec-keygen.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options/parsers.hpp>
-
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
-
-#include "security/key-chain.hpp"
-
-using namespace std;
-using namespace ndn;
-namespace po = boost::program_options;
-
-
-int main(int argc, char** argv)	
-{
-  string identityName;
-  bool dskFlag = false;
-  bool notDefault = false;
-  char keyType = 'r';
-  int keySize = 2048;
-  string outputFilename;
-
-  // po::options_description desc("General Usage\n  ndn-keygen [-h] [-d] [-i] [-t type] [-s size] identity\nGeneral options");
-  po::options_description desc("General Usage\n  ndn-keygen [-h] [-i] identity\nGeneral options");
-  desc.add_options()
-    ("help,h", "produce help message")
-    ("identity_name,n", po::value<string>(&identityName), "identity name, for example, /ndn/ucla.edu/alice")
-    // ("dsk,d", "optional, if specified, a Data-Signing-Key will be created, otherwise create a Key-Signing-Key")
-    ("not_default,i", "optional, if not specified, the target identity will be set as the default identity of the system")
-    // ("type,t", po::value<char>(&keyType)->default_value('r'), "optional, key type, r for RSA key (default)")
-    // ("size,s", po::value<int>(&keySize)->default_value(2048), "optional, key size, 2048 (default)")
-    ;
-
-  po::positional_options_description p;
-  p.add("identity_name", 1);
-  
-  po::variables_map vm;
-  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
-  po::notify(vm);
-
-  if (vm.count("help")) 
-    {
-      cerr << desc << endl;
-      return 1;
-    }
-
-  if (0 == vm.count("identity_name"))
-    {
-      cerr << "identity_name must be specified" << endl;
-      cerr << desc << endl;
-      return 1;
-    }
-
-  // if (vm.count("dsk")) 
-  //   dskFlag =  true;
-  
-  if (vm.count("not_default"))
-    notDefault = true;
-
-  KeyChain keyChain;
-
-  // if (vm.count("type")) 
-  if (true)
-    {
-      switch(keyType)
-      {
-      case 'r':
-        {
-          try
-            {
-              Name keyName = keyChain.generateRSAKeyPair(Name(identityName), !dskFlag, keySize);            
-
-              if(0 == keyName.size())
-                {                  
-                  return 1;
-                }
-
-              keyChain.setDefaultKeyNameForIdentity(keyName);
-            
-              ptr_lib::shared_ptr<IdentityCertificate> idcert = keyChain.selfSign(keyName);
-
-              if(!notDefault)
-                {
-                  keyChain.setDefaultIdentity(Name(identityName));
-                }
-              
-              CryptoPP::StringSource ss(idcert->wireEncode().wire(), 
-                                        idcert->wireEncode().size(), 
-                                        true,
-                                        new CryptoPP::Base64Encoder(new CryptoPP::FileSink(cout), true, 64));
-              return 0;
-            }
-          catch(std::exception &e)
-            {
-              cerr << "ERROR: " << e.what() << endl;
-              return 1;
-            }
-        }
-      default:
-        cerr << "Unrecongized key type" << "\n";
-        cerr << desc << endl;
-        return 1;
-      }
-    }
-
-  return 0;
-}
diff --git a/tools/ndnsec-list.hpp b/tools/ndnsec-list.hpp
new file mode 100644
index 0000000..b9724d6
--- /dev/null
+++ b/tools/ndnsec-list.hpp
@@ -0,0 +1,190 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_LIST_HPP
+#define NDNSEC_LIST_HPP
+
+#include "ndnsec-util.hpp"
+
+int 
+ndnsec_list(int argc, char** argv)	
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  bool getId = true;
+  bool getKey = false;
+  bool getCert = false;
+
+  po::options_description desc("General Usage\n  ndnsec list [-h] [-K|C]\nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ("key,K", "granularity: key")
+    ("cert,C", "granularity: certificate")
+    ;
+
+  po::variables_map vm;
+  po::store(po::parse_command_line(argc, argv, desc), vm);
+  po::notify(vm);
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;;
+      return 0;
+    }
+
+  if (vm.count("cert"))
+    {
+      getCert = true;
+      getId = false;
+    }
+  else if(vm.count("key"))
+    {
+      getKey = true;
+      getId = false;
+    }
+
+  try
+    {
+      KeyChain keyChain;
+      
+      if(getId)
+        {
+          std::vector<Name> defaultList;
+          keyChain.getAllIdentities(defaultList, true);
+          for(int i = 0; i < defaultList.size(); i++)
+            std::cout << "* " << defaultList[i] << std::endl;
+          std::vector<Name> otherList;
+          keyChain.getAllIdentities(otherList, false);
+          for(int i = 0; i < otherList.size(); i++)
+            std::cout << "  " << otherList[i] << std::endl;
+          return 0;
+        }
+      if(getKey)
+        {
+          std::vector<Name> defaultIdList;
+          keyChain.getAllIdentities(defaultIdList, true);
+          for(int i = 0; i < defaultIdList.size(); i++)
+            {
+              std::cout << "* " << defaultIdList[i] << std::endl;
+              std::vector<Name> defaultKeyList;
+              keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], defaultKeyList, true);
+              for(int j = 0; j < defaultKeyList.size(); j++)
+                std::cout << "  +->* " << defaultKeyList[j] << std::endl;
+              std::vector<Name> otherKeyList;
+              keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], otherKeyList, false);
+              for(int j = 0; j < otherKeyList.size(); j++)
+                std::cout << "  +->  " << otherKeyList[j] << std::endl;
+              std::cout << std::endl;
+            }
+          std::vector<Name> otherIdList;
+          keyChain.getAllIdentities(otherIdList, false);
+          for(int i = 0; i < otherIdList.size(); i++)
+            {
+              std::cout << "  " << otherIdList[i] << std::endl;
+              std::vector<Name> defaultKeyList;
+              keyChain.getAllKeyNamesOfIdentity(otherIdList[i], defaultKeyList, true);
+              for(int j = 0; j < defaultKeyList.size(); j++)
+                std::cout << "  +->* " << defaultKeyList[j] << std::endl;
+              std::vector<Name> otherKeyList;
+              keyChain.getAllKeyNamesOfIdentity(otherIdList[i], otherKeyList, false);
+              for(int j = 0; j < otherKeyList.size(); j++)
+                std::cout << "  +->  " << otherKeyList[j] << std::endl;
+              std::cout << std::endl;
+            }
+          return 0;
+        }
+      if(getCert)
+        {
+          std::vector<Name> defaultIdList;
+          keyChain.getAllIdentities(defaultIdList, true);
+          for(int i = 0; i < defaultIdList.size(); i++)
+            {
+              std::cout << "* " << defaultIdList[i] << std::endl;
+              std::vector<Name> defaultKeyList;
+              keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], defaultKeyList, true);
+              for(int j = 0; j < defaultKeyList.size(); j++)
+                {
+                  std::cout << "  +->* " << defaultKeyList[j] << std::endl;
+                  std::vector<Name> defaultCertList;
+                  keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], defaultCertList, true);
+                  for(int k = 0; k < defaultCertList.size(); k++)
+                    std::cout << "       +->* " << defaultCertList[k] << std::endl;
+                  std::vector<Name> otherCertList;
+                  keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], otherCertList, false);
+                  for(int k = 0; k < otherCertList.size(); k++)
+                    std::cout << "       +->  " << otherCertList[k] << std::endl;
+                }
+              std::vector<Name> otherKeyList;
+              keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], otherKeyList, false);
+              for(int j = 0; j < otherKeyList.size(); j++)
+                {
+                  std::cout << "  +->  " << otherKeyList[j] << std::endl;
+                  std::vector<Name> defaultCertList;
+                  keyChain.getAllCertificateNamesOfKey(otherKeyList[j], defaultCertList, true);
+                  for(int k = 0; k < defaultCertList.size(); k++)
+                    std::cout << "       +->* " << defaultCertList[k] << std::endl;
+                  std::vector<Name> otherCertList;
+                  keyChain.getAllCertificateNamesOfKey(otherKeyList[j], otherCertList, false);
+                  for(int k = 0; k < otherCertList.size(); k++)
+                    std::cout << "       +->  " << otherCertList[k] << std::endl;
+                }
+            
+              std::cout << std::endl;
+            }
+          std::vector<Name> otherIdList;
+          keyChain.getAllIdentities(otherIdList, false);
+          for(int i = 0; i < otherIdList.size(); i++)
+            {
+              std::cout << "  " << otherIdList[i] << std::endl;
+              std::vector<Name> defaultKeyList;
+              keyChain.getAllKeyNamesOfIdentity(otherIdList[i], defaultKeyList, true);
+              for(int j = 0; j < defaultKeyList.size(); j++)
+                {
+                  std::cout << "  +->* " << defaultKeyList[j] << std::endl;
+                  std::vector<Name> defaultCertList;
+                  keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], defaultCertList, true);
+                  for(int k = 0; k < defaultCertList.size(); k++)
+                    std::cout << "       +->* " << defaultCertList[k] << std::endl;
+                  std::vector<Name> otherCertList;
+                  keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], otherCertList, false);
+                  for(int k = 0; k < otherCertList.size(); k++)
+                    std::cout << "       +->  " << otherCertList[k] << std::endl;
+                }
+              std::vector<Name> otherKeyList;
+              keyChain.getAllKeyNamesOfIdentity(otherIdList[i], otherKeyList, false);
+              for(int j = 0; j < otherKeyList.size(); j++)
+                {
+                  std::cout << "  +->  " << otherKeyList[j] << std::endl;
+                  std::vector<Name> defaultCertList;
+                  keyChain.getAllCertificateNamesOfKey(otherKeyList[j], defaultCertList, true);
+                  for(int k = 0; k < defaultCertList.size(); k++)
+                    std::cout << "       +->* " << defaultCertList[k] << std::endl;
+                  std::vector<Name> otherCertList;
+                  keyChain.getAllCertificateNamesOfKey(otherKeyList[j], otherCertList, false);
+                  for(int k = 0; k < otherCertList.size(); k++)
+                    std::cout << "       +->  " << otherCertList[k] << std::endl;
+                }
+              std::cout << std::endl;
+            }
+          return 0;
+        }
+      return 1;
+    }
+  catch(const SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(const SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+}
+
+#endif //NDNSEC_LIST_HPP
diff --git a/tools/ndnsec-ls-identity.cpp b/tools/ndnsec-ls-identity.cpp
deleted file mode 100644
index 8570156..0000000
--- a/tools/ndnsec-ls-identity.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#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 <cryptopp/base64.h>
-
-#include "security/key-chain.hpp"
-
-using namespace std;
-using namespace ndn;
-namespace po = boost::program_options;
-
-int main(int argc, char** argv)	
-{
-  bool getId = true;
-  bool getKey = false;
-  bool getCert = false;
-
-  po::options_description desc("General Usage\n  ndn-ls-identity [-h] [-K|C]\nGeneral options");
-  desc.add_options()
-    ("help,h", "produce help message")
-    ("key,K", "granularity: key")
-    ("cert,C", "granularity: certificate")
-    ;
-
-  po::variables_map vm;
-  po::store(po::parse_command_line(argc, argv, desc), vm);
-  po::notify(vm);
-
-  if (vm.count("help")) 
-    {
-      cerr << desc << endl;;
-      return 1;
-    }
-
-  if(vm.count("cert"))
-    {
-      getCert = true;
-      getId = false;
-    }
-  else if(vm.count("key"))
-    {
-      getKey = true;
-      getId = false;
-    }
-
-  KeyChain keyChain;
-
-  if(getId)
-    {
-      vector<Name> defaultList;
-      keyChain.getAllIdentities(defaultList, true);
-      for(int i = 0; i < defaultList.size(); i++)
-	cout << "* " << defaultList[i] << endl;
-      vector<Name> otherList;
-      keyChain.getAllIdentities(otherList, false);
-      for(int i = 0; i < otherList.size(); i++)
-	cout << "  " << otherList[i] << endl;
-      return 0;
-    }
-  if(getKey)
-    {
-      vector<Name> defaultIdList;
-      keyChain.getAllIdentities(defaultIdList, true);
-      for(int i = 0; i < defaultIdList.size(); i++)
-        {
-          cout << "* " << defaultIdList[i] << endl;
-          vector<Name> defaultKeyList;
-          keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], defaultKeyList, true);
-          for(int j = 0; j < defaultKeyList.size(); j++)
-            cout << "  +->* " << defaultKeyList[j] << endl;
-          vector<Name> otherKeyList;
-          keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], otherKeyList, false);
-          for(int j = 0; j < otherKeyList.size(); j++)
-            cout << "  +->  " << otherKeyList[j] << endl;
-          cout << endl;
-        }
-      vector<Name> otherIdList;
-      keyChain.getAllIdentities(otherIdList, false);
-      for(int i = 0; i < otherIdList.size(); i++)
-        {
-          cout << "  " << otherIdList[i] << endl;
-          vector<Name> defaultKeyList;
-          keyChain.getAllKeyNamesOfIdentity(otherIdList[i], defaultKeyList, true);
-          for(int j = 0; j < defaultKeyList.size(); j++)
-            cout << "  +->* " << defaultKeyList[j] << endl;
-          vector<Name> otherKeyList;
-          keyChain.getAllKeyNamesOfIdentity(otherIdList[i], otherKeyList, false);
-          for(int j = 0; j < otherKeyList.size(); j++)
-            cout << "  +->  " << otherKeyList[j] << endl;
-          cout << endl;
-        }
-      return 0;
-    }
-  if(getCert)
-    {
-      vector<Name> defaultIdList;
-      keyChain.getAllIdentities(defaultIdList, true);
-      for(int i = 0; i < defaultIdList.size(); i++)
-        {
-          cout << "* " << defaultIdList[i] << endl;
-          vector<Name> defaultKeyList;
-          keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], defaultKeyList, true);
-          for(int j = 0; j < defaultKeyList.size(); j++)
-            {
-              cout << "  +->* " << defaultKeyList[j] << endl;
-              vector<Name> defaultCertList;
-              keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], defaultCertList, true);
-              for(int k = 0; k < defaultCertList.size(); k++)
-                  cout << "       +->* " << defaultCertList[k] << endl;
-              vector<Name> otherCertList;
-              keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], otherCertList, false);
-              for(int k = 0; k < otherCertList.size(); k++)
-                  cout << "       +->  " << otherCertList[k] << endl;
-            }
-          vector<Name> otherKeyList;
-          keyChain.getAllKeyNamesOfIdentity(defaultIdList[i], otherKeyList, false);
-          for(int j = 0; j < otherKeyList.size(); j++)
-            {
-              cout << "  +->  " << otherKeyList[j] << endl;
-              vector<Name> defaultCertList;
-              keyChain.getAllCertificateNamesOfKey(otherKeyList[j], defaultCertList, true);
-              for(int k = 0; k < defaultCertList.size(); k++)
-                  cout << "       +->* " << defaultCertList[k] << endl;
-              vector<Name> otherCertList;
-              keyChain.getAllCertificateNamesOfKey(otherKeyList[j], otherCertList, false);
-              for(int k = 0; k < otherCertList.size(); k++)
-                  cout << "       +->  " << otherCertList[k] << endl;
-            }
-
-          cout << endl;
-        }
-      vector<Name> otherIdList;
-      keyChain.getAllIdentities(otherIdList, false);
-      for(int i = 0; i < otherIdList.size(); i++)
-        {
-          cout << "  " << otherIdList[i] << endl;
-          vector<Name> defaultKeyList;
-          keyChain.getAllKeyNamesOfIdentity(otherIdList[i], defaultKeyList, true);
-          for(int j = 0; j < defaultKeyList.size(); j++)
-            {
-              cout << "  +->* " << defaultKeyList[j] << endl;
-              vector<Name> defaultCertList;
-              keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], defaultCertList, true);
-              for(int k = 0; k < defaultCertList.size(); k++)
-                  cout << "       +->* " << defaultCertList[k] << endl;
-              vector<Name> otherCertList;
-              keyChain.getAllCertificateNamesOfKey(defaultKeyList[j], otherCertList, false);
-              for(int k = 0; k < otherCertList.size(); k++)
-                  cout << "       +->  " << otherCertList[k] << endl;
-            }
-          vector<Name> otherKeyList;
-          keyChain.getAllKeyNamesOfIdentity(otherIdList[i], otherKeyList, false);
-          for(int j = 0; j < otherKeyList.size(); j++)
-            {
-              cout << "  +->  " << otherKeyList[j] << endl;
-              vector<Name> defaultCertList;
-              keyChain.getAllCertificateNamesOfKey(otherKeyList[j], defaultCertList, true);
-              for(int k = 0; k < defaultCertList.size(); k++)
-                  cout << "       +->* " << defaultCertList[k] << endl;
-              vector<Name> otherCertList;
-              keyChain.getAllCertificateNamesOfKey(otherKeyList[j], otherCertList, false);
-              for(int k = 0; k < otherCertList.size(); k++)
-                  cout << "       +->  " << otherCertList[k] << endl;
-            }
-
-          cout << endl;
-        }
-      return 0;
-    }
-  return 1;
-}
diff --git a/tools/ndnsec-op-tool.hpp b/tools/ndnsec-op-tool.hpp
new file mode 100644
index 0000000..a8d9421
--- /dev/null
+++ b/tools/ndnsec-op-tool.hpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_OP_TOOL_HPP
+#define NDNSEC_OP_TOOL_HPP
+
+#include "ndnsec-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 desc("General options");
+  desc.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(desc).positional(p).run(), vm);
+      po::notify(vm);
+    }
+  catch(std::exception &e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return -1;
+    }
+    
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+  
+  if (0 == vm.count("command"))
+    {
+      std::cerr << "command must be specified" << std::endl;
+      std::cerr << desc << std::endl;
+      return 1;
+    }
+
+  if (command == "sign") // the content to be signed from stdin
+    {
+      try
+        {
+          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());
+        }
+      catch (boost::exception& e)
+        {
+          std::cerr << "ERROR: " << boost::diagnostic_information (e) << std::endl;
+          return -1;
+        }
+      catch (SecTpm::Error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          return -1;
+        }
+      catch (SecPublicInfo::Error& e)
+        {
+          std::cerr << "ERROR: " << e.what() << std::endl;
+          return -1;
+        }
+    }
+
+  return 0;
+}
+
+#endif //NDNSEC_OP_TOOL_HPP
diff --git a/tools/ndnsec-operator-tool.cpp b/tools/ndnsec-operator-tool.cpp
deleted file mode 100644
index 942570e..0000000
--- a/tools/ndnsec-operator-tool.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#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/regex.hpp>
-#include <boost/exception/all.hpp>
-
-#include "security/key-chain.hpp"
-#include "security/signature-sha256-with-rsa.hpp"
-
-using namespace std;
-using namespace ndn;
-namespace po = boost::program_options;
-
-int main(int argc, char** argv)
-{
-  string command;
-  
-  po::options_description desc("General options");
-  desc.add_options()
-    ("help,h", "produce this help message")
-    ("command", po::value<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(desc).positional(p).run(), vm);
-      po::notify(vm);
-    }
-  catch(std::exception &e)
-    {
-      cerr << "ERROR: " << e.what() << endl;
-      return -1;
-    }
-    
-  if (vm.count("help"))
-    {
-      cout << desc << "\n";
-      return 1;
-    }
-  
-  if (0 == vm.count("command"))
-    {
-      cerr << "command must be specified" << endl;
-      cerr << desc << endl;
-      return 1;
-    }
-
-  if (command == "sign") // the content to be signed from stdin
-    {
-      KeyChain keyChain;
-
-      try
-        {
-          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)
-            {
-              cerr << "Error signing with default key" << endl;
-              return -1;
-            }
-
-          cout.write(reinterpret_cast<const char*>(signature.getValue().wire()), signature.getValue().size());
-        }
-      catch (boost::exception &e)
-        {
-          std::cerr << "ERROR: " << boost::diagnostic_information (e) << std::endl;
-          return -1;
-        }
-      catch(std::exception &e)
-        {
-          cerr << "ERROR: " << e.what() << endl;
-          return -1;
-        }
-    }
-
-  return 0;
-}
diff --git a/tools/ndnsec-set-acl.hpp b/tools/ndnsec-set-acl.hpp
new file mode 100644
index 0000000..2d64aca
--- /dev/null
+++ b/tools/ndnsec-set-acl.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_SET_ACL_HPP
+#define NDNSEC_SET_ACL_HPP
+
+#include "ndnsec-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 desc("General Usage\n  ndnsec set-acl [-h] keyName appPath \nGeneral options");
+  desc.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(desc).positional(p).run(), vm);
+      po::notify(vm);
+    }
+  catch (std::exception &e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  try
+    {
+      KeyChain keyChain;
+      keyChain.addAppToACL(keyName, KEY_CLASS_PRIVATE, appPath, ACL_TYPE_PRIVATE);
+
+    }
+  catch(const SecTpm::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+  catch(const SecPublicInfo::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+
+  
+  return 0;
+}
+
+#endif //NDNSEC_SET_ACL_HPP
diff --git a/tools/ndnsec-set-default.cpp b/tools/ndnsec-set-default.cpp
deleted file mode 100644
index 873b15a..0000000
--- a/tools/ndnsec-set-default.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#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 <cryptopp/base64.h>
-
-#include "security/key-chain.hpp"
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-int main(int argc, char** argv)	
-{
-  std::string certFileName;
-  bool setDefaultId = true;
-  bool setDefaultKey = false;
-  bool setDefaultCert = false;
-  std::string name;
-
-  po::options_description desc("General Usage\n  ndn-set-default [-h] [-K|C] name\nGeneral options");
-  desc.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;
-  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
-
-  po::notify(vm);
-
-  if (vm.count("help")) 
-    {
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-
-  KeyChain keyChain;
-
-  if (vm.count("default_key"))
-    {
-      setDefaultKey = true;
-      setDefaultId = false;
-    }
-  else if(vm.count("default_cert"))
-    {
-      setDefaultCert = true;
-      setDefaultId = false;
-    }
-
-  if (setDefaultId)
-    {
-      Name idName(name);
-      keyChain.setDefaultIdentity(idName);
-      return 0;
-    }
-  if (setDefaultKey)
-    {
-      Name keyName(name);
-      keyChain.setDefaultKeyNameForIdentity(keyName);
-      return 0;
-    }
-  
-  if (setDefaultCert)
-    {
-      keyChain.setDefaultCertificateNameForKey(name);
-      return 0;
-    }
-}
diff --git a/tools/ndnsec-set-default.hpp b/tools/ndnsec-set-default.hpp
new file mode 100644
index 0000000..86c831a
--- /dev/null
+++ b/tools/ndnsec-set-default.hpp
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_SET_DEFAULT_HPP
+#define NDNSEC_SET_DEFAULT_HPP
+
+int 
+ndnsec_set_default(int argc, char** argv)	
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string certFileName;
+  bool setDefaultId = true;
+  bool setDefaultKey = false;
+  bool setDefaultCert = false;
+  std::string name;
+
+  po::options_description desc("General Usage\n  ndnsec set-default [-h] [-K|C] name\nGeneral options");
+  desc.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;
+  po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
+
+  po::notify(vm);
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  try
+    {
+      KeyChain keyChain;
+
+      if (vm.count("default_key"))
+        {
+          setDefaultKey = true;
+          setDefaultId = false;
+        }
+      else if(vm.count("default_cert"))
+        {
+          setDefaultCert = true;
+          setDefaultId = false;
+        }
+
+      if (setDefaultId)
+        {
+          Name idName(name);
+          keyChain.setDefaultIdentity(idName);
+          return 0;
+        }
+      if (setDefaultKey)
+        {
+          Name keyName(name);
+          keyChain.setDefaultKeyNameForIdentity(keyName);
+          return 0;
+        }
+
+      if (setDefaultCert)
+        {
+          keyChain.setDefaultCertificateNameForKey(name);
+          return 0;
+        }
+
+      return 1;
+
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << e.what() << std::endl;
+      return 1;
+    }
+
+}
+#endif //NDNSEC_SET_DEFAULT_HPP
diff --git a/tools/ndnsec-sig-verify.cpp b/tools/ndnsec-sig-verify.cpp
deleted file mode 100644
index a6b1b85..0000000
--- a/tools/ndnsec-sig-verify.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options/parsers.hpp>
-
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
-
-#include "security/key-chain.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>(boost::cref(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(ptr_lib::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
-  //     ptr_lib::shared_ptr<Blob> input = ptr_lib::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 main(int argc, char** argv)	
-{
-  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;
-    }
-}
diff --git a/tools/ndnsec-sig-verify.hpp b/tools/ndnsec-sig-verify.hpp
new file mode 100644
index 0000000..fdb6f03
--- /dev/null
+++ b/tools/ndnsec-sig-verify.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_SIG_VERIFY_HPP
+#define NDNSEC_SIG_VERIFY_HPP
+
+#include "ndnsec-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>(boost::cref(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(ptr_lib::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
+//   //     ptr_lib::shared_ptr<Blob> input = ptr_lib::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 //NDNSEC_SIG_VERIFY_HPP
diff --git a/tools/ndnsec-sign-req.cpp b/tools/ndnsec-sign-req.cpp
deleted file mode 100644
index 6aef0b8..0000000
--- a/tools/ndnsec-sign-req.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include <iostream>
-#include <fstream>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options/parsers.hpp>
-#include <cryptopp/base64.h>
-#include <cryptopp/files.h>
-
-#include "security/key-chain.hpp"
-
-using namespace ndn;
-namespace po = boost::program_options;
-
-
-int main(int argc, char** argv)	
-{
-  std::string name;
-  bool isKeyName = false;
-
-  po::options_description desc("General Usage\n  ndn-sign-req [-h] [-k] name\nGeneral options");
-  desc.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(desc).positional(p).run(), vm);
-    po::notify(vm);
-  }
-  catch(const std::exception &e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << desc << std::endl;
-    return 1;
-  }
-
-  if (vm.count("help")) 
-    {
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-
-  if (0 == vm.count("name"))
-    {
-      std::cerr << "identity_name must be specified" << std::endl;
-      std::cerr << desc << std::endl;
-      return 1;
-    }
-  
-  if (vm.count("key"))
-    isKeyName = true;
-    
-  KeyChain keyChain;
-
-  try{
-    if(isKeyName)
-      {
-        shared_ptr<IdentityCertificate> selfSignCert = keyChain.selfSign(name);
-
-        CryptoPP::StringSource ss(selfSignCert->wireEncode().wire(), selfSignCert->wireEncode().size(), true,
-                              new CryptoPP::Base64Encoder(new CryptoPP::FileSink(std::cout), true, 64));
-      }
-    else
-      {
-        Name keyName = keyChain.getDefaultKeyNameForIdentity(name);
-        ptr_lib::shared_ptr<IdentityCertificate> selfSignCert = keyChain.selfSign(keyName);
-
-        CryptoPP::StringSource ss(selfSignCert->wireEncode().wire(), selfSignCert->wireEncode().size(), true,
-                              new CryptoPP::Base64Encoder(new CryptoPP::FileSink(std::cout), true, 64));
-      }
-  }
-  catch(std::exception & e)
-    {
-      std::cerr << "ERROR: " << e.what() << std::endl;
-      return 1;
-    }
-  return 0;
-}
diff --git a/tools/ndnsec-sign-req.hpp b/tools/ndnsec-sign-req.hpp
new file mode 100644
index 0000000..54a5c9a
--- /dev/null
+++ b/tools/ndnsec-sign-req.hpp
@@ -0,0 +1,101 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_SIGN_REQ_HPP
+#define NDNSEC_SIGN_REQ_HPP
+
+#include "ndnsec-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 desc("General Usage\n  ndnsec sign-req [-h] [-k] name\nGeneral options");
+  desc.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(desc).positional(p).run(), vm);
+    po::notify(vm);
+  }
+  catch(const std::exception &e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << desc << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help")) 
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+
+  if (0 == vm.count("name"))
+    {
+      std::cerr << "identity_name must be specified" << std::endl;
+      std::cerr << desc << std::endl;
+      return 1;
+    }
+  
+  if (vm.count("key"))
+    isKeyName = true;
+
+  shared_ptr<IdentityCertificate> selfSignCert;
+
+  try
+    {
+      KeyChain keyChain;
+      
+      if(isKeyName)
+        {
+          selfSignCert = keyChain.selfSign(name);
+        }
+      else
+        {
+          Name keyName = keyChain.getDefaultKeyNameForIdentity(name);
+          selfSignCert = keyChain.selfSign(keyName);
+        }
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  try
+    {
+      using namespace CryptoPP;
+      StringSource ss(selfSignCert->wireEncode().wire(), selfSignCert->wireEncode().size(), true,
+                      new Base64Encoder(new FileSink(std::cout), true, 64));
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  
+  return 0;
+}
+
+#endif //NDNSEC_SIGN_REQ_HPP
diff --git a/tools/ndnsec-unlock-tpm.hpp b/tools/ndnsec-unlock-tpm.hpp
new file mode 100644
index 0000000..3ee4d7c
--- /dev/null
+++ b/tools/ndnsec-unlock-tpm.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_UNLOCK_TPM_HPP
+#define NDNSEC_UNLOCK_TPM_HPP
+
+#include "ndnsec-util.hpp"
+
+int
+ndnsec_unlock_tpm(int argc, char** argv)
+{
+  using namespace ndn;
+  namespace po = boost::program_options;
+
+  std::string keyName; 
+  std::string appPath;
+
+  po::options_description desc("General Usage\n  ndnsec unlock-tpm [-h] \nGeneral options");
+  desc.add_options()
+    ("help,h", "produce help message")
+    ;
+
+  po::variables_map vm;
+  po::store(po::parse_command_line(argc, argv, desc), vm);
+  po::notify(vm);
+
+  if (vm.count("help"))
+    {
+      std::cerr << desc << std::endl;
+      return 0;
+    }
+  
+  bool res = false;
+  
+  try
+    {
+      KeyChain keyChain;
+      
+      char* password;
+      password = getpass("Password to unlock the TPM: ");
+      res = keyChain.unlockTpm(password, strlen(password), true);
+      memset(password, 0, strlen(password));
+
+    }
+  catch(const SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+  catch(const SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return 1;
+    }
+
+  if(res)
+    {
+      std::cerr << "OK: TPM is unlocked" << std::endl;
+      return 0;
+    }
+  else
+    {
+      std::cerr << "ERROR: TPM is still locked" << std::endl;
+      return 1;
+    }
+}
+
+#endif //NDNSEC_UNLOCK_TPM_HPP
diff --git a/tools/ndnsec-util.hpp b/tools/ndnsec-util.hpp
new file mode 100644
index 0000000..2827023
--- /dev/null
+++ b/tools/ndnsec-util.hpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDNSEC_UTIL_HPP
+#define 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 <cryptopp/base64.h>
+#include <cryptopp/files.h>
+
+#include "security/key-chain.hpp"
+
+bool
+getPassword(std::string& password, const std::string& prompt)
+{
+  int result = false;
+
+  char* pw0 = NULL;
+  
+  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))
+    {
+      result = 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 result;
+}
+
+ndn::shared_ptr<ndn::IdentityCertificate>
+getIdentityCertificate(const std::string& fileName)
+{
+  std::istream* ifs;
+  std::istream* ffs = 0;
+  if(fileName == "-")
+    ifs = &std::cin;
+  else
+    {
+      ifs = new std::ifstream(fileName.c_str());
+      ffs = ifs;
+    }
+
+  ndn::OBufferStream os;
+  try
+    {
+      CryptoPP::FileSource ss2(*ifs, true, new CryptoPP::Base64Decoder(new CryptoPP::FileSink(os)));
+      
+      if(ffs)
+        delete ffs;
+      ffs = 0;
+      ifs = 0;
+      
+    }
+  catch(const CryptoPP::Exception& e)
+    {
+      if(ffs)
+        delete ffs;
+      ffs = 0;
+      ifs = 0;
+      
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return ndn::shared_ptr<ndn::IdentityCertificate>();
+    }
+  
+  try
+    {
+      ndn::shared_ptr<ndn::IdentityCertificate> identityCertificate = ndn::make_shared<ndn::IdentityCertificate>();
+      identityCertificate->wireDecode(ndn::Block(os.buf()));
+      return identityCertificate;
+    }
+  catch(const ndn::SecPublicInfo::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return ndn::shared_ptr<ndn::IdentityCertificate>();
+    }
+  catch(const ndn::SecTpm::Error& e)
+    {
+      std::cerr << "ERROR: " << e.what() << std::endl;
+      return ndn::shared_ptr<ndn::IdentityCertificate>();
+    }
+}
+
+#endif //NDNSEC_UTIL_HPP
diff --git a/tools/ndnsec.cpp b/tools/ndnsec.cpp
new file mode 100644
index 0000000..eb0877a
--- /dev/null
+++ b/tools/ndnsec.cpp
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * BSD license, See the LICENSE file for more information
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "ndnsec-util.hpp"
+#include "ndnsec-list.hpp"
+#include "ndnsec-get-default.hpp"
+#include "ndnsec-set-default.hpp"
+#include "ndnsec-key-gen.hpp"
+#include "ndnsec-dsk-gen.hpp"
+#include "ndnsec-sign-req.hpp"
+#include "ndnsec-cert-gen.hpp"
+#include "ndnsec-cert-dump.hpp"
+#include "ndnsec-cert-install.hpp"
+#include "ndnsec-export.hpp"
+#include "ndnsec-import.hpp"
+#include "ndnsec-delete.hpp"
+#include "ndnsec-sig-verify.hpp"
+#include "ndnsec-set-acl.hpp"
+#include "ndnsec-unlock-tpm.hpp"
+#include "ndnsec-op-tool.hpp"
+
+using namespace ndn;
+
+std::string ndnsec_helper("\
+  help         Show all commands.\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-dump    Dump a certificate from PublicInfo.\n\
+  cert-install Install a certificate into PublicInfo.\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)
+{
+  std::string command(argv[1]);
+  
+  if(command == "help") { std::cerr << ndnsec_helper << 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-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 == "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;
+  }
+
+  return 0;
+}
diff --git a/tools/wrapper/ndnsec-cert-dump.sh b/tools/wrapper/ndnsec-cert-dump.sh
new file mode 100644
index 0000000..240a9b3
--- /dev/null
+++ b/tools/wrapper/ndnsec-cert-dump.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec cert-dump "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-cert-gen.sh b/tools/wrapper/ndnsec-cert-gen.sh
new file mode 100644
index 0000000..9479ac5
--- /dev/null
+++ b/tools/wrapper/ndnsec-cert-gen.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec cert-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-cert-install.sh b/tools/wrapper/ndnsec-cert-install.sh
new file mode 100644
index 0000000..4338823
--- /dev/null
+++ b/tools/wrapper/ndnsec-cert-install.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec cert-install "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-certgen.sh b/tools/wrapper/ndnsec-certgen.sh
new file mode 100644
index 0000000..c31d1b2
--- /dev/null
+++ b/tools/wrapper/ndnsec-certgen.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec cert-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-delete.sh b/tools/wrapper/ndnsec-delete.sh
new file mode 100644
index 0000000..5d8a05c
--- /dev/null
+++ b/tools/wrapper/ndnsec-delete.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec delete "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-dsk-gen.sh b/tools/wrapper/ndnsec-dsk-gen.sh
new file mode 100644
index 0000000..31e485c
--- /dev/null
+++ b/tools/wrapper/ndnsec-dsk-gen.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec dsk-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-dskgen.sh b/tools/wrapper/ndnsec-dskgen.sh
new file mode 100644
index 0000000..c256026
--- /dev/null
+++ b/tools/wrapper/ndnsec-dskgen.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec dsk-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-dump-certificate.sh b/tools/wrapper/ndnsec-dump-certificate.sh
new file mode 100644
index 0000000..c0e7c08
--- /dev/null
+++ b/tools/wrapper/ndnsec-dump-certificate.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec cert-dump "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-export.sh b/tools/wrapper/ndnsec-export.sh
new file mode 100644
index 0000000..50b7229
--- /dev/null
+++ b/tools/wrapper/ndnsec-export.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec export "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-get-default.sh b/tools/wrapper/ndnsec-get-default.sh
new file mode 100644
index 0000000..d1ef31d
--- /dev/null
+++ b/tools/wrapper/ndnsec-get-default.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec get-default "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-import.sh b/tools/wrapper/ndnsec-import.sh
new file mode 100644
index 0000000..e05774e
--- /dev/null
+++ b/tools/wrapper/ndnsec-import.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec import "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-install-cert.sh b/tools/wrapper/ndnsec-install-cert.sh
new file mode 100644
index 0000000..e89744a
--- /dev/null
+++ b/tools/wrapper/ndnsec-install-cert.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec cert-install "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-key-gen.sh b/tools/wrapper/ndnsec-key-gen.sh
new file mode 100644
index 0000000..0e3bde9
--- /dev/null
+++ b/tools/wrapper/ndnsec-key-gen.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec key-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-keygen.sh b/tools/wrapper/ndnsec-keygen.sh
new file mode 100644
index 0000000..6dd142d
--- /dev/null
+++ b/tools/wrapper/ndnsec-keygen.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec key-gen "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-list.sh b/tools/wrapper/ndnsec-list.sh
new file mode 100644
index 0000000..454ac6e
--- /dev/null
+++ b/tools/wrapper/ndnsec-list.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec list "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-ls-identity.sh b/tools/wrapper/ndnsec-ls-identity.sh
new file mode 100644
index 0000000..4f173bf
--- /dev/null
+++ b/tools/wrapper/ndnsec-ls-identity.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec list "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-op-tool.sh b/tools/wrapper/ndnsec-op-tool.sh
new file mode 100644
index 0000000..2db363d
--- /dev/null
+++ b/tools/wrapper/ndnsec-op-tool.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec op-tool "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-operator-tool.sh b/tools/wrapper/ndnsec-operator-tool.sh
new file mode 100644
index 0000000..503d0ea
--- /dev/null
+++ b/tools/wrapper/ndnsec-operator-tool.sh
@@ -0,0 +1,4 @@
+#!@SH@
+
+#to accomodate the old command
+`dirname "$0"`/ndnsec op-tool "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-set-acl.sh b/tools/wrapper/ndnsec-set-acl.sh
new file mode 100644
index 0000000..5a651fd
--- /dev/null
+++ b/tools/wrapper/ndnsec-set-acl.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec set-acl "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-set-default.sh b/tools/wrapper/ndnsec-set-default.sh
new file mode 100644
index 0000000..dfcd03b
--- /dev/null
+++ b/tools/wrapper/ndnsec-set-default.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec set-default "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-sig-verify.sh b/tools/wrapper/ndnsec-sig-verify.sh
new file mode 100644
index 0000000..214fcfb
--- /dev/null
+++ b/tools/wrapper/ndnsec-sig-verify.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec sig-verify "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-sign-req.sh b/tools/wrapper/ndnsec-sign-req.sh
new file mode 100644
index 0000000..15aef6c
--- /dev/null
+++ b/tools/wrapper/ndnsec-sign-req.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec sign-req "$@"
\ No newline at end of file
diff --git a/tools/wrapper/ndnsec-unlock-tpm.sh b/tools/wrapper/ndnsec-unlock-tpm.sh
new file mode 100644
index 0000000..ec8d0a9
--- /dev/null
+++ b/tools/wrapper/ndnsec-unlock-tpm.sh
@@ -0,0 +1,3 @@
+#!@SH@
+
+`dirname "$0"`/ndnsec unlock-tpm "$@"
\ No newline at end of file
diff --git a/tools/wscript b/tools/wscript
index be76916..bc28425 100644
--- a/tools/wscript
+++ b/tools/wscript
@@ -2,6 +2,9 @@
 
 top = '..'
 
+def configure(conf):
+    conf.find_program('sh')
+
 def build(bld):
     for app in bld.path.ant_glob('*.cpp'):
         bld(features=['cxx', 'cxxprogram'],
@@ -9,3 +12,10 @@
             source = app,
             use = 'ndn-cpp-dev',
             )        
+
+    bld (features = "subst",
+         source = bld.path.ant_glob(['wrapper/*.sh']),
+         target = ['%s' % node.change_ext('', '.sh') for node in bld.path.ant_glob(['wrapper/*.sh'])],
+         install_path = "${BINDIR}",
+         chmod = 0755,
+        )