tools: Convert ndnsec to v2::KeyChain

This commit removes the following tools:
- cert-revoke (wasn't working properly before and need a new
  design)
- set-acl (wasn't working before)
- dsk-gen (no longer makes sense with the new certificate naming
  conventions, new tools for creating derivative certificates will
  be created later)

This commit also fixes Bug #3644 causing import command to ask for
unnecessary password confirmation.

ndnsec main now catch all exceptions logs the extended message

Change-Id: Ib50e0994970020bcf0a1840aca6bc3942818094b
Refs: #3098, #3644
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 83c34a3..60f57b1 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.cpp
@@ -124,41 +124,50 @@
     return 1;
   }
 
-  shared_ptr<security::v1::IdentityCertificate> certificate;
+  security::v2::Certificate certificate;
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
 
-  if (isIdentityName || isKeyName || isCertName) {
-    if (isIdentityName) {
-      Name certName = keyChain.getDefaultCertificateNameForIdentity(name);
-      certificate = keyChain.getCertificate(certName);
+  try {
+    if (isIdentityName || isKeyName || isCertName) {
+      if (isIdentityName) {
+        certificate = keyChain.getPib()
+          .getIdentity(name)
+          .getDefaultKey()
+          .getDefaultCertificate();
+      }
+      else if (isKeyName) {
+        certificate = keyChain.getPib()
+          .getIdentity(security::v2::extractIdentityFromKeyName(name))
+          .getKey(name)
+          .getDefaultCertificate();
+      }
+      else {
+        certificate = keyChain.getPib()
+          .getIdentity(security::v2::extractIdentityFromCertName(name))
+          .getKey(security::v2::extractKeyNameFromCertName(name))
+          .getDefaultCertificate();
+      }
     }
-    else if (isKeyName) {
-      Name certName = keyChain.getDefaultCertificateNameForKey(name);
-      certificate = keyChain.getCertificate(certName);
-    }
-    else
-      certificate = keyChain.getCertificate(name);
-
-    if (certificate == nullptr) {
-      std::cerr << "No certificate found!" << std::endl;
-      return 1;
+    else {
+      certificate = loadCertificate(name);
     }
   }
-  else {
-    certificate = getIdentityCertificate(name);
-    if (certificate == nullptr) {
-      std::cerr << "No certificate read!" << std::endl;
-      return 1;
-    }
+  catch (const security::Pib::Error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+  catch (const CannotLoadCertificate&) {
+    std::cerr << "Cannot load certificate from `" << name << "`" << std::endl;
+    return 1;
   }
 
   if (isPretty) {
-    std::cout << *certificate << std::endl;
+    std::cout << certificate << std::endl;
   }
   else {
     if (isStdOut) {
-      io::save(*certificate, std::cout);
+      io::save(certificate, std::cout);
       return 0;
     }
     if (isRepoOut) {
@@ -170,8 +179,8 @@
         std::cerr << "fail to open the stream!" << std::endl;
         return 1;
       }
-      request_stream.write(reinterpret_cast<const char*>(certificate->wireEncode().wire()),
-                           certificate->wireEncode().size());
+      request_stream.write(reinterpret_cast<const char*>(certificate.wireEncode().wire()),
+                           certificate.wireEncode().size());
 
       return 0;
     }
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index f1b2512..c1f8868 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -32,22 +32,20 @@
   using boost::escaped_list_separator;
 
   namespace po = boost::program_options;
+  namespace t = security::transform;
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
 
   std::string notBeforeStr;
   std::string notAfterStr;
-  std::string subjectName;
   std::string requestFile("-");
   Name signId;
-  std::string subjectInfo;
-  std::vector<std::string> signedInfo;
-  Name certPrefix = security::v1::KeyChain::DEFAULT_PREFIX; // to avoid displaying the default value
+  std::vector<std::string> infos;
+  std::string issuerId;
 
   po::options_description description(
     "General Usage\n"
-    "  ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] "
-        "[-s sign-id] [-p cert-prefix] request\n"
+    "  ndnsec cert-gen [-h] [-S date] [-E date] [-I info] [-s sign-id] request\n"
     "General options");
 
   description.add_options()
@@ -56,22 +54,17 @@
                        "certificate starting date, YYYYMMDDhhmmss (default: now)")
     ("not-after,E",    po::value<std::string>(&notAfterStr),
                        "certificate ending date, YYYYMMDDhhmmss (default: now + 365 days)")
-    ("subject-name,N", po::value<std::string>(&subjectName),
-                       "subject name")
-    ("subject-info,I", po::value<std::string>(&subjectInfo),
-                       "(deprecated, uses 'signed-info') subject info, pairs of OID and string "
-                       " description: \"2.5.4.10 'University of California, Los Angeles'\"")
-    ("signed-info",    po::value<std::vector<std::string> >(&signedInfo),
-                       "a pair of OID and string (must be separated by a single space), e.g., "
-                       "\"2.5.4.10 University of California, Los Angeles\". "
+    ("info,I",         po::value<std::vector<std::string>>(&infos),
+                       "key and value (must be separated by a single space) of the additional "
+                       "description to be included in the issued certificate, e.g., "
+                       "\"affiliation University of California, Los Angeles\". "
                        "May be repeated multiple times")
-    ("sign-id,s",      po::value<Name>(&signId)->default_value(keyChain.getDefaultIdentity()),
+    ("sign-id,s",      po::value<Name>(&signId),
                        "signing identity")
-    ("cert-prefix,p",  po::value<Name>(&certPrefix),
-                       "cert prefix, which is the part of certificate name before "
-                       "KEY component")
     ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
                        "request file name, - for stdin")
+    ("issuer-id,i",    po::value<std::string>(&issuerId)->default_value("NA"),
+                       "issuer's ID to be included as part of the issued certificate name")
     ;
 
   po::positional_options_description p;
@@ -99,44 +92,18 @@
     return 1;
   }
 
-  std::vector<security::v1::CertificateSubjectDescription> subjectDescription;
-  subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName));
+  security::v2::AdditionalDescription additionalDescription;
 
-  // 'subjectInfo' is deprecated and the following block will be removed eventually
-  tokenizer<escaped_list_separator<char>> subjectInfoItems(subjectInfo,
-                                                           escaped_list_separator<char>("\\", " \t",
-                                                                                        "'\""));
-
-  tokenizer<escaped_list_separator<char>>::iterator it = subjectInfoItems.begin();
-
-  while (it != subjectInfoItems.end()) {
-    std::string oid = *it;
-
-    it++;
-    if (it == subjectInfoItems.end()) {
-      std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl;
-      return 1;
-    }
-
-    std::string value = *it;
-
-    subjectDescription.push_back(security::v1::CertificateSubjectDescription(Oid(oid), value));
-
-    it++;
-  }
-
-  // new 'signedInfo' processing
-  for (std::vector<std::string>::const_iterator info = signedInfo.begin(); info != signedInfo.end();
-       ++info) {
-    size_t pos = info->find(" ");
+  for (const auto& info : infos) {
+    size_t pos = info.find(" ");
     if (pos == std::string::npos) {
-      std::cerr << "ERROR: incorrectly formatted signed info block [" << *info << "]" << std::endl;
+      std::cerr << "ERROR: incorrectly formatted info block [" << info << "]" << std::endl;
       return 1;
     }
-    Oid oid(info->substr(0, pos));
-    std::string value = info->substr(pos + 1);
+    std::string key = info.substr(0, pos);
+    std::string value = info.substr(pos + 1);
 
-    subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid, value));
+    additionalDescription.set(key, value);
   }
 
   time::system_clock::TimePoint notBefore;
@@ -170,39 +137,52 @@
     return 1;
   }
 
-  shared_ptr<security::v1::IdentityCertificate> selfSignedCertificate = getIdentityCertificate(requestFile);
+  security::v2::Certificate certRequest = loadCertificate(requestFile);
 
-  if (selfSignedCertificate == nullptr) {
-    std::cerr << "ERROR: input error" << std::endl;
+  // validate that the content is a public key
+  try {
+    Buffer keyContent = certRequest.getPublicKey();
+    t::PublicKey pubKey;
+    pubKey.loadPkcs8(keyContent.buf(), keyContent.size());
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
     return 1;
   }
 
-  Name keyName = selfSignedCertificate->getPublicKeyName();
+  security::v2::Certificate cert;
 
-  shared_ptr<security::v1::IdentityCertificate> certificate =
-    keyChain.prepareUnsignedIdentityCertificate(keyName, selfSignedCertificate->getPublicKeyInfo(),
-                                                signId, notBefore, notAfter, subjectDescription,
-                                                certPrefix);
+  Name certName = certRequest.getKeyName();
+  certName
+    .append(issuerId)
+    .appendVersion();
 
-  if (certificate == nullptr) {
-    std::cerr << "ERROR: key name is not formated correctly or does not match certificate name"
-              << std::endl;
-    return 1;
+  cert.setName(certName);
+  cert.setContent(certRequest.getContent());
+
+  // @TODO add ability to customize
+  cert.setFreshnessPeriod(time::hours(1));
+
+  SignatureInfo signatureInfo;
+  signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
+
+  security::Identity identity;
+  if (vm.count("sign-id") == 0) {
+    identity = keyChain.getPib().getDefaultIdentity();
+  }
+  else {
+    identity = keyChain.getPib().getIdentity(signId);
   }
 
-  keyChain.createIdentity(signId);
-  Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signId);
-  keyChain.sign(*certificate,
-                security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT,
-                                      signingCertificateName));
+  keyChain.sign(cert, security::SigningInfo(identity).setSignatureInfo(signatureInfo));
 
-  Block wire = certificate->wireEncode();
+  Block wire = cert.wireEncode();
 
-  namespace t = security::transform;
+
   try {
     t::bufferSource(wire.wire(), wire.size()) >> t::base64Encode(true) >> t::streamSink(std::cout);
   }
-  catch (const security::transform::Error& e) {
+  catch (const t::Error& e) {
     std::cerr << "ERROR: " << e.what() << std::endl;
     return 1;
   }
diff --git a/tools/ndnsec/cert-install.cpp b/tools/ndnsec/cert-install.cpp
index 72a82bd..c506a53 100644
--- a/tools/ndnsec/cert-install.cpp
+++ b/tools/ndnsec/cert-install.cpp
@@ -35,7 +35,7 @@
   }
 };
 
-shared_ptr<security::v1::IdentityCertificate>
+security::v2::Certificate
 getCertificateHttp(const std::string& host, const std::string& port, const std::string& path)
 {
   using namespace boost::asio::ip;
@@ -84,17 +84,12 @@
     streamSource(requestStream) >> base64Decode(true) >> streamSink(os);
   }
 
-  auto identityCertificate = std::make_shared<security::v1::IdentityCertificate>();
-  identityCertificate->wireDecode(ndn::Block(os.buf()));
-
-  return identityCertificate;
+  return security::v2::Certificate(Block(os.buf()));
 }
 
 int
 ndnsec_cert_install(int argc, char** argv)
 {
-  using namespace ndn;
-  using namespace ndn::security;
   namespace po = boost::program_options;
 
   std::string certFileName;
@@ -149,8 +144,9 @@
     isSystemDefault = false;
   }
 
-  shared_ptr<security::v1::IdentityCertificate> cert;
+  security::v2::Certificate cert;
 
+  try {
   if (certFileName.find("http://") == 0) {
     std::string host;
     std::string port;
@@ -179,32 +175,42 @@
     cert = getCertificateHttp(host, port, path);
   }
   else {
-    cert = getIdentityCertificate(certFileName);
+    cert = loadCertificate(certFileName);
+  }
+  }
+  catch (const CannotLoadCertificate&) {
+    std::cerr << "ERROR: Cannot load the certificate " << certFileName << std::endl;
+    return 1;
   }
 
-  if (cert == nullptr)
-    return 1;
+  security::v2::KeyChain keyChain;
+  security::Identity id;
+  security::Key key;
+  try {
+    id = keyChain.getPib().getIdentity(cert.getIdentity());
+    key = id.getKey(cert.getKeyName());
+  }
+  catch (const security::Pib::Error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+  }
 
-  security::v1::KeyChain keyChain;
+  keyChain.addCertificate(key, cert);
 
   if (isSystemDefault) {
-    keyChain.addCertificateAsIdentityDefault(*cert);
-    Name keyName = cert->getPublicKeyName();
-    Name identity = keyName.getSubName(0, keyName.size() - 1);
-    keyChain.setDefaultIdentity(identity);
+    keyChain.setDefaultIdentity(id);
+    keyChain.setDefaultKey(id, key);
+    keyChain.setDefaultCertificate(key, cert);
   }
   else if (isIdentityDefault) {
-    keyChain.addCertificateAsIdentityDefault(*cert);
+    keyChain.setDefaultKey(id, key);
+    keyChain.setDefaultCertificate(key, cert);
   }
   else if (isKeyDefault) {
-    keyChain.addCertificateAsKeyDefault(*cert);
-  }
-  else {
-    keyChain.addCertificate(*cert);
+    keyChain.setDefaultCertificate(key, cert);
   }
 
-  std::cerr << "OK: certificate with name [" << cert->getName().toUri()
-            << "] has been successfully installed" << std::endl;
+  std::cerr << "OK: certificate with name [" << cert.getName().toUri() << "] "
+            << "has been successfully installed" << std::endl;
 
   return 0;
 }
diff --git a/tools/ndnsec/cert-revoke.cpp b/tools/ndnsec/cert-revoke.cpp
deleted file mode 100644
index f7de148..0000000
--- a/tools/ndnsec/cert-revoke.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_cert_revoke(int argc, char** argv)
-{
-  using namespace ndn;
-  using namespace ndn::security;
-  namespace po = boost::program_options;
-
-  security::v1::KeyChain keyChain;
-
-  std::string requestFile("-");
-  Name signId = keyChain.getDefaultIdentity();
-  bool hasSignId = false;
-  Name certPrefix = security::v1::KeyChain::DEFAULT_PREFIX;
-
-  po::options_description description("General Usage\n  ndnsec cert-revoke [-h] request\n"
-                                      "General options");
-  description.add_options()
-    ("help,h", "produce help message")
-    ("sign-id,s",     po::value<Name>(&signId),
-                      "signing identity (default: use the same as in the revoked certificate)")
-    ("cert-prefix,p", po::value<Name>(&certPrefix),
-                      "cert prefix, which is the part of certificate name before "
-                      "KEY component (default: use the same as in the revoked certificate)")
-    ("request,r",     po::value<std::string>(&requestFile)->default_value("-"),
-                      "request file name, - for stdin")
-    ;
-
-  po::positional_options_description p;
-  p.add("request", 1);
-
-  po::variables_map vm;
-  try {
-    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
-    po::notify(vm);
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
-  }
-
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
-    return 0;
-  }
-
-  hasSignId = (vm.count("sign-id") != 0);
-
-  if (vm.count("request") == 0) {
-    std::cerr << "request file must be specified" << std::endl;
-    return 1;
-  }
-
-  shared_ptr<security::v1::IdentityCertificate> revokedCertificate = getIdentityCertificate(requestFile);
-
-  if (revokedCertificate == nullptr) {
-    std::cerr << "ERROR: input error" << std::endl;
-    return 1;
-  }
-
-  Block wire;
-
-  try {
-    Name keyName;
-
-    if (hasSignId) {
-      keyName = keyChain.getDefaultKeyNameForIdentity(signId);
-    }
-    else {
-      const Signature& signature = revokedCertificate->getSignature();
-      if (!signature.hasKeyLocator() ||
-          signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name) {
-        std::cerr << "ERROR: Invalid certificate to revoke" << std::endl;
-        return 1;
-      }
-
-      keyName = security::v1::IdentityCertificate::certificateNameToPublicKeyName(signature.getKeyLocator().getName());
-    }
-
-    Name certName;
-    if (certPrefix == security::v1::KeyChain::DEFAULT_PREFIX) {
-      certName = revokedCertificate->getName().getPrefix(-1);
-    }
-    else {
-      Name revokedKeyName = revokedCertificate->getPublicKeyName();
-
-      if (certPrefix.isPrefixOf(revokedKeyName) && certPrefix != revokedKeyName) {
-        certName.append(certPrefix)
-          .append("KEY")
-          .append(revokedKeyName.getSubName(certPrefix.size()))
-          .append("ID-CERT");
-      }
-      else {
-        std::cerr << "ERROR: certificate prefix does not match the revoked certificate" << std::endl;
-        return 1;
-      }
-    }
-    certName.appendVersion().append("REVOKED");
-
-    Data revocationCert;
-    revocationCert.setName(certName);
-
-    if (keyChain.doesPublicKeyExist(keyName)) {
-      Name signingCertificateName = keyChain.getDefaultCertificateNameForKey(keyName);
-      keyChain.sign(revocationCert,
-                    SigningInfo(SigningInfo::SIGNER_TYPE_CERT, signingCertificateName));
-    }
-    else {
-      std::cerr << "ERROR: Cannot find the signing key!" << std::endl;
-      return 1;
-    }
-
-    wire = revocationCert.wireEncode();
-  }
-  catch (const Signature::Error& e) {
-    std::cerr << "ERROR: No valid signature!" << std::endl;
-    return 1;
-  }
-  catch (const KeyLocator::Error& e) {
-    std::cerr << "ERROR: No valid KeyLocator!" << std::endl;
-    return 1;
-  }
-  catch (const security::v1::IdentityCertificate::Error& e) {
-    std::cerr << "ERROR: Cannot determine the signing key!" << std::endl;
-    return 1;
-  }
-  catch (const security::v1::SecPublicInfo::Error& e) {
-    std::cerr << "ERROR: Incomplete or corrupted PIB (" << e.what() << ")" << std::endl;
-    return 1;
-  }
-
-  try {
-    transform::bufferSource(wire.wire(), wire.size()) >> transform::base64Encode(true) >>
-      transform::streamSink(std::cout);
-  }
-  catch (const transform::Error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
-  }
-
-  return 0;
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/delete.cpp b/tools/ndnsec/delete.cpp
index cfda520..8c08cf0 100644
--- a/tools/ndnsec/delete.cpp
+++ b/tools/ndnsec/delete.cpp
@@ -28,7 +28,6 @@
 int
 ndnsec_delete(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
   bool isDeleteKey = false;
@@ -41,9 +40,7 @@
   description.add_options()
     ("help,h", "produce help message")
     ("delete-key,k", "(Optional) delete a key if specified.")
-    ("delete-key2,K", "(Optional) delete a key if specified.")
     ("delete-cert,c", "(Optional) delete a certificate if specified.")
-    ("delete-cert2,C", "(Optional) delete a certificate if specified.")
     ("name,n", po::value<std::string>(&name), "By default, it refers to an identity."
      "If -k is specified, it refers to a key."
      "If -c is specified, it refers to a certificate.");
@@ -74,52 +71,45 @@
     return 2;
   }
 
-  if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0)
+  if (vm.count("delete-cert") != 0) {
     isDeleteCert = true;
-
-  else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0)
+  }
+  else if (vm.count("delete-key") != 0) {
     isDeleteKey = true;
+  }
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
 
   try {
     if (isDeleteCert) {
-      if (!keyChain.doesCertificateExist(name)) {
-        std::cerr << "ERROR: Certificate does not exist: " << name << std::endl;
-        return 1;
-      }
+      security::Key key = keyChain.getPib()
+        .getIdentity(security::v2::extractIdentityFromCertName(name))
+        .getKey(security::v2::extractKeyNameFromCertName(name));
 
-      keyChain.deleteCertificate(name);
+      keyChain.deleteCertificate(key, key.getCertificate(name).getName());
       std::cerr << "OK: Delete certificate: " << name << std::endl;
     }
     else if (isDeleteKey) {
-      if (!keyChain.doesPublicKeyExist(name) && !keyChain.doesKeyExistInTpm(name, KeyClass::PRIVATE)) {
-        std::cerr << "ERROR: Key does not exist: " << name << std::endl;
-        return 1;
-      }
+      security::Identity identity = keyChain.getPib()
+        .getIdentity(security::v2::extractIdentityFromKeyName(name));
 
-      keyChain.deleteKey(name);
+      keyChain.deleteKey(identity, identity.getKey(name));
       std::cerr << "OK: Delete key: " << name << std::endl;
     }
     else {
-      if (!keyChain.doesIdentityExist(name)) {
-        std::cerr << "ERROR: Identity does not exist: " << name << std::endl;
-        return 1;
-      }
-
-      keyChain.deleteIdentity(name);
+      keyChain.deleteIdentity(keyChain.getPib().getIdentity(name));
       std::cerr << "OK: Delete identity: " << name << std::endl;
     }
   }
-  catch (const security::v1::SecPublicInfo::Error& e) {
+  catch (const security::Pib::Error& e) {
     std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
     return 2;
   }
-  catch (const security::v1::SecTpm::Error& e) {
+  catch (const security::Tpm::Error& e) {
     std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
     return 2;
   }
-  catch (const security::v1::KeyChain::Error& e) {
+  catch (const security::v2::KeyChain::Error& e) {
     std::cerr << "ERROR: " << e.what() << std::endl;
     return 2;
   }
diff --git a/tools/ndnsec/dsk-gen.cpp b/tools/ndnsec/dsk-gen.cpp
deleted file mode 100644
index a9109ee..0000000
--- a/tools/ndnsec/dsk-gen.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_dsk_gen(int argc, char** argv)
-{
-  using namespace ndn;
-  using namespace ndn::security;
-  namespace po = boost::program_options;
-
-  std::string identityName;
-  char keyType = 'r';
-
-  po::options_description description("General Usage\n"
-                                      "  ndnsec dsk-gen [-h] [-t keyType] identity\n"
-                                      "General options");
-  description.add_options()
-    ("help,h", "produce help message")
-    ("identity,i", po::value<std::string>(&identityName),
-     "identity name, for example, /ndn/ucla.edu/alice")
-    ("type,t", po::value<char>(&keyType)->default_value('r'),
-     "optional, key type, r for RSA key (default), e for EC key.")
-    // ("size,s", po::value<int>(&keySize)->default_value(2048),
-    //  "optional, key size, 2048 (default)")
-    ;
-
-  po::positional_options_description p;
-  p.add("identity", 1);
-
-  po::variables_map vm;
-  try {
-    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
-    po::notify(vm);
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
-    return 0;
-  }
-
-  if (vm.count("identity") == 0) {
-    std::cerr << "identity must be specified" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  shared_ptr<security::v1::IdentityCertificate> kskCert;
-  Name signingCertName;
-
-  security::v1::KeyChain keyChain;
-
-  try {
-    Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
-    bool isDefaultDsk = false;
-    std::string keyUsageTag = defaultCertName.get(-3).toUri().substr(0, 4);
-    if (keyUsageTag == "ksk-")
-      isDefaultDsk = false;
-    else if (keyUsageTag == "dsk-")
-      isDefaultDsk = true;
-    else {
-      std::cerr << "ERROR: Unknown key usage tag: " << keyUsageTag << std::endl;
-      return 1;
-    }
-
-    if (isDefaultDsk) {
-      shared_ptr<security::v1::IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
-
-      if (dskCert != nullptr) {
-        SignatureSha256WithRsa sha256sig(dskCert->getSignature());
-
-        Name keyLocatorName = sha256sig.getKeyLocator().getName();
-
-        Name kskName = security::v1::IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-        Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
-        signingCertName = kskCertName;
-        kskCert = keyChain.getCertificate(kskCertName);
-      }
-      else {
-        std::cerr << "ERROR: The default certificate is missing." << std::endl;
-        return 1;
-      }
-    }
-    else {
-      signingCertName = defaultCertName;
-      kskCert = keyChain.getCertificate(defaultCertName);
-    }
-
-    if (kskCert == nullptr) {
-      std::cerr << "ERROR: KSK certificate is missing." << std::endl;
-      return 1;
-    }
-
-    Name newKeyName;
-    switch (keyType) {
-      case 'r': {
-        RsaKeyParams params;
-        newKeyName = keyChain.generateRsaKeyPair(Name(identityName), false, params.getKeySize());
-        if (0 == newKeyName.size()) {
-          std::cerr << "ERROR: Fail to generate RSA key!" << std::endl;
-          return 1;
-        }
-        break;
-      }
-      case 'e': {
-        EcKeyParams params;
-        newKeyName = keyChain.generateEcKeyPair(Name(identityName), false, params.getKeySize());
-        if (0 == newKeyName.size()) {
-          std::cerr << "ERROR: Fail to generate EC key!" << std::endl;
-          return 1;
-        }
-        break;
-      }
-      default:
-        std::cerr << "ERROR: Unrecongized key type"
-                  << "\n";
-        std::cerr << description << std::endl;
-        return 1;
-    }
-
-    Name certName = newKeyName.getPrefix(-1);
-    certName.append("KEY").append(newKeyName.get(-1)).append("ID-CERT").appendVersion();
-
-    shared_ptr<security::v1::IdentityCertificate> certificate =
-      keyChain.prepareUnsignedIdentityCertificate(newKeyName,
-                                                  Name(identityName),
-                                                  kskCert->getNotBefore(),
-                                                  kskCert->getNotAfter(),
-                                                  kskCert->getSubjectDescriptionList());
-
-    if (certificate != nullptr)
-      certificate->encode();
-    else {
-      std::cerr << "ERROR: Cannot format the certificate of the requested dsk."
-                << "\n";
-      return 1;
-    }
-
-    keyChain.sign(*certificate,
-                  security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT, signingCertName));
-
-    keyChain.addCertificateAsIdentityDefault(*certificate);
-
-    std::cerr << "OK: dsk certificate with name [" << certificate->getName()
-              << "] has been successfully installed\n";
-    return 0;
-  }
-  catch (const std::runtime_error& e) {
-    std::cerr << "ERROR: other runtime errors: " << e.what() << "\n";
-    return 1;
-  }
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/export.cpp b/tools/ndnsec/export.cpp
index 9b7a0e9..4de938e 100644
--- a/tools/ndnsec/export.cpp
+++ b/tools/ndnsec/export.cpp
@@ -28,20 +28,17 @@
 int
 ndnsec_export(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
-  std::string identityStr;
+  Name identityName;
   std::string output;
   std::string exportPassword;
-  bool isPrivateExport = false;
 
   po::options_description description("General Usage\n  ndnsec export [-h] [-o output] [-p] identity \nGeneral options");
   description.add_options()
     ("help,h", "Produce help message")
     ("output,o", po::value<std::string>(&output), "(Optional) output file, stdout if not specified")
-    ("private,p", "export info contains private key")
-    ("identity,i", po::value<std::string>(&identityStr), "Identity to export")
+    ("identity,i", po::value<Name>(&identityName), "Identity to export")
     ;
 
   po::positional_options_description p;
@@ -69,55 +66,39 @@
     return 1;
   }
 
-  if (vm.count("private") != 0)
-    isPrivateExport = true;
-
   if (vm.count("output") == 0)
     output = "-";
 
-  Name identity(identityStr);
-  if (!isPrivateExport) {
-    security::v1::KeyChain keyChain;
-    shared_ptr<security::v1::IdentityCertificate> cert =
-      keyChain.getCertificate(keyChain.getDefaultCertificateNameForIdentity(identity));
+  try {
+    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;
+      }
+    }
+
+    security::v2::KeyChain keyChain;
+    security::Identity id = keyChain.getPib().getIdentity(identityName);
+
+    // @TODO export all certificates, selected key pair, selected certificate
+    shared_ptr<security::SafeBag> safeBag = keyChain.exportSafeBag(id.getDefaultKey().getDefaultCertificate(),
+                                                                   exportPassword.c_str(), exportPassword.size());
+    memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
 
     if (output == "-")
-      io::save(*cert, std::cout);
+      io::save(*safeBag, std::cout);
     else
-      io::save(*cert, output);
+      io::save(*safeBag, output);
 
     return 0;
   }
-  else {
-    Block wire;
-    try {
-      security::v1::KeyChain keyChain;
-
-      int count = 3;
-      while (!getPassword(exportPassword, "Passphrase for the private key: ")) {
-        count--;
-        if (count <= 0) {
-          std::cerr << "ERROR: invalid password" << std::endl;
-          memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
-          return 1;
-        }
-      }
-      shared_ptr<security::v1::SecuredBag> securedBag =
-        keyChain.exportIdentity(identity, exportPassword);
-      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
-
-      if (output == "-")
-        io::save(*securedBag, std::cout);
-      else
-        io::save(*securedBag, output);
-
-      return 0;
-    }
-    catch (const std::runtime_error& e) {
-      std::cerr << "ERROR: " << e.what() << std::endl;
-      memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
-      return 1;
-    }
+  catch (const std::runtime_error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
+    return 1;
   }
 }
 
diff --git a/tools/ndnsec/get-default.cpp b/tools/ndnsec/get-default.cpp
index 96ee12e..0e2b499 100644
--- a/tools/ndnsec/get-default.cpp
+++ b/tools/ndnsec/get-default.cpp
@@ -28,15 +28,14 @@
 int
 ndnsec_get_default(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
   bool isGetDefaultId = true;
   bool isGetDefaultKey = false;
   bool isGetDefaultCert = false;
   bool isQuiet = false;
-  std::string identityString;
-  std::string keyName;
+  Name identityName;
+  Name keyName;
 
   po::options_description description("General Usage\n"
                                       "  ndnsec get-default [-h] [-k|c] [-i identity|-K key] [-q]\n"
@@ -45,8 +44,8 @@
     ("help,h", "produce help message")
     ("default_key,k", "get default key")
     ("default_cert,c", "get default certificate")
-    ("identity,i", po::value<std::string>(&identityString), "target identity")
-    ("key,K", po::value<std::string>(&keyName), "target key")
+    ("identity,i", po::value<Name>(&identityName), "target identity")
+    ("key,K", po::value<Name>(&keyName), "target key")
     ("quiet,q", "don't output trailing newline")
     ;
 
@@ -80,53 +79,57 @@
     isQuiet = true;
   }
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
 
   if (vm.count("key") != 0) {
-    Name keyNdnName(keyName);
     if (isGetDefaultCert) {
-      std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName);
-      if (!isQuiet)
+      std::cout << keyChain.getPib()
+        .getIdentity(security::v2::extractIdentityFromKeyName(keyName))
+        .getKey(keyName)
+        .getDefaultCertificate().getName();
+
+      if (!isQuiet) {
         std::cout << std::endl;
+      }
       return 0;
     }
     return 1;
   }
   else if (vm.count("identity") != 0) {
-    Name identity(identityString);
+    security::Key key = keyChain.getPib()
+      .getIdentity(identityName)
+      .getDefaultKey();
 
     if (isGetDefaultKey) {
-      std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+      std::cout << key.getName();
       if (!isQuiet)
         std::cout << std::endl;
-
       return 0;
     }
     if (isGetDefaultCert) {
-      std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+      std::cout << key.getDefaultCertificate().getName();
       if (!isQuiet)
         std::cout << std::endl;
-
       return 0;
     }
     return 1;
   }
   else {
-    Name identity = keyChain.getDefaultIdentity();
+    security::Identity identity = keyChain.getPib().getDefaultIdentity();
     if (isGetDefaultId) {
-      std::cout << identity;
+      std::cout << identity.getName();
       if (!isQuiet)
         std::cout << std::endl;
       return 0;
     }
     if (isGetDefaultKey) {
-      std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+      std::cout << identity.getDefaultKey().getName();
       if (!isQuiet)
         std::cout << std::endl;
       return 0;
     }
     if (isGetDefaultCert) {
-      std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+      std::cout << identity.getDefaultKey().getDefaultCertificate().getName();
       if (!isQuiet)
         std::cout << std::endl;
       return 0;
diff --git a/tools/ndnsec/import.cpp b/tools/ndnsec/import.cpp
index 57b9f1b..4bb9b63 100644
--- a/tools/ndnsec/import.cpp
+++ b/tools/ndnsec/import.cpp
@@ -28,17 +28,14 @@
 int
 ndnsec_import(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
   std::string input("-");
   std::string importPassword;
-  bool isPrivateImport = false;
 
   po::options_description description("General Usage\n  ndnsec import [-h] [-p] input \nGeneral options");
   description.add_options()
     ("help,h", "produce help message")
-    ("private,p", "import info contains private key")
     ("input,i", po::value<std::string>(&input), "input source, stdin if -")
     ;
 
@@ -61,44 +58,33 @@
     return 0;
   }
 
-  if (vm.count("private") != 0)
-    isPrivateImport = true;
+  try {
+    security::v2::KeyChain keyChain;
 
-  if (!isPrivateImport) {
-    std::cerr << "You are trying to import certificate!\n"
-              << "Please use ndnsec cert-install!" << std::endl;
-    return 1;
-  }
-  else {
-    try {
-      security::v1::KeyChain keyChain;
+    shared_ptr<security::SafeBag> safeBag;
+    if (input == "-")
+      safeBag = io::load<security::SafeBag>(std::cin);
+    else
+      safeBag = io::load<security::SafeBag>(input);
 
-      shared_ptr<security::v1::SecuredBag> securedBag;
-      if (input == "-")
-        securedBag = io::load<security::v1::SecuredBag>(std::cin);
-      else
-        securedBag = io::load<security::v1::SecuredBag>(input);
-
-      int count = 3;
-      while (!getPassword(importPassword, "Passphrase for the private key: ")) {
-        count--;
-        if (count <= 0) {
-          std::cerr << "ERROR: Fail to get password" << std::endl;
-          memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
-          return 1;
-        }
+    int count = 3;
+    while (!getPassword(importPassword, "Passphrase for the private key: ")) {
+      count--;
+      if (count <= 0) {
+        std::cerr << "ERROR: Fail to get password" << std::endl;
+        memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+        return 1;
       }
-      keyChain.importIdentity(*securedBag, importPassword);
-      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
     }
-    catch (const std::runtime_error& e) {
-      std::cerr << "ERROR: " << e.what() << std::endl;
-      memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
-      return 1;
-    }
-
+    keyChain.importSafeBag(*safeBag, importPassword.c_str(), importPassword.size());
+    memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
     return 0;
   }
+  catch (const std::runtime_error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
+    return 1;
+  }
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/key-gen.cpp b/tools/ndnsec/key-gen.cpp
index 584b79c..81e5d39 100644
--- a/tools/ndnsec/key-gen.cpp
+++ b/tools/ndnsec/key-gen.cpp
@@ -31,7 +31,7 @@
   using namespace ndn;
   namespace po = boost::program_options;
 
-  std::string identityName;
+  Name identityName;
   bool isDefault = true;
   char keyType = 'r';
   std::string outputFilename;
@@ -41,14 +41,13 @@
                                       "General options");
   description.add_options()
     ("help,h", "produce help message")
-    ("identity,i", po::value<std::string>(&identityName),
+    ("identity,i", po::value<Name>(&identityName),
      "identity name, for example, /ndn/edu/ucla/alice")
     ("not_default,n",
      "optional, if not specified, the target identity will be set as "
      "the default identity of the system")
-    ("dsk,d", "generate Data-Signing-Key (DSK) instead of the default Key-Signing-Key (KSK)")
     ("type,t", po::value<char>(&keyType)->default_value('r'),
-    "optional, key type, r for RSA key (default), e for EC key")
+     "optional, key type, r for RSA key (default), e for EC key")
     // ("size,s", po::value<int>(&keySize)->default_value(2048),
     // "optional, key size, 2048 (default)")
     ;
@@ -78,21 +77,18 @@
     return 1;
   }
 
-  if (vm.count("not_default") != 0)
+  if (vm.count("not_default") != 0) {
     isDefault = false;
-
-  bool isKsk = (vm.count("dsk") == 0);
-
-  security::v1::KeyChain keyChain;
-  Name keyName;
+  }
 
   try {
+    unique_ptr<KeyParams> params;
     switch (keyType) {
       case 'r':
-        keyName = keyChain.generateRsaKeyPair(Name(identityName), isKsk, RsaKeyParams().getKeySize());
+        params = make_unique<RsaKeyParams>();
         break;
       case 'e':
-        keyName = keyChain.generateEcKeyPair(Name(identityName), isKsk, EcKeyParams().getKeySize());
+        params = make_unique<EcKeyParams>();
         break;
       default:
         std::cerr << "Unrecongized key type\n"
@@ -100,19 +96,27 @@
         return 1;
     }
 
-    if (keyName.empty()) {
-      std::cerr << "Error: failed to generate key" << std::endl;
-      return 1;
+    // @TODO set other parameters based on whatever user specified
+
+    security::v2::KeyChain keyChain;
+    security::Identity identity;
+    security::Key key;
+    try {
+      identity = keyChain.getPib().getIdentity(identityName);
+      key = keyChain.createKey(identity, *params);
+    }
+    catch (const security::Pib::Error&) {
+      // identity doesn't exist, so create it and generate key
+      identity = keyChain.createIdentity(identityName, *params);
+      key = identity.getDefaultKey();
     }
 
-    keyChain.setDefaultKeyNameForIdentity(keyName);
+    if (isDefault) {
+      keyChain.setDefaultKey(identity, key);
+      keyChain.setDefaultIdentity(identity);
+    }
 
-    shared_ptr<security::v1::IdentityCertificate> identityCert = keyChain.selfSign(keyName);
-
-    if (isDefault)
-      keyChain.setDefaultIdentity(Name(identityName));
-
-    io::save(*identityCert, std::cout);
+    io::save(key.getDefaultCertificate(), std::cout);
   }
   catch (const std::exception& e) {
     std::cerr << "Error: " << e.what() << std::endl;
diff --git a/tools/ndnsec/list.cpp b/tools/ndnsec/list.cpp
index f6adbfe..36026d7 100644
--- a/tools/ndnsec/list.cpp
+++ b/tools/ndnsec/list.cpp
@@ -21,82 +21,90 @@
 
 #include "ndnsec.hpp"
 #include "util.hpp"
+#include "util/indented-stream.hpp"
 
 namespace ndn {
 namespace ndnsec {
 
-void
-printCertificate(security::v1::KeyChain& keyChain,
-                 const ndn::Name& certName,
-                 bool isDefault,
-                 int verboseLevel)
+class Printer
 {
-  if (isDefault)
-    std::cout << "       +->* ";
-  else
-    std::cout << "       +->  ";
-
-  std::cout << certName << std::endl;
-
-  if (verboseLevel >= 3) {
-    shared_ptr<security::v1::IdentityCertificate> certificate = keyChain.getCertificate(certName);
-    if (certificate != nullptr)
-      certificate->printCertificate(std::cout, "            ");
+public:
+  Printer(int verboseLevel)
+    : m_verboseLevel(verboseLevel)
+  {
   }
-}
 
-void
-printKey(security::v1::KeyChain& keyChain, const ndn::Name& keyName, bool isDefault, int verboseLevel)
-{
-  if (isDefault)
-    std::cout << "  +->* ";
-  else
-    std::cout << "  +->  ";
+  void
+  printIdentity(const security::Identity& identity, bool isDefault)
+  {
+    if (isDefault)
+      std::cout << "* ";
+    else
+      std::cout << "  ";
 
-  std::cout << keyName << std::endl;
+    std::cout << identity.getName() << std::endl;
 
-  if (verboseLevel >= 2) {
-    std::vector<ndn::Name> defaultCertificates;
-    keyChain.getAllCertificateNamesOfKey(keyName, defaultCertificates, true);
+    if (m_verboseLevel >= 1) {
+      security::Key defaultKey;
+      try {
+        defaultKey = identity.getDefaultKey();
+      }
+      catch (const security::Pib::Error&) {
+        // no default key
+      }
 
-    for (const auto& certName : defaultCertificates)
-      printCertificate(keyChain, certName, true, verboseLevel);
+      for (const auto& key : identity.getKeys()) {
+        printKey(key, key == defaultKey);
+      }
 
-    std::vector<ndn::Name> otherCertificates;
-    keyChain.getAllCertificateNamesOfKey(keyName, otherCertificates, false);
-    for (const auto& certName : otherCertificates)
-      printCertificate(keyChain, certName, false, verboseLevel);
-  }
-}
-
-void
-printIdentity(security::v1::KeyChain& keyChain,
-              const ndn::Name& identity,
-              bool isDefault,
-              int verboseLevel)
-{
-  if (isDefault)
-    std::cout << "* ";
-  else
-    std::cout << "  ";
-
-  std::cout << identity << std::endl;
-
-  if (verboseLevel >= 1) {
-    std::vector<ndn::Name> defaultKeys;
-    keyChain.getAllKeyNamesOfIdentity(identity, defaultKeys, true);
-    for (const auto& keyName : defaultKeys)
-      printKey(keyChain, keyName, true, verboseLevel);
-
-    std::vector<ndn::Name> otherKeys;
-    keyChain.getAllKeyNamesOfIdentity(identity, otherKeys, false);
-    for (const auto& keyName : otherKeys) {
-      printKey(keyChain, keyName, false, verboseLevel);
+      std::cout << std::endl;
     }
-
-    std::cout << std::endl;
   }
-}
+
+  void
+  printKey(const security::Key& key, bool isDefault)
+  {
+    if (isDefault)
+      std::cout << "  +->* ";
+    else
+      std::cout << "  +->  ";
+
+    std::cout << key.getName() << std::endl;
+
+    if (m_verboseLevel >= 2) {
+      security::v2::Certificate defaultCert;
+      try {
+        defaultCert = key.getDefaultCertificate();
+      }
+      catch (const security::Pib::Error&) {
+        // no default certificate
+      }
+
+      for (const auto& cert : key.getCertificates()) {
+        printCertificate(cert, cert == defaultCert);
+      }
+    }
+  }
+
+  void
+  printCertificate(const security::v2::Certificate& cert, bool isDefault)
+  {
+    if (isDefault)
+      std::cout << "       +->* ";
+    else
+      std::cout << "       +->  ";
+
+    std::cout << cert.getName() << std::endl;
+
+    if (m_verboseLevel >= 3) {
+      util::IndentedStream os(std::cout, "            ");
+      os << cert;
+    }
+  }
+
+private:
+  int m_verboseLevel;
+};
 
 int
 ndnsec_list(int argc, char** argv)
@@ -118,17 +126,9 @@
                   "verbose mode: -v is equivalent to -k, -vv is equivalent to -c")
     ;
 
-  po::options_description oldOptions;
-  oldOptions.add_options()
-    ("key2,K",         "granularity: key")
-    ("cert2,C",        "granularity: certificate");
-
-  po::options_description allOptions;
-  allOptions.add(options).add(oldOptions);
-
   po::variables_map vm;
   try {
-    po::store(po::parse_command_line(argc, argv, allOptions), vm);
+    po::store(po::parse_command_line(argc, argv, options), vm);
     po::notify(vm);
   }
   catch (const std::exception& e) {
@@ -144,25 +144,26 @@
   }
 
   int tmpVerboseLevel = 0;
-  if (vm.count("cert") != 0 || vm.count("cert2") != 0)
+  if (vm.count("cert") != 0)
     tmpVerboseLevel = 2;
-  else if (vm.count("key") != 0 || vm.count("key2") != 0)
+  else if (vm.count("key") != 0)
     tmpVerboseLevel = 1;
 
   verboseLevel = std::max(verboseLevel, tmpVerboseLevel);
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
+  Printer printer(verboseLevel);
 
-  std::vector<Name> defaultIdentities;
-  keyChain.getAllIdentities(defaultIdentities, true);
-  for (const auto& identity : defaultIdentities) {
-    printIdentity(keyChain, identity, true, verboseLevel);
+  // TODO add API to check for default identity (may be from the identity itself)
+  security::Identity defaultIdentity;
+  try {
+    keyChain.getPib().getDefaultIdentity();
   }
-
-  std::vector<Name> otherIdentities;
-  keyChain.getAllIdentities(otherIdentities, false);
-  for (const auto& identity : otherIdentities) {
-    printIdentity(keyChain, identity, false, verboseLevel);
+  catch (const security::Pib::Error&) {
+    // no default identity
+  }
+  for (const auto& identity : keyChain.getPib().getIdentities()) {
+    printer.printIdentity(identity, identity == defaultIdentity);
   }
 
   return 0;
diff --git a/tools/ndnsec/main.cpp b/tools/ndnsec/main.cpp
index 6a2572a..351c29b 100644
--- a/tools/ndnsec/main.cpp
+++ b/tools/ndnsec/main.cpp
@@ -22,24 +22,26 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 #include "version.hpp"
+#include "util/logger.hpp"
 
-std::string ndnsec_helper = R"STR(
+#include <boost/exception/get_error_info.hpp>
+
+NDN_LOG_INIT(ndnsec);
+
+std::string ndnsec_helper = R"STR(\
   help         Show all commands
   version      Show version and exit
   list         Display information in PublicInfo
   get-default  Get default setting info
   set-default  Configure default setting
   key-gen      Generate a Key-Signing-Key for an identity
-  dsk-gen      Generate a Data-Signing-Key for an identity
   sign-req     Generate a certificate signing request
   cert-gen     Generate an identity certificate
-  cert-revoke  Revoke an identity certificate
   cert-dump    Dump a certificate from PublicInfo
   cert-install Install a certificate into PublicInfo
   delete       Delete identity/key/certificate
   export       Export an identity package
   import       Import an identity package
-  set-acl      Configure ACL of a private key
   unlock-tpm   Unlock Tpm
 )STR";
 
@@ -61,24 +63,35 @@
     else if (command == "get-default")  { return ndnsec_get_default(argc - 1, argv + 1); }
     else if (command == "set-default")  { return ndnsec_set_default(argc - 1, argv + 1); }
     else if (command == "key-gen")      { return ndnsec_key_gen(argc - 1, argv + 1); }
-    else if (command == "dsk-gen")      { return ndnsec_dsk_gen(argc - 1, argv + 1); }
     else if (command == "sign-req")     { return ndnsec_sign_req(argc - 1, argv + 1); }
     else if (command == "cert-gen")     { return ndnsec_cert_gen(argc - 1, argv + 1); }
-    else if (command == "cert-revoke")  { return ndnsec_cert_revoke(argc - 1, argv + 1); }
     else if (command == "cert-dump")    { return ndnsec_cert_dump(argc - 1, argv + 1); }
     else if (command == "cert-install") { return ndnsec_cert_install(argc - 1, argv + 1); }
     else if (command == "delete")       { return ndnsec_delete(argc - 1, argv + 1); }
     else if (command == "export")       { return ndnsec_export(argc - 1, argv + 1); }
     else if (command == "import")       { return ndnsec_import(argc - 1, argv + 1); }
-    else if (command == "set-acl")      { return ndnsec_set_acl(argc - 1, argv + 1); }
     else if (command == "unlock-tpm")   { return ndnsec_unlock_tpm(argc - 1, argv + 1); }
     else {
       std::cerr << ndnsec_helper << std::endl;
       return 1;
     }
   }
-  catch (const std::runtime_error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
+  catch (const std::exception& e) {
+
+    std::cerr << "ERROR: " << e.what();
+
+    std::ostringstream extendedError;
+    const char* const* file = boost::get_error_info<boost::throw_file>(e);
+    const int* line = boost::get_error_info<boost::throw_line>(e);
+    const char* const* func = boost::get_error_info<boost::throw_function>(e);
+    if (file && line) {
+      extendedError << " [from " << *file << ":" << *line;
+      if (func) {
+        extendedError << " in " << *func;
+      }
+      extendedError << "]";
+    }
+    NDN_LOG_ERROR(e.what() << extendedError.str());
     return 1;
   }
 
diff --git a/tools/ndnsec/ndnsec.hpp b/tools/ndnsec/ndnsec.hpp
index b64a6b2..dd34dd9 100644
--- a/tools/ndnsec/ndnsec.hpp
+++ b/tools/ndnsec/ndnsec.hpp
@@ -25,6 +25,8 @@
 namespace ndn {
 namespace ndnsec {
 
+// TODO convert to tool registry (may be)
+
 int
 ndnsec_list(int argc, char** argv);
 
@@ -38,18 +40,12 @@
 ndnsec_key_gen(int argc, char** argv);
 
 int
-ndnsec_dsk_gen(int argc, char** argv);
-
-int
 ndnsec_sign_req(int argc, char** argv);
 
 int
 ndnsec_cert_gen(int argc, char** argv);
 
 int
-ndnsec_cert_revoke(int argc, char** argv);
-
-int
 ndnsec_cert_dump(int argc, char** argv);
 
 int
@@ -65,9 +61,6 @@
 ndnsec_import(int argc, char** argv);
 
 int
-ndnsec_set_acl(int argc, char** argv);
-
-int
 ndnsec_unlock_tpm(int argc, char** argv);
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/set-acl.cpp b/tools/ndnsec/set-acl.cpp
deleted file mode 100644
index 3f73f27..0000000
--- a/tools/ndnsec/set-acl.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_set_acl(int argc, char** argv)
-{
-  using namespace ndn;
-  namespace po = boost::program_options;
-
-  std::string keyName;
-  std::string appPath;
-
-  po::options_description description("General Usage\n  ndnsec set-acl [-h] keyName appPath \nGeneral options");
-  description.add_options()
-    ("help,h", "produce help message")
-    ("keyName,k", po::value<std::string>(&keyName), "Key name.")
-    ("appPath,p", po::value<std::string>(&appPath), "Application path.")
-    ;
-
-  po::positional_options_description p;
-  p.add("keyName", 1);
-  p.add("appPath", 1);
-
-  po::variables_map vm;
-  try {
-    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
-    po::notify(vm);
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
-  }
-
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
-    return 0;
-  }
-
-  if (vm.count("keyName") == 0) {
-    std::cerr << "ERROR: keyName is required!" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  if (vm.count("appPath") == 0) {
-    std::cerr << "ERROR: appPath is required!" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  security::v1::KeyChain keyChain;
-  keyChain.addAppToAcl(keyName, KeyClass::PRIVATE, appPath, AclType::PRIVATE);
-
-  return 0;
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/set-default.cpp b/tools/ndnsec/set-default.cpp
index ab045ef..d39abdb 100644
--- a/tools/ndnsec/set-default.cpp
+++ b/tools/ndnsec/set-default.cpp
@@ -28,21 +28,20 @@
 int
 ndnsec_set_default(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
   std::string certFileName;
   bool isSetDefaultId = true;
   bool isSetDefaultKey = false;
   bool isSetDefaultCert = false;
-  std::string name;
+  Name name;
 
   po::options_description description("General Usage\n  ndnsec set-default [-h] [-k|c] name\nGeneral options");
   description.add_options()
     ("help,h", "produce help message")
-    ("default_key,k", "set default key of the identity")
-    ("default_cert,c", "set default certificate of the key")
-    ("name,n", po::value<std::string>(&name), "the name to set")
+    ("default_key,k", po::bool_switch(&isSetDefaultKey), "set default key of the identity")
+    ("default_cert,c", po::bool_switch(&isSetDefaultCert), "set default certificate of the key")
+    ("name,n", po::value<Name>(&name), "the identity/key/certificate name to set")
     ;
 
   po::positional_options_description p;
@@ -69,30 +68,28 @@
     return 1;
   }
 
-  security::v1::KeyChain keyChain;
+  isSetDefaultId = !isSetDefaultKey && !isSetDefaultCert;
 
-  if (vm.count("default_key") != 0) {
-    isSetDefaultKey = true;
-    isSetDefaultId = false;
-  }
-  else if (vm.count("default_cert") != 0) {
-    isSetDefaultCert = true;
-    isSetDefaultId = false;
-  }
+  security::v2::KeyChain keyChain;
 
   if (isSetDefaultId) {
-    Name idName(name);
-    keyChain.setDefaultIdentity(idName);
+    security::Identity identity = keyChain.getPib().getIdentity(name);
+    keyChain.setDefaultIdentity(identity);
     return 0;
   }
+
   if (isSetDefaultKey) {
-    Name keyName(name);
-    keyChain.setDefaultKeyNameForIdentity(keyName);
+    security::Identity identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
+    security::Key key = identity.getKey(name);
+    keyChain.setDefaultKey(identity, key);
     return 0;
   }
 
   if (isSetDefaultCert) {
-    keyChain.setDefaultCertificateNameForKey(name);
+    security::Identity identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromCertName(name));
+    security::Key key = identity.getKey(security::v2::extractKeyNameFromCertName(name));
+    security::v2::Certificate cert = key.getCertificate(name);
+    keyChain.setDefaultCertificate(key, cert);
     return 0;
   }
 
diff --git a/tools/ndnsec/sign-req.cpp b/tools/ndnsec/sign-req.cpp
index eced361..da330cf 100644
--- a/tools/ndnsec/sign-req.cpp
+++ b/tools/ndnsec/sign-req.cpp
@@ -28,19 +28,19 @@
 int
 ndnsec_sign_req(int argc, char** argv)
 {
-  using namespace ndn;
-  using namespace ndn::security;
   namespace po = boost::program_options;
 
-  std::string name;
+  Name name;
   bool isKeyName = false;
 
   po::options_description description(
     "General Usage\n  ndnsec sign-req [-h] [-k] name\nGeneral options");
-  description.add_options()
+  description
+    .add_options()
     ("help,h", "produce help message")
-    ("key,k", "optional, if specified, name is keyName (e.g. /ndn/edu/ucla/alice/ksk-123456789), otherwise identity name")
-    ("name,n", po::value<std::string>(&name), "name, for example, /ndn/edu/ucla/alice");
+    ("key,k", "optional, if specified, name is keyName (e.g., /ndn/edu/ucla/alice/KEY/ksk-123456789), "
+              "otherwise identity name")
+    ("name,n", po::value<Name>(&name), "name, for example, /ndn/edu/ucla/alice");
 
   po::positional_options_description p;
   p.add("name", 1);
@@ -67,28 +67,49 @@
     return 1;
   }
 
-  if (vm.count("key") != 0)
+  if (vm.count("key") != 0) {
     isKeyName = true;
-
-  shared_ptr<security::v1::IdentityCertificate> selfSignCert;
-
-  security::v1::KeyChain keyChain;
-
-  if (isKeyName)
-    selfSignCert = keyChain.selfSign(name);
-  else {
-    Name keyName = keyChain.getDefaultKeyNameForIdentity(name);
-    selfSignCert = keyChain.selfSign(keyName);
   }
 
-  if (selfSignCert != nullptr) {
-    io::save(*selfSignCert, std::cout);
-    return 0;
+  security::v2::KeyChain keyChain;
+
+  security::Identity identity;
+  security::Key key;
+  if (!isKeyName) {
+    identity = keyChain.getPib().getIdentity(name);
+    key = identity.getDefaultKey();
   }
   else {
-    std::cerr << "ERROR: Public key does not exist" << std::endl;
-    return 1;
+    identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
+    key = identity.getKey(name);
   }
+
+  // Create signing request (similar to self-signed certificate)
+  security::v2::Certificate certificate;
+
+  // set name
+  Name certificateName = key.getName();
+  certificateName
+    .append("cert-request")
+    .appendVersion();
+  certificate.setName(certificateName);
+
+  // set metainfo
+  certificate.setContentType(tlv::ContentType_Key);
+  certificate.setFreshnessPeriod(time::hours(1));
+
+  // set content
+  certificate.setContent(key.getPublicKey().buf(), key.getPublicKey().size());
+
+  // set signature-info
+  SignatureInfo signatureInfo;
+  signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
+                                                           time::system_clock::now() + time::days(10)));
+
+  keyChain.sign(certificate, security::SigningInfo(key).setSignatureInfo(signatureInfo));
+
+  io::save(certificate, std::cout);
+  return 0;
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/unlock-tpm.cpp b/tools/ndnsec/unlock-tpm.cpp
index 86d7635..0d70acc 100644
--- a/tools/ndnsec/unlock-tpm.cpp
+++ b/tools/ndnsec/unlock-tpm.cpp
@@ -29,7 +29,6 @@
 ndnsec_unlock_tpm(int argc, char** argv)
 {
 #ifdef NDN_CXX_HAVE_GETPASS
-  using namespace ndn;
   namespace po = boost::program_options;
 
   std::string keyName;
@@ -56,11 +55,11 @@
 
   bool isUnlocked = false;
 
-  security::v1::KeyChain keyChain;
+  security::v2::KeyChain keyChain;
 
   char* password;
   password = getpass("Password to unlock the TPM: ");
-  isUnlocked = keyChain.unlockTpm(password, strlen(password), true);
+  isUnlocked = keyChain.getTpm().unlockTpm(password, strlen(password));
   memset(password, 0, strlen(password));
 
   if (isUnlocked) {
diff --git a/tools/ndnsec/util.cpp b/tools/ndnsec/util.cpp
index 7afa036..52657f7 100644
--- a/tools/ndnsec/util.cpp
+++ b/tools/ndnsec/util.cpp
@@ -25,11 +25,9 @@
 namespace ndnsec {
 
 bool
-getPassword(std::string& password, const std::string& prompt)
+getPassword(std::string& password, const std::string& prompt, bool shouldConfirm)
 {
 #ifdef NDN_CXX_HAVE_GETPASS
-  bool isReady = false;
-
   char* pw0 = nullptr;
 
   pw0 = getpass(prompt.c_str());
@@ -38,6 +36,10 @@
   std::string password1 = pw0;
   memset(pw0, 0, strlen(pw0));
 
+  if (!shouldConfirm) {
+    return true;
+  }
+
   pw0 = getpass("Confirm:");
   if (!pw0) {
     char* pw1 = const_cast<char*>(password1.c_str());
@@ -45,6 +47,8 @@
     return false;
   }
 
+  bool isReady = false;
+
   if (!password1.compare(pw0)) {
     isReady = true;
     password.swap(password1);
@@ -63,13 +67,19 @@
 #endif // NDN_CXX_HAVE_GETPASS
 }
 
-shared_ptr<security::v1::IdentityCertificate>
-getIdentityCertificate(const std::string& fileName)
+security::v2::Certificate
+loadCertificate(const std::string& fileName)
 {
+  shared_ptr<security::v2::Certificate> cert;
   if (fileName == "-")
-    return io::load<security::v1::IdentityCertificate>(std::cin);
+    cert = io::load<security::v2::Certificate>(std::cin);
   else
-    return io::load<security::v1::IdentityCertificate>(fileName);
+    cert = io::load<security::v2::Certificate>(fileName);
+
+  if (cert == nullptr) {
+    BOOST_THROW_EXCEPTION(CannotLoadCertificate(fileName));
+  }
+  return *cert;
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/util.hpp b/tools/ndnsec/util.hpp
index 4f6cee4..0173b51 100644
--- a/tools/ndnsec/util.hpp
+++ b/tools/ndnsec/util.hpp
@@ -24,7 +24,8 @@
 
 #include "encoding/buffer-stream.hpp"
 #include "security/transform.hpp"
-#include "security/v1/key-chain.hpp"
+#include "security/key-chain.hpp"
+#include "security/v2/additional-description.hpp"
 #include "util/io.hpp"
 
 #include <fstream>
@@ -37,16 +38,24 @@
 #include <boost/program_options/options_description.hpp>
 #include <boost/program_options/parsers.hpp>
 #include <boost/program_options/variables_map.hpp>
-#include <boost/tokenizer.hpp>
 
 namespace ndn {
 namespace ndnsec {
 
-bool
-getPassword(std::string& password, const std::string& prompt);
+class CannotLoadCertificate : public std::runtime_error
+{
+public:
+  CannotLoadCertificate(const std::string& msg)
+    : std::runtime_error(msg)
+  {
+  }
+};
 
-shared_ptr<security::v1::IdentityCertificate>
-getIdentityCertificate(const std::string& fileName);
+bool
+getPassword(std::string& password, const std::string& prompt, bool shouldConfirm = true);
+
+security::v2::Certificate
+loadCertificate(const std::string& fileName);
 
 /**
  * @brief An accumulating option value to handle multiple incrementing options.