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-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;
   }