docs+ndnsec: improve description and parsing of command options, rewrite man pages

Replace custom redmine_issue extension with sphinx.ext.extlinks

Refs: #4907
Change-Id: Ib0cb94156ae4fc80cdcaf4c70d7c8d55c16fcbc3
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index 00f7667..ec630c9 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,7 +22,10 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
-#include <boost/tokenizer.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 {
 namespace ndnsec {
@@ -30,43 +33,37 @@
 int
 ndnsec_cert_gen(int argc, char** argv)
 {
-  using boost::tokenizer;
-  using boost::escaped_list_separator;
-
   namespace po = boost::program_options;
-  namespace t = security::transform;
 
-  security::v2::KeyChain keyChain;
-
+  std::string requestFile;
   std::string notBeforeStr;
   std::string notAfterStr;
-  std::string requestFile("-");
-  Name signId;
   std::vector<std::string> infos;
+  Name signId;
   std::string issuerId;
 
   po::options_description description(
-    "General Usage\n"
-    "  ndnsec cert-gen [-h] [-S date] [-E date] [-I info] [-s sign-id] request\n"
-    "General options");
-
+    "Usage: ndnsec cert-gen [-h] [-S TIMESTAMP] [-E TIMESTAMP] [-I INFO]...\n"
+    "                       [-s IDENTITY] [-i ISSUER] [-r] FILE\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
+    ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
+                       "request file name, '-' for stdin (the default)")
     ("not-before,S",   po::value<std::string>(&notBeforeStr),
-                       "certificate starting date, YYYYMMDDhhmmss (default: now)")
+                       "certificate validity start date/time in YYYYMMDDhhmmss format (default: now)")
     ("not-after,E",    po::value<std::string>(&notAfterStr),
-                       "certificate ending date, YYYYMMDDhhmmss (default: now + 365 days)")
+                       "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\". "
-                       "May be repeated multiple times")
-    ("sign-id,s",      po::value<Name>(&signId),
-                       "signing identity")
-    ("request,r",      po::value<std::string>(&requestFile)->default_value("-"),
-                       "request file name, - for stdin")
+                       "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)->default_value("NA"),
-                       "issuer's ID to be included as part of the issued certificate name")
+                       "issuer's ID to be included in the issued certificate name")
     ;
 
   po::positional_options_description p;
@@ -78,11 +75,12 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
+  if (vm.count("help") > 0) {
     std::cout << description << std::endl;
     return 0;
   }
@@ -90,10 +88,10 @@
   security::v2::AdditionalDescription additionalDescription;
 
   for (const auto& info : infos) {
-    size_t pos = info.find(" ");
+    auto pos = info.find(" ");
     if (pos == std::string::npos) {
       std::cerr << "ERROR: incorrectly formatted info block [" << info << "]" << std::endl;
-      return 1;
+      return 2;
     }
     std::string key = info.substr(0, pos);
     std::string value = info.substr(pos + 1);
@@ -118,44 +116,36 @@
     notAfter = time::fromIsoString(notAfterStr.substr(0, 8) + "T" + notAfterStr.substr(8, 6));
 
     if (notAfter < notBefore) {
-      std::cerr << "ERROR: not-before cannot be later than not-after" << std::endl
-                << std::endl
-                << description << std::endl;
-      return 1;
+      std::cerr << "ERROR: '--not-before' cannot be later than '--not-after'" << std::endl;
+      return 2;
     }
   }
 
-  if (vm.count("request") == 0) {
-    std::cerr << "ERROR: request file must be specified" << std::endl
-              << std::endl
-              << description << std::endl;
+  security::v2::KeyChain keyChain;
+
+  security::v2::Certificate certRequest;
+  try {
+    certRequest = loadCertificate(requestFile);
+  }
+  catch (const CannotLoadCertificate&) {
+    std::cerr << "ERROR: Cannot load the request from `" << requestFile << "`" << std::endl;
     return 1;
   }
 
-  security::v2::Certificate certRequest = loadCertificate(requestFile);
-
   // validate that the content is a public key
-  try {
-    Buffer keyContent = certRequest.getPublicKey();
-    t::PublicKey pubKey;
-    pubKey.loadPkcs8(keyContent.data(), keyContent.size());
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
-  }
-
-  security::v2::Certificate cert;
+  Buffer keyContent = certRequest.getPublicKey();
+  security::transform::PublicKey pubKey;
+  pubKey.loadPkcs8(keyContent.data(), keyContent.size());
 
   Name certName = certRequest.getKeyName();
   certName
     .append(issuerId)
     .appendVersion();
 
+  security::v2::Certificate cert;
   cert.setName(certName);
   cert.setContent(certRequest.getContent());
-
-  // @TODO add ability to customize
+  // TODO: add ability to customize
   cert.setFreshnessPeriod(1_h);
 
   SignatureInfo signatureInfo;
@@ -174,15 +164,10 @@
 
   keyChain.sign(cert, security::SigningInfo(identity).setSignatureInfo(signatureInfo));
 
-  Block wire = cert.wireEncode();
-
-
-  try {
-    t::bufferSource(wire.wire(), wire.size()) >> t::base64Encode(true) >> t::streamSink(std::cout);
-  }
-  catch (const t::Error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
+  const Block& wire = cert.wireEncode();
+  {
+    using namespace security::transform;
+    bufferSource(wire.wire(), wire.size()) >> base64Encode(true) >> streamSink(std::cout);
   }
 
   return 0;