tools: relax restriction on KeyId component type in `ndnsec key-gen`

And add a similar check on the IssuerId in cert-gen

Change-Id: I6828287a8c2f97dacba3326f0579afc71d9c69a3
diff --git a/docs/manpages/ndnsec-cert-gen.rst b/docs/manpages/ndnsec-cert-gen.rst
index b433ef8..db4f03c 100644
--- a/docs/manpages/ndnsec-cert-gen.rst
+++ b/docs/manpages/ndnsec-cert-gen.rst
@@ -75,17 +75,18 @@
     ug/vLAIgY3xJITCwf55sqey33q5GIQSk1TRCkNNl58ojvPs5sNU=
 
     $ ndnsec-cert-dump -p -f signed.cert
-    Certificate name:
+    Certificate Name:
       /example/KEY/%E4%14%99%7F%28%96%82%EB/Universe/%FD%00%00%01q%D1%02N%82
-    Validity:
-      NotBefore: 20200501T000000
-      NotAfter: 20210101T000000
     Additional Description:
       affiliation: Some Organization
       foobar: Foo Bar
-    Public key bits:
+    Public Key:
+      Key Type: 256-bit EC
       MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkmwKS8TlEyPFFV3IrpbrP4WgKr6
       pEQSf+zF/6faCeyXbmqbU1qsJ9IZ/3rMgnL0FED1u24wx65aUA3/Ka8wXA==
+    Validity:
+      Not Before: 2020-05-01T00:00:00
+      Not After: 2021-01-01T00:00:00
     Signature Information:
       Signature Type: SignatureSha256WithEcdsa
       Key Locator: Name=/ndn/test/KEY/I%3FS%9A%28%BB%9A%95
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index 49b0362..cc77f02 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -25,7 +25,6 @@
 #include "ndn-cxx/security/additional-description.hpp"
 #include "ndn-cxx/security/transform/base64-encode.hpp"
 #include "ndn-cxx/security/transform/buffer-source.hpp"
-#include "ndn-cxx/security/transform/public-key.hpp"
 #include "ndn-cxx/security/transform/stream-sink.hpp"
 
 namespace ndn {
@@ -35,13 +34,14 @@
 ndnsec_cert_gen(int argc, char** argv)
 {
   namespace po = boost::program_options;
+  using security::Certificate;
 
   std::string requestFile;
   std::string notBeforeStr;
   std::string notAfterStr;
   std::vector<std::string> infos;
   Name signId;
-  std::string issuerId;
+  std::string issuer;
 
   po::options_description description(
     "Usage: ndnsec cert-gen [-h] [-S TIMESTAMP] [-E TIMESTAMP] [-I INFO]...\n"
@@ -51,22 +51,20 @@
   description.add_options()
     ("help,h", "produce help message")
     ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
-                       "request file name, '-' for stdin (the default)")
+                       "certificate request file name, '-' for stdin (the default)")
     ("not-before,S",   po::value<std::string>(&notBeforeStr),
                        "certificate validity start date/time in YYYYMMDDhhmmss format (default: now)")
     ("not-after,E",    po::value<std::string>(&notAfterStr),
                        "certificate validity end date/time in YYYYMMDDhhmmss format (default: "
                        "365 days after the --not-before timestamp)")
     ("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\"); "
-                       "this option may be repeated multiple times")
+                       "key and value (separated by a single space) of the additional description "
+                       "to be included in the issued certificate (e.g., \"affiliation University of "
+                       "California, Los Angeles\"); this option may be repeated multiple times")
     ("sign-id,s",      po::value<Name>(&signId), "signing identity")
-    ("issuer-id,i",    po::value<std::string>(&issuerId),
-                       ("issuer's ID to be included in the issued certificate name, interpreted as "
-                        "name component in URI format (default: \"" +
-                        security::Certificate::DEFAULT_ISSUER_ID.toUri() + "\")").data())
+    ("issuer-id,i",    po::value<std::string>(&issuer)->default_value(Certificate::DEFAULT_ISSUER_ID.toUri()),
+                       "issuer's ID to be included in the issued certificate name, interpreted as a "
+                       "name component in URI format")
     ;
 
   po::positional_options_description p;
@@ -124,9 +122,17 @@
     }
   }
 
+  auto issuerId = name::Component::fromEscapedString(issuer);
+  if (issuerId.isImplicitSha256Digest() ||
+      issuerId.isParametersSha256Digest() ||
+      issuerId.isKeyword()) {
+    std::cerr << "ERROR: '" << issuerId << "' cannot be used as issuer ID" << std::endl;
+    return 2;
+  }
+
   KeyChain keyChain;
 
-  auto request = loadFromFile<security::Certificate>(requestFile);
+  auto request = loadFromFile<Certificate>(requestFile);
 
   security::SigningInfo signer;
   if (vm.count("sign-id") > 0) {
@@ -139,9 +145,7 @@
   }
 
   security::MakeCertificateOptions opts;
-  if (vm.count("issuer-id") > 0) {
-    opts.issuerId = name::Component::fromEscapedString(issuerId);
-  }
+  opts.issuerId = issuerId;
   opts.validity.emplace(notBefore, notAfter);
   auto cert = keyChain.makeCertificate(request, signer, opts);
 
diff --git a/tools/ndnsec/key-gen.cpp b/tools/ndnsec/key-gen.cpp
index 6773e72..ac85fe8 100644
--- a/tools/ndnsec/key-gen.cpp
+++ b/tools/ndnsec/key-gen.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -47,9 +47,10 @@
     ("type,t",        po::value<char>(&keyTypeChoice)->default_value('e'),
                       "key type: 'r' for RSA, 'e' for ECDSA")
     ("keyid-type,k",  po::value<char>(&keyIdTypeChoice),
-                      "key id type: 'h' for the SHA-256 of the public key, 'r' for a 64-bit "
+                      "key ID type: 'h' for the SHA-256 of the public key, 'r' for a 64-bit "
                       "random number (the default unless --keyid is specified)")
-    ("keyid",         po::value<std::string>(&userKeyId), "user-specified key id")
+    ("keyid",         po::value<std::string>(&userKeyId),
+                      "user-specified key ID, interpreted as a name component in URI format")
     ;
 
   po::positional_options_description p;
@@ -87,12 +88,11 @@
 
     keyIdType = KeyIdType::USER_SPECIFIED;
     userKeyIdComponent = name::Component::fromEscapedString(userKeyId);
-    if (userKeyIdComponent.empty()) {
-      std::cerr << "ERROR: key id cannot be an empty name component" << std::endl;
-      return 2;
-    }
-    if (!userKeyIdComponent.isGeneric()) {
-      std::cerr << "ERROR: key id must be a GenericNameComponent" << std::endl;
+    if (userKeyIdComponent.empty() ||
+        userKeyIdComponent.isImplicitSha256Digest() ||
+        userKeyIdComponent.isParametersSha256Digest() ||
+        userKeyIdComponent.isKeyword()) {
+      std::cerr << "ERROR: '" << userKeyIdComponent << "' cannot be used as key ID" << std::endl;
       return 2;
     }
   }
@@ -106,7 +106,7 @@
       // KeyIdType::RANDOM is the default
       break;
     default:
-      std::cerr << "ERROR: unrecognized key id type '" << keyIdTypeChoice << "'" << std::endl;
+      std::cerr << "ERROR: unrecognized key ID type '" << keyIdTypeChoice << "'" << std::endl;
       return 2;
     }
   }