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/.waf-tools/sphinx_build.py b/.waf-tools/sphinx_build.py
index e61da6e..b44a54f 100644
--- a/.waf-tools/sphinx_build.py
+++ b/.waf-tools/sphinx_build.py
@@ -44,28 +44,28 @@
     task.inputs.append(conf)
 
     confdir = conf.parent.abspath()
-    buildername = getattr(self, "builder", "html")
-    srcdir = getattr(self, "srcdir", confdir)
-    outdir = self.path.find_or_declare(getattr(self, "outdir", buildername)).get_bld()
-    doctreedir = getattr(self, "doctreedir", os.path.join(outdir.abspath(), ".doctrees"))
+    buildername = getattr(self, 'builder', 'html')
+    srcdir = getattr(self, 'srcdir', confdir)
+    outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
+    doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
 
     task.env['BUILDERNAME'] = buildername
     task.env['SRCDIR'] = srcdir
     task.env['DOCTREEDIR'] = doctreedir
     task.env['OUTDIR'] = outdir.abspath()
-    task.env['VERSION'] = "version=%s" % self.VERSION
-    task.env['RELEASE'] = "release=%s" % self.VERSION
+    task.env['VERSION'] = 'version=%s' % self.version
+    task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
 
     import imp
     confData = imp.load_source('sphinx_conf', conf.abspath())
 
-    if buildername == "man":
+    if buildername == 'man':
         for i in confData.man_pages:
             target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
             task.outputs.append(target)
 
             if self.install_path:
-                self.bld.install_files("%s/man%d/" % (self.install_path, i[4]), target)
+                self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
     else:
         task.outputs.append(outdir)
 
diff --git a/README.md b/README.md
index a04cb68..f661518 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,9 @@
 [![Build Status](https://travis-ci.org/named-data/ndn-cxx.svg?branch=master)](https://travis-ci.org/named-data/ndn-cxx)
 ![Latest Version](https://img.shields.io/github/tag/named-data/ndn-cxx.svg?color=darkkhaki&label=latest%20version)
 
-ndn-cxx is a C++14 library, implementing Named Data Networking (NDN) primitives
-that can be used to write various NDN applications. The library is currently
-being used by the following projects:
+**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
+that can be used to write various NDN applications. The library is currently being
+used by the following projects:
 
 * [NFD - NDN Forwarding Daemon](https://github.com/named-data/NFD)
 * [NLSR - Named-data Link-State Routing protocol](https://github.com/named-data/NLSR)
diff --git a/docs/conf.py b/docs/conf.py
index 82688a1..7e73680 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,37 +1,53 @@
 # -*- coding: utf-8 -*-
 #
-# NFD - Named Data Networking Forwarding Daemon documentation build configuration file, created by
-# sphinx-quickstart on Sun Apr  6 19:58:22 2014.
+# Configuration file for the Sphinx documentation builder.
 #
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
 
-import sys
-import os
-import re
+# -- Path setup --------------------------------------------------------------
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.insert(0, os.path.abspath('.'))
+#
+import os
+import sys
+# sys.path.insert(0, os.path.abspath('.'))
 
-# -- General configuration ------------------------------------------------
+
+# -- Project information -----------------------------------------------------
+
+project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
+copyright = u'Copyright © 2013-2019 Regents of the University of California.'
+author = u'Named Data Networking Project'
+
+# The short X.Y version
+#version = ''
+
+# The full version, including alpha/beta/rc tags
+#release = ''
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%Y-%m-%d'
+
+
+# -- General configuration ---------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
+#
+needs_sphinx = '1.1'
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = [
+    'sphinx.ext.extlinks',
     'sphinx.ext.todo',
-    'redmine_issue',
 ]
 
 def addExtensionIfExists(extension):
@@ -39,10 +55,8 @@
         __import__(extension)
         extensions.append(extension)
     except ImportError:
-        sys.stderr.write("Extension '%s' in not available. "
+        sys.stderr.write("Extension '%s' not found. "
                          "Some documentation may not build correctly.\n" % extension)
-        sys.stderr.write("To install, use \n"
-                         "  sudo pip install %s\n" % extension.replace('.', '-'))
 
 if sys.version_info[0] >= 3:
     addExtensionIfExists('sphinxcontrib.doxylink')
@@ -51,232 +65,99 @@
 # if os.getenv('GOOGLE_ANALYTICS', None):
 #     addExtensionIfExists('sphinxcontrib.googleanalytics')
 
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
 # The master toctree document.
 master_doc = 'index'
 
-# General information about the project.
-project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
-copyright = u'Copyright (c) 2013-2019 Regents of the University of California.'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
 exclude_patterns = []
 
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#default_role = None
 
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-# If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
-
-
-# -- Options for HTML output ----------------------------------------------
+# -- Options for HTML output -------------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-# html_theme = 'default'
+#
 html_theme = 'named_data_theme'
 
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
 # Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = ['./']
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
+html_theme_path = ['.']
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ['_static']
 
-# Add any extra paths that contain custom files (such as robots.txt or
-# .htaccess) here, relative to this directory. These files are copied
-# directly to the root of the documentation.
-#html_extra_path = []
 
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-html_file_suffix = ".html"
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'ndn-cxx-docs'
-
-
-# -- Options for LaTeX output ---------------------------------------------
+# -- Options for LaTeX output ------------------------------------------------
 
 latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
 
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
 
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-  ('index', 'ndn-cxx-docs.tex', u'NDN C++ library with eXperimental eXtensions',
-   u'Named Data Networking Project', 'manual'),
+    ('index', 'ndn-cxx-docs.tex', u'NDN C++ library with eXperimental eXtensions',
+     author, 'manual'),
 ]
 
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
 
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output ---------------------------------------
+# -- Options for manual page output ------------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('manpages/ndnsec',              'ndnsec',              'NDN security toolkit', None, 1),
-    ('manpages/ndnsec-cert-dump',    'ndnsec-cert-dump',    'export an NDN certificate', None, 1),
-    ('manpages/ndnsec-cert-gen',     'ndnsec-cert-gen',     'create an NDN certificate for an identity', None, 1),
-    ('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file', None, 1),
-    ('manpages/ndnsec-delete',       'ndnsec-delete',       'delete an NDN identity, key, or certificate', None, 1),
-    ('manpages/ndnsec-export',       'ndnsec-export',
-     'export an NDN certificate and its private key to a file', None, 1),
-    ('manpages/ndnsec-get-default',  'ndnsec-get-default',
-     'show the default NDN identity, key, and certificate for the current user', None, 1),
-    ('manpages/ndnsec-import',       'ndnsec-import',
-     'import an NDN certificate and its private key from a file', None, 1),
-    ('manpages/ndnsec-key-gen',      'ndnsec-key-gen',
-     'generate an NDN key for an identity', None, 1),
-    ('manpages/ndnsec-list',         'ndnsec-list',
-     'list all known NDN identities, keys, and certificates', None, 1),
-    ('manpages/ndnsec-set-default',  'ndnsec-set-default',
-     'change the default NDN identity, key, or certificate for the current user', None, 1),
-    ('manpages/ndnsec-sign-req',     'ndnsec-sign-req',     'generate an NDN certificate signing request', None, 1),
-    ('manpages/ndnsec-unlock-tpm',   'ndnsec-unlock-tpm',   'unlock the TPM', None, 1),
-    ('manpages/ndn-client.conf',     'ndn-client.conf',     'configuration file for NDN platform', None, 5),
-    ('manpages/ndn-log',             'ndn-log',             'ndn-cxx logging',                     None, 7),
+    ('manpages/ndnsec',              'ndnsec',              'NDN security toolkit',                         None, 1),
+    ('manpages/ndnsec-cert-dump',    'ndnsec-cert-dump',    'export an NDN certificate',                    None, 1),
+    ('manpages/ndnsec-cert-gen',     'ndnsec-cert-gen',     'create an NDN certificate for an identity',    None, 1),
+    ('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file',        None, 1),
+    ('manpages/ndnsec-delete',       'ndnsec-delete',       'delete an NDN identity, key, or certificate',  None, 1),
+    ('manpages/ndnsec-export',       'ndnsec-export',       'export an NDN certificate and its private key to a file', None, 1),
+    ('manpages/ndnsec-get-default',  'ndnsec-get-default',  'show the default NDN identity, key, and certificate for the current user', None, 1),
+    ('manpages/ndnsec-import',       'ndnsec-import',       'import an NDN certificate and its private key from a file', None, 1),
+    ('manpages/ndnsec-key-gen',      'ndnsec-key-gen',      'generate an NDN key for an identity',          None, 1),
+    ('manpages/ndnsec-list',         'ndnsec-list',         'list all known NDN identities, keys, and certificates', None, 1),
+    ('manpages/ndnsec-set-default',  'ndnsec-set-default',  'change the default NDN identity, key, or certificate for the current user', None, 1),
+    ('manpages/ndnsec-sign-req',     'ndnsec-sign-req',     'generate an NDN certificate signing request',  None, 1),
+    ('manpages/ndnsec-unlock-tpm',   'ndnsec-unlock-tpm',   'unlock the TPM',                               None, 1),
+    ('manpages/ndn-client.conf',     'ndn-client.conf',     'configuration file for NDN platform',          None, 5),
+    ('manpages/ndn-log',             'ndn-log',             'ndn-cxx logging',                              None, 7),
 ]
 
-
 # If true, show URL addresses after external links.
-man_show_urls = True
+#man_show_urls = True
 
 
-# ---- Custom options --------
+# -- Custom options ----------------------------------------------------------
 
 doxylink = {
-  'ndn-cxx' : ('ndn-cxx.tag', 'doxygen/'),
+    'ndn-cxx': ('ndn-cxx.tag', 'doxygen/'),
+}
+
+extlinks = {
+    'issue': ('https://redmine.named-data.net/issues/%s', 'issue #'),
 }
 
 if os.getenv('GOOGLE_ANALYTICS', None):
     googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
     googleanalytics_enabled = True
-
-# exclude_patterns = ['RELEASE_NOTES.rst']
-
-redmine_project_url = "https://redmine.named-data.net/"
diff --git a/docs/index.rst b/docs/index.rst
index 1749fef..dc3682b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,9 +1,9 @@
 ndn-cxx: NDN C++ library with eXperimental eXtensions
 =====================================================
 
-ndn-cxx is a C++14 library, implementing Named Data Networking (NDN) primitives
-that can be used to write various NDN applications. The library is currently
-being used by the following projects:
+**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
+that can be used to write various NDN applications. The library is currently being
+used by the following projects:
 
 * `NFD - NDN Forwarding Daemon <https://github.com/named-data/NFD>`_
 * `NLSR - Named-data Link-State Routing protocol <https://github.com/named-data/NLSR>`_
diff --git a/docs/manpages/ndnsec-cert-dump.rst b/docs/manpages/ndnsec-cert-dump.rst
index 5aa69a9..04e0107 100644
--- a/docs/manpages/ndnsec-cert-dump.rst
+++ b/docs/manpages/ndnsec-cert-dump.rst
@@ -1,52 +1,50 @@
 ndnsec-cert-dump
 ================
 
-``ndnsec-cert-dump`` is a tool to dump a certificate from **Public Info Base** or file and output
-it to standard output.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-cert-dump [-h] [-p] [-ikf] name
+**ndnsec-cert-dump** [**-h**] [**-p**] [**-r** [**-H** *host*] [**-P** *port*]]
+[**-i**\|\ **-k**\|\ **-f**] *name*
 
 Description
 -----------
 
-``ndnsec-cert-dump`` can read a certificate from **Public Info Base (PIB)** or a file and output
-the certificate to standard output.
+:program:`ndnsec-cert-dump` reads a certificate from the **Public Info Base (PIB)**
+or from a file, and prints it on the standard output.
 
-By default, ``name`` is interpreted as a certificate name.
+By default, *name* is interpreted as a certificate name.
 
 Options
 -------
 
-``-i``
-  Interpret ``name`` as an identity name. If specified, the certificate to dump is the default
-  certificate of the identity.
+.. option:: -i, --identity
 
-``-k``
-  Interpret ``name`` as a key name. If specified, the certificate to dump is the default certificate
-  of the key.
+   Interpret *name* as an identity name. If specified, the certificate to dump
+   is the default certificate of the identity.
 
-``-f``
-  Interpret ``name`` as a path to a file containing the certificate. If ``name`` is ``-``,
-  certificate will be read from standard input.
+.. option:: -k, --key
 
-``-p``
-  Print out the certificate to a human-readable format.
+   Interpret *name* as a key name. If specified, the certificate to dump is the
+   default certificate of the key.
 
-Examples
---------
+.. option:: -f, --file
 
-Dump a certificate from PIB to standard output:
-::
+   Interpret *name* as a path to a file containing the certificate. If *name*
+   is "-", the certificate will be read from the standard input.
+
+.. option:: -p, --pretty
+
+   Print the certificate in a human-readable format.
+
+Example
+-------
+
+Dump a certificate from PIB to standard output::
 
     $ ndnsec-cert-dump /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
 
-Dump a certificate to a human-readable format:
-::
+Dump a certificate in human-readable format::
 
     $ ndnsec-cert-dump -p /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
     Certificate name:
diff --git a/docs/manpages/ndnsec-cert-gen.rst b/docs/manpages/ndnsec-cert-gen.rst
index 97e8e87..3b6617f 100644
--- a/docs/manpages/ndnsec-cert-gen.rst
+++ b/docs/manpages/ndnsec-cert-gen.rst
@@ -1,60 +1,64 @@
 ndnsec-cert-gen
 ===============
 
-``ndnsec-cert-gen`` is a tool to issue an identity certificate.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-cert-gen [-h] [-S timestamp] [-E timestamp] [-I info] [-s sign-id] [-i issuer-id] request
+**ndnsec-cert-gen** [**-h**] [**-S** *timestamp*] [**-E** *timestamp*]
+[**-I** *info*]... [**-s** *signer*] [**-i** *issuer*] *file*
 
 Description
 -----------
 
-``ndnsec-cert-gen`` takes signing request as input and issues an identity certificate for the key in
-the signing request. The signing request can be created during ``ndnsec-keygen`` and can be
-re-generated with ``ndnsec-sign-req``.
+:program:`ndnsec-cert-gen` takes a signing request as input and issues an
+identity certificate for the key in the signing request. The signing request
+can be created with :program:`ndnsec-key-gen` and can be re-generated with
+:program:`ndnsec-sign-req`.
 
-By default, the default key/certificate will be used to sign the issued certificate.
+By default, the default key is used to sign the issued certificate.
 
-``request`` could be a path to a file that contains the signing request. If ``request`` is ``-``,
-then signing request will be read from standard input.
+*file* is the name of a file that contains the signing request. If *file* is
+"-", the signing request is read from the standard input.
 
-The generated certificate will be written to standard output in base64 encoding.
+The generated certificate is written to the standard output in base64 encoding.
 
 Options
 -------
 
-``-S timestamp``
-  Timestamp when the certificate becomes valid. The default value is now.
+.. option:: -S <timestamp>, --not-before <timestamp>
 
-``-E timestamp``
-  Timestamp when the certificate expires. The default value is one year from now.
+   Date and time when the certificate becomes valid, in "YYYYMMDDhhmmss" format.
+   The default value is now.
 
-``-I info``
-  Other information to be included in the issued certificate.  For example,
+.. option:: -E <timestamp>, --not-after <timestamp>
 
-   ::
+   Date and time when the certificate expires, in "YYYYMMDDhhmmss" format.
+   The default value is 365 days after the **--not-before** timestamp.
+
+.. option:: -I <info>, --info <info>
+
+   Other information to be included in the issued certificate. For example::
 
       -I "affiliation Some Organization" -I "homepage http://home.page/"
 
-``-s sign-id``
-  Signing identity. The default key/certificate of ``sign-id`` will be used to sign the requested
-  certificate. If this option is not specified, the system default identity will be used.
+.. option:: -s <signer>, --sign-id <signer>
 
-``-s issuer-id``
-  Issuer's ID to be included as part of the issued certificate name.  If not specified, "NA"
-  value will be used
+   Signing identity. The default key/certificate of *signer* will be used to
+   sign the requested certificate. If this option is not specified, the system
+   default identity will be used.
 
-Examples
---------
+.. option:: -i <issuer>, --issuer-id <issuer>
+
+   Issuer's ID to be included in the issued certificate name. The default
+   value is "NA".
+
+Example
+-------
 
 ::
 
     $ ndnsec-cert-gen -S 20140401000000 -E 20150331235959 -N "David"
-    -I "2.5.4.10 'Some Organization'" -s /ndn/test sign_request.cert
+    -I "2.5.4.10 'Some Organization'" -s /ndn/test request.cert
     Bv0C9wc9CANuZG4IBHRlc3QIA0tFWQgFZGF2aWQIEWtzay0xMzk2OTEzMDU4MTk2
     CAdJRC1DRVJUCAgAAAFFPp2g3hQDGAECFf0BdjCCAXIwIhgPMjAxNDA0MDEwMDAw
     MDBaGA8yMDE1MDMzMTIzNTk1OVowKDAMBgNVBCkTBURhdmlkMBgGA1UEChMRU29t
diff --git a/docs/manpages/ndnsec-cert-install.rst b/docs/manpages/ndnsec-cert-install.rst
index a1a98a3..dae8ee7 100644
--- a/docs/manpages/ndnsec-cert-install.rst
+++ b/docs/manpages/ndnsec-cert-install.rst
@@ -1,56 +1,50 @@
 ndnsec-cert-install
 ===================
 
-``ndnsec-cert-install`` is a tool to install a certificate into **Public Information Base (PIB)**.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-cert-install [-h] [-IKN] cert-source
+**ndnsec-cert-install** [**-h**] [**-I**\|\ **-K**\|\ **-N**] *file*
 
 Description
 -----------
 
-``ndnsec-cert-install`` can insert a certificate into PIB. By default, the installed certificate
-will be set as the default certificate of its corresponding identity and the identity is set as
-the system default identity.
+:program:`ndnsec-cert-install` allows importing a certificate into the
+**Public Information Base (PIB)**. By default, the installed certificate
+will be set as the default certificate for the corresponding identity and
+the identity will be set as the user's default identity.
 
-``cert-source`` could be a filesystem path or an HTTP URL of a file containing to certificate to
-install or . If ``cert-file`` is ``-``, the certificate will be read from standard input.
+*file* can be a filesystem path or an HTTP URL of a file containing the certificate
+to install. If *file* is "-", the certificate will be read from the standard input.
 
 Options
 -------
 
-``-I``
-  Set the certificate as the default certificate of its corresponding identity, but do not change
-  the system default identity.
+.. option:: -I, --identity-default
 
-``-K``
-  Set the certificate as the default certificate of its corresponding key, but do not change the
-  corresponding identity's default key and the system default identity.
+   Set the certificate as the default certificate for the corresponding identity,
+   but do not change the user's default identity.
 
-``-N``
-  Install the certificate but do not change any default settings.
+.. option:: -K, --key-default
 
-Examples
---------
+   Set the certificate as the default certificate for the corresponding key, but
+   do not change the identity's default key or the user's default identity.
 
-Install a certificate and set it as the system default certificate:
+.. option:: -N, --no-default
 
-::
+   Install the certificate but do not change any default settings.
+
+Example
+-------
+
+Install a certificate and set it as the default certificate::
 
     $ ndnsec-cert-install cert_file.cert
 
-Install a certificate with HTTP URL and set it as the system default certificate:
-
-::
+Install a certificate via HTTP and set it as the default certificate::
 
     $ ndnsec-install-cert "http://ndncert.domain.com/cert/get/my-certificate.ndncert"
 
-Install a certificate but do not change any default settings:
-
-::
+Install a certificate but do not change any default settings::
 
     $ ndnsec-cert-install -N cert_file.cert
diff --git a/docs/manpages/ndnsec-delete.rst b/docs/manpages/ndnsec-delete.rst
index 3c808af..141aa0c 100644
--- a/docs/manpages/ndnsec-delete.rst
+++ b/docs/manpages/ndnsec-delete.rst
@@ -1,32 +1,32 @@
 ndnsec-delete
 =============
 
-``ndnsec-delete`` is a tool to delete security data from both **Public Info Base** and
-**Trusted Platform Module**.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-delete [-h] [-kc] name
+**ndnsec-delete** [**-h**] [**-k**\|\ **-c**] *name*
 
 Description
 -----------
 
-By default, ``ndnsec-delete`` interpret ``name`` as an identity name. If an identity is deleted,
-all the keys and certificates belonging to the identity will be deleted as well. If a key is
-deleted,  all the certificate belonging to the key will be deleted as well.
+:program:`ndnsec-delete` allows to delete security data from both the
+**Public Info Base (PIB)** and the **Trusted Platform Module (TPM)**.
 
+By default, :program:`ndnsec-delete` will interpret *name* as an identity name.
+If an identity is deleted, all keys and certificates belonging to that identity
+will be deleted as well. If a key is deleted, all certificates associated with
+that key will be deleted as well.
 
 Options
 -------
 
-``-k``
-  Interpret ``name`` as a key name and delete the key and its related data.
+.. option:: -k, --delete-key
 
-``-c``
-  Interpret ``name`` as a certificate name and delete the certificate.
+   Interpret *name* as a key name and delete the key and its associated data.
+
+.. option:: -c, --delete-cert
+
+   Interpret *name* as a certificate name and delete the certificate.
 
 Exit Status
 -----------
@@ -35,11 +35,9 @@
 If the entity to be deleted does not exist, the exit status is 1.
 For other errors, the exit status is 2.
 
-Examples
---------
+Example
+-------
 
-Delete all data related to an identity:
-
-::
+Delete all data related to an identity::
 
     $ ndnsec-delete /ndn/test/david
diff --git a/docs/manpages/ndnsec-export.rst b/docs/manpages/ndnsec-export.rst
index 7b51ad4..4d7e277 100644
--- a/docs/manpages/ndnsec-export.rst
+++ b/docs/manpages/ndnsec-export.rst
@@ -1,49 +1,39 @@
 ndnsec-export
 =============
 
-Usage
------
+Synopsis
+--------
 
-::
-
-    ndnsec-export [-h] [-o output] identity
+**ndnsec-export** [**-h**] [**-o** *file*] [**-P** *passphrase*] *identity*
 
 Description
 -----------
 
-``ndnsec-export`` exports the default certificate of an identity and its private key as a file. It
-will ask for a passphrase to encrypt the private key. The output file can be imported again with
-``ndnsec-import`` command.
+:program:`ndnsec-export` exports the default certificate of *identity* and its
+private key to a file. It will ask for a passphrase to encrypt the private key.
+The resulting file can be imported again using :program:`ndnsec-import`.
 
 Options
 -------
 
-``-h``
-  Print a help message.
+.. option:: -o <file>, --output <file>
 
-``-o output``
-  Write to an output file instead of the standard output.
+   Write to the specified output file instead of the standard output.
 
-``-P passphrase``
-  Passphrase to use for the export. If not specified (or specified an empty passphrase), the
-  user is interactively asked to input the passphrase on the terminal. Note that specifying
-  passphrase via -P is insecure, as it can potentially end up in shell history, be visible in
-  ps output, etc.
+.. option:: -P <passphrase>, --password <passphrase>
 
-``identity``
-  The identity name.
+   Passphrase to use for the export. If empty or not specified, the user is
+   interactively asked to type the passphrase on the terminal. Note that
+   specifying the passphrase via this option is insecure, as it can potentially
+   end up in the shell's history, be visible in :command:`ps` output, and so on.
 
-Examples
---------
+Example
+-------
 
-Export an identity's default certificate and private key into a file:
-
-::
+Export an identity's default certificate and private key into a file::
 
     $ ndnsec-export -o alice.ndnkey /ndn/test/alice
 
-Export an identity's default certificate and private key to the standard output:
-
-::
+Export an identity's default certificate and private key to the standard output::
 
     $ ndnsec-export /ndn/test/alice
diff --git a/docs/manpages/ndnsec-get-default.rst b/docs/manpages/ndnsec-get-default.rst
index 54da09e..0a27dee 100644
--- a/docs/manpages/ndnsec-get-default.rst
+++ b/docs/manpages/ndnsec-get-default.rst
@@ -1,61 +1,56 @@
 ndnsec-get-default
 ==================
 
-``ndnsec-get-default`` is a tool to display the default setting of a particular entity.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-get-default [-h] [-kc] [-i identity|-K key] [-q]
+**ndnsec-get-default** [**-h**] [**-k**\|\ **-c**] [**-i** *identity*\|\ **-K** *key*] [**-q**]
 
 Description
 -----------
 
-Given a particular entity, ``ndnsec-get-default`` can display its default setting as specified in
-options. If ``identity`` is specified, the given entity becomes the identity. If ``key`` is
-specified, the given identity becomes the key. If no entity is specified, the command will take the
-system default identity as the given entity.
+Given a particular entity, :program:`ndnsec-get-default` shows its default settings
+according to the command-line options. By default, if neither **-i** nor **-K** is
+given, the command displays the default identity or the default key/certificate of
+the default identity.
 
 Options
 -------
 
-``-k``
-  Display the given entity's default key name.
+.. option:: -k, --default-key
 
-``-c``
-  Display the given entity's default certificate name.
+   Display the chosen entity's default key name.
 
-``-i identity``
-  Display default setting of the ``identity``
+.. option:: -c, --default-cert
 
-``-K key``
-  Display default setting of the ``key``.
+   Display the chosen entity's default certificate name.
 
-``-q``
-  Disable trailling new line character.
+.. option:: -i <identity>, --identity <identity>
 
-Examples
---------
+   Display default settings of *identity*.
 
-Display an identity's default key name.
+.. option:: -K <key>, --key <key>
 
-::
+   Display default settings of *key*.
+
+.. option:: -q, --quiet
+
+   Disable printing the trailing newline character.
+
+Example
+-------
+
+Display an identity's default key name::
 
     $ ndnsec-get-default -k -i /ndn/test/alice
     /ndn/test/alice/ksk-1394129695025
 
-Display an identity's default certificate name.
-
-::
+Display an identity's default certificate name::
 
     $ ndnsec-get-default -c -i /ndn/test/alice
     /ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F
 
-Display a key's default certificate name.
-
-::
+Display a key's default certificate name::
 
     $ ndnsec-get-default -c -K /ndn/test/alice/ksk-1394129695025
     /ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F
diff --git a/docs/manpages/ndnsec-import.rst b/docs/manpages/ndnsec-import.rst
index 7dd02ed..7c25a6a 100644
--- a/docs/manpages/ndnsec-import.rst
+++ b/docs/manpages/ndnsec-import.rst
@@ -1,39 +1,33 @@
 ndnsec-import
 =============
 
-Usage
------
+Synopsis
+--------
 
-::
-
-    ndnsec-import [-h] input
+**ndnsec-import** [**-h**] [**-P** *passphrase*] *file*
 
 Description
 -----------
 
-``ndnsec-import`` imports a certificate and private key from a file created by ``ndnsec-export``. It
-will ask for the passphrase used to encrypt the private key.
+:program:`ndnsec-import` imports a certificate and its private key from a file
+created by :program:`ndnsec-export`. It will ask for the passphrase used to
+encrypt the private key.
+
+If *file* is "-", read from the standard input.
 
 Options
 -------
 
-``-h``
-  Print a help message.
+.. option:: -P <passphrase>, --password <passphrase>
 
-``-P passphrase``
-  Passphrase to use for the export. If not specified (or specified an empty passphrase), the
-  user is interactively asked to input the passphrase on the terminal. Note that specifying
-  passphrase via -P is insecure, as it can potentially end up in shell history, be visible in
-  ps output, etc.
+   Passphrase to use for the export. If empty or not specified, the user is
+   interactively asked to type the passphrase on the terminal. Note that
+   specifying the passphrase via this option is insecure, as it can potentially
+   end up in the shell's history, be visible in :command:`ps` output, and so on.
 
-``input``
-  Read from an input file. Specify ``-`` to read from the standard input.
+Example
+-------
 
-Examples
---------
-
-Import a certificate and private key from a file:
-
-::
+Import a certificate and private key from a file::
 
     $ ndnsec-import alice.ndnkey
diff --git a/docs/manpages/ndnsec-key-gen.rst b/docs/manpages/ndnsec-key-gen.rst
index 304f189..0d68b86 100644
--- a/docs/manpages/ndnsec-key-gen.rst
+++ b/docs/manpages/ndnsec-key-gen.rst
@@ -1,38 +1,42 @@
 ndnsec-key-gen
 ==============
 
-``ndnsec-key-gen`` is tool to generate a pair of key.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-key-gen [-h] [-n] [-d] [-t keyType] identity
+**ndnsec-key-gen** [**-h**] [**-n**] [**-t** *type*] [**-k** *keyidtype*] *identity*
 
 Description
 -----------
 
-``ndnsec-key-gen`` creates a key pair for the specified ``identity`` and sets the key as the
-identity's default key. ``ndnsec-key-gen`` will also create a signing request for the generated key.
-The signing request will be written to standard output in base64 encoding.
+:program:`ndnsec-key-gen` generates a key pair for the specified *identity* and
+sets the generated public key as the identity's default key.
+:program:`ndnsec-key-gen` will also create a signing request for the generated key.
+The signing request will be written to the standard output in base64 encoding.
 
-By default, it will also set the identity as the system default identity.
+By default, it will also set the identity as the user's default identity.
 
 Options
 -------
 
-``-n``
-  Do not set the identity as the system default identity.
+.. option:: -n, --not-default
 
-  Note that if it is the first identity/key/certificate, then it will be
-  set as default regardless of ``-n`` flag.
+   Do not set the identity as the user's default identity.
 
-``-t keyType``
-  Specify the key type. ``r`` (default) for RSA key. ``e`` for ECDSA key.
+   Note that if no other identity/key/certificate exists, then the identity
+   will become the default regardless of this option.
 
-Examples
---------
+.. option:: -t <type>, --type <type>
+
+   Type of key to generate. "r" for RSA (default), "e" for ECDSA.
+
+.. option:: -k <keyidtype>, --keyid-type <keyidtype>
+
+   Type of KeyId for the generated key. "r" for 64-bit random number (default),
+   "h" for SHA256 of the public key.
+
+Example
+-------
 
 ::
 
diff --git a/docs/manpages/ndnsec-list.rst b/docs/manpages/ndnsec-list.rst
index a3de1a9..e0fde91 100644
--- a/docs/manpages/ndnsec-list.rst
+++ b/docs/manpages/ndnsec-list.rst
@@ -1,24 +1,20 @@
 ndnsec-list
 ===========
 
-``ndnsec-list`` is a tool to display entities stored in **Public Information Base (PIB)**, such as
-identities, keys, and certificates.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-list [-h] [-KkCc]
+**ndnsec-list** [**-h**] [**-k**\|\ **-c**]
 
 Description
 -----------
 
-``ndnsec-list`` lists names of all the entities according to the granularity specified in options
-(The default granularity is identity). The default entities will be marked with ``*`` in front of
-their names. For example:
+:program:`ndnsec-list` prints the names of all the entities stored in the
+**Public Information Base (PIB)**, such as identities, keys, and certificates,
+up to the given granularity level. By default, only the identity names are
+shown. The default entities will be marked with a "*" in front of their names.
 
-::
+For example::
 
     $ ndnsec list
     * /ndn/edu/ucla/cs/yingdi
@@ -26,24 +22,23 @@
       /ndn/test/bob
       /ndn/test/alice
 
-
 Options
 -------
 
-``-K, -k``
-  Display key names for each identity. The key name with ``*`` in front is the default key name of
-  the corresponding identity.
+.. option:: -k, --key
 
-``-C, -c``
-  Display certificate names for each key. The certificate name with ``*`` in front is the default
-  certificate name of the corresponding key.
+   Display key names for each identity. The key name with a "*" in front is
+   the default key name of the corresponding identity.
 
-Examples
---------
+.. option:: -c, --cert
 
-Display all the key names in PIB.
+   Display certificate names for each key. The certificate name with a "*"
+   in front is the default certificate name of the corresponding key.
 
-::
+Example
+-------
+
+Display all the key names in PIB::
 
     $ ndnsec-list -k
     * /ndn/edu/ucla/cs/yingdi
@@ -59,9 +54,7 @@
       /ndn/test/alice
       +->* /ndn/test/alice/ksk-1394129695025
 
-Display all the certificate names in PIB.
-
-::
+Display all the certificate names in PIB::
 
     $ ndnsec-list -c
     * /ndn/edu/ucla/cs/yingdi
diff --git a/docs/manpages/ndnsec-set-default.rst b/docs/manpages/ndnsec-set-default.rst
index 4af6ad9..05c6677 100644
--- a/docs/manpages/ndnsec-set-default.rst
+++ b/docs/manpages/ndnsec-set-default.rst
@@ -1,49 +1,43 @@
 ndnsec-set-default
 ==================
 
-``ndnsec-set-default`` is a tool to change the default security settings.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-set-default [-h] [-k|c] name
+**ndnsec-set-default** [**-h**] [**-k**\|\ **-c**] *name*
 
 Description
 -----------
 
-By default, ``ndnsec-set-default`` takes ``name`` as an identity name and sets the identity as the
-system default identity.
+:program:`ndnsec-set-default` allows changing the default security settings.
+
+Without any options, *name*, which must be an identity name, is set as the
+default identity for the current user.
 
 Options
 -------
 
-``-k``
-  Set default key. ``name`` should be a key name, ``ndnsec-set-default`` can infer the corresponding
-  identity and set the key as the identity's default key.
+.. option:: -k, --default-key
 
-``-c``
-  Set default certificate. ``name`` should be a certificate name, ``ndnsec-set-default`` can
-  infer the corresponding key name and set the certificate as the key's default certificate.
+   Set *name*, which must be a key name, as the default key for the
+   corresponding identity.
 
-Examples
---------
+.. option:: -c, --default-cert
 
-Set a key's default certificate:
+   Set *name*, which must be a certificate name, as the default certificate
+   for the corresponding key.
 
-::
+Example
+-------
+
+Set a key's default certificate::
 
     $ ndnsec-set-default -c /ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F
 
-Set an identity's default key:
-
-::
+Set an identity's default key::
 
     $ ndnsec-set-default -k /ndn/test/alice/ksk-1394129695025
 
-Set system default identity:
-
-::
+Set the user's default identity::
 
     $ ndnsec-set-default /ndn/test/alice
diff --git a/docs/manpages/ndnsec-sign-req.rst b/docs/manpages/ndnsec-sign-req.rst
index 90a0694..d17ff3c 100644
--- a/docs/manpages/ndnsec-sign-req.rst
+++ b/docs/manpages/ndnsec-sign-req.rst
@@ -1,37 +1,35 @@
 ndnsec-sign-req
 ===============
 
-``ndnsec-sign-req`` is a tool to generate a signing request for a particular key.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-sign-req [-h] [-k] name
+**ndnsec-sign-req** [**-h**] [**-k**] *name*
 
 Description
 -----------
 
-The signing request of a key is actually a self-signed certificate. Given key's information,
-``ndnsec-sign-req`` looks up the key in PIB. If such a key exists, a self-signed certificate of the
-key, or its signing request, will be outputed to **stdout** with base64 encoding.
+:program:`ndnsec-sign-req` generates a signing request for a key.
 
-By default, ``name`` is interpreted as an identity name. ``ndnsec-sign-req`` will generate a
-signing request for the identity's default key.
+The signing request of a key is actually a self-signed certificate. Given the
+key's information, :program:`ndnsec-sign-req` looks up the key in the PIB.
+If such a key exists, a self-signed certificate for the key, i.e. its signing
+request, is written to the standard output in base64 encoding.
+
+By default, *name* is interpreted as an identity name, and the signing request
+will be generated for that identity's default key.
 
 Options
 -------
 
-``-k``
-  Interpret ``name`` as a key name.
+.. option:: -k, --key
 
-Examples
---------
+   Interpret *name* as a key name, instead of an identity name.
 
-Create a signing request for an identity's default key.
+Example
+-------
 
-::
+Create a signing request for an identity's default key::
 
     $ ndnsec-sign-req /ndn/test/david
     Bv0DAAc9CANuZG4IBHRlc3QIBWRhdmlkCANLRVkIEWtzay0xMzk2OTk4Mzg5MjU3
@@ -52,10 +50,7 @@
     0wHjvDS1cuIH2j6XveoUYapRjZXaEZqB/YoBwRqEYq2KVn/ol5knLM6FIISXXjxn
     cIh62A==
 
-
-Create a signing request for a particular key.
-
-::
+Create a signing request for a particular key::
 
     $ ndnsec-sign-req -k /ndn/test/david/ksk-1396913058196
     Bv0DAAc9CANuZG4IBHRlc3QIBWRhdmlkCANLRVkIEWtzay0xMzk2OTEzMDU4MTk2
diff --git a/docs/manpages/ndnsec-unlock-tpm.rst b/docs/manpages/ndnsec-unlock-tpm.rst
index 175ba51..f5a8d92 100644
--- a/docs/manpages/ndnsec-unlock-tpm.rst
+++ b/docs/manpages/ndnsec-unlock-tpm.rst
@@ -1,17 +1,13 @@
 ndnsec-unlock-tpm
 =================
 
-``ndnsec-unlock-tpm`` is a tool to (temporarily) unlock the **Trusted Platform Module (TPM)** that
-manages private keys.
+Synopsis
+--------
 
-Usage
------
-
-::
-
-    ndnsec-unlock-tpm [-h]
+ndnsec-unlock-tpm [**-h**]
 
 Description
 -----------
 
-``ndnsec-unlock-tpm`` will ask for password to unlock the TPM.
+:program:`ndnsec-unlock-tpm` can be used to (temporarily) unlock the
+**Trusted Platform Module (TPM)** that manages private keys.
diff --git a/docs/redmine_issue.py b/docs/redmine_issue.py
deleted file mode 100644
index 0df2b1f..0000000
--- a/docs/redmine_issue.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-# Based on http://doughellmann.com/2010/05/09/defining-custom-roles-in-sphinx.html
-
-"""Integration of Sphinx with Redmine.
-"""
-
-from docutils import nodes, utils
-from docutils.parsers.rst.roles import set_classes
-
-def redmine_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
-    """Link to a Redmine issue.
-
-    Returns 2 part tuple containing list of nodes to insert into the
-    document and a list of system messages.  Both are allowed to be
-    empty.
-
-    :param name: The role name used in the document.
-    :param rawtext: The entire markup snippet, with role.
-    :param text: The text marked with the role.
-    :param lineno: The line number where rawtext appears in the input.
-    :param inliner: The inliner instance that called us.
-    :param options: Directive options for customization.
-    :param content: The directive content for customization.
-    """
-    try:
-        issue_num = int(text)
-        if issue_num <= 0:
-            raise ValueError
-    except ValueError:
-        msg = inliner.reporter.error(
-            'Redmine issue number must be a number greater than or equal to 1; '
-            '"%s" is invalid.' % text, line=lineno)
-        prb = inliner.problematic(rawtext, rawtext, msg)
-        return [prb], [msg]
-    app = inliner.document.settings.env.app
-    node = make_link_node(rawtext, app, 'issues', str(issue_num), options)
-    return [node], []
-
-def make_link_node(rawtext, app, type, slug, options):
-    """Create a link to a Redmine resource.
-
-    :param rawtext: Text being replaced with link node.
-    :param app: Sphinx application context
-    :param type: Link type (issue, changeset, etc.)
-    :param slug: ID of the thing to link to
-    :param options: Options dictionary passed to role func.
-    """
-    #
-    try:
-        base = app.config.redmine_project_url
-        if not base:
-            raise AttributeError
-    except AttributeError:
-        raise ValueError('redmine_project_url configuration value is not set')
-    #
-    slash = '/' if base[-1] != '/' else ''
-    ref = base + slash + type + '/' + slug + '/'
-    set_classes(options)
-    node = nodes.reference(rawtext, 'Issue #' + utils.unescape(slug), refuri=ref,
-                           **options)
-    return node
-
-def setup(app):
-    """Install the plugin.
-
-    :param app: Sphinx application context.
-    """
-    app.add_role('issue', redmine_role)
-    app.add_config_value('redmine_project_url', None, 'env')
-    return
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 39d5baf..52b9f9f 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.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,6 +22,7 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
+#include <boost/asio/ip/tcp.hpp>
 #if BOOST_VERSION < 106700
 #include <boost/date_time/posix_time/posix_time_duration.hpp>
 #endif // BOOST_VERSION < 106700
@@ -35,39 +36,37 @@
   namespace po = boost::program_options;
 
   std::string name;
-  bool isKeyName = false;
   bool isIdentityName = false;
-  bool isCertName = true;
-  // bool isFileName = false;
+  bool isKeyName = false;
+  bool isFileName = false;
   bool isPretty = false;
-  bool isStdOut = true;
   bool isRepoOut = false;
   std::string repoHost;
   std::string repoPort;
-  // bool isDnsOut = false;
 
-  po::options_description description("General Usage\n"
-                                      "  ndnsec cert-dump [-h] [-p] [-d] [-r [-H repo-host] "
-                                         "[-P repo-port] ] [-i|k|f] name\n"
-                                      "General options");
+  po::options_description description(
+    "Usage: ndnsec cert-dump [-h] [-p] [-r [-H HOST] [-P PORT]] [-i|-k|-f] [-n] NAME\n"
+    "\n"
+    "Options");
   description.add_options()
-    ("help,h",     "produce help message")
-    ("pretty,p",   "display certificate in human readable format")
-    ("identity,i", "treat the name parameter as identity name (e.g., /ndn/edu/ucla/alice")
-    ("key,k",      "treat the name parameter as key name "
-                   "(e.g., /ndn/edu/ucla/alice/ksk-123456789)")
-    ("file,f",     "treat the name parameter as file name with base64 encoded certificate, "
-                   "- for stdin")
-    ("repo-output,r", "publish the certificate to the repo-ng")
-    ("repo-host,H", po::value<std::string>(&repoHost)->default_value("localhost"),
-                   "the repo host if repo-output is specified")
-    ("repo-port,P", po::value<std::string>(&repoPort)->default_value("7376"),
-                   "the repo port if repo-output is specified")
-    // ("dns-output,d", "published the certificate to NDNS")
-    ("name,n", po::value<std::string>(&name),
-                   "unless overridden with --identity or --key parameter, the certificate name, "
-                   "for example, /ndn/edu/ucla/KEY/cs/alice/ksk-1234567890"
-                                "/ID-CERT/%FD%FF%FF%FF%FF%FF%FF%FF")
+    ("help,h", "produce help message")
+    ("pretty,p",   po::bool_switch(&isPretty), "display certificate in human readable format")
+    ("identity,i", po::bool_switch(&isIdentityName),
+                   "treat the NAME argument as an identity name (e.g., /ndn/edu/ucla/alice)")
+    ("key,k",      po::bool_switch(&isKeyName),
+                   "treat the NAME argument as a key name (e.g., /ndn/edu/ucla/alice/ksk-123456789)")
+    ("file,f",     po::bool_switch(&isFileName),
+                   "treat the NAME argument as the name of a file containing a base64-encoded "
+                   "certificate, '-' for stdin")
+    ("name,n",     po::value<std::string>(&name),
+                   "unless overridden by -i/-k/-f, the name of the certificate to be exported "
+                   "(e.g., /ndn/edu/ucla/KEY/cs/alice/ksk-1234567890/ID-CERT/%FD%FF%FF%FF%FF%FF%FF%FF)")
+    ("repo-output,r", po::bool_switch(&isRepoOut),
+                      "publish the certificate into a repo-ng instance")
+    ("repo-host,H",   po::value<std::string>(&repoHost)->default_value("localhost"),
+                      "repo hostname if --repo-output is specified")
+    ("repo-port,P",   po::value<std::string>(&repoPort)->default_value("7376"),
+                      "repo port number if --repo-output is specified")
     ;
 
   po::positional_options_description p;
@@ -79,119 +78,87 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("name") == 0) {
-    std::cerr << "identity_name must be specified" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: you must specify a name" << std::endl;
+    return 2;
   }
 
-  if (vm.count("key") != 0) {
-    isCertName = false;
-    isKeyName = true;
-  }
-  else if (vm.count("identity") != 0) {
-    isCertName = false;
-    isIdentityName = true;
-  }
-  else if (vm.count("file") != 0) {
-    isCertName = false;
-    // isFileName = true;
+  if (isIdentityName + isKeyName + isFileName > 1) {
+    std::cerr << "ERROR: at most one of '--identity', '--key', "
+                 "or '--file' may be specified" << std::endl;
+    return 2;
   }
 
-  if (vm.count("pretty") != 0)
-    isPretty = true;
-
-  if (vm.count("repo-output") != 0) {
-    isRepoOut = true;
-    isStdOut = false;
+  if (isPretty && isRepoOut) {
+    std::cerr << "ERROR: '--pretty' is incompatible with '--repo-output'" << std::endl;
+    return 2;
   }
-  else if (vm.count("dns-output") != 0) {
-    // 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;
-  }
-
-  security::v2::Certificate certificate;
 
   security::v2::KeyChain keyChain;
 
+  security::v2::Certificate certificate;
   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))
-          .getCertificate(name);
-      }
+    if (isIdentityName) {
+      certificate = keyChain.getPib()
+                    .getIdentity(name)
+                    .getDefaultKey()
+                    .getDefaultCertificate();
     }
-    else {
+    else if (isKeyName) {
+      certificate = keyChain.getPib()
+                    .getIdentity(security::v2::extractIdentityFromKeyName(name))
+                    .getKey(name)
+                    .getDefaultCertificate();
+    }
+    else if (isFileName) {
       certificate = loadCertificate(name);
     }
-  }
-  catch (const security::Pib::Error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 1;
+    else {
+      certificate = keyChain.getPib()
+                    .getIdentity(security::v2::extractIdentityFromCertName(name))
+                    .getKey(security::v2::extractKeyNameFromCertName(name))
+                    .getCertificate(name);
+    }
   }
   catch (const CannotLoadCertificate&) {
-    std::cerr << "Cannot load certificate from `" << name << "`" << std::endl;
+    std::cerr << "ERROR: Cannot load the certificate from `" << name << "`" << std::endl;
     return 1;
   }
 
   if (isPretty) {
     std::cout << certificate << std::endl;
+    return 0;
   }
-  else {
-    if (isStdOut) {
-      io::save(certificate, std::cout);
-      return 0;
-    }
-    if (isRepoOut) {
-      boost::asio::ip::tcp::iostream requestStream;
-#if BOOST_VERSION >= 106700
-      requestStream.expires_after(std::chrono::seconds(3));
-#else
-      requestStream.expires_from_now(boost::posix_time::seconds(3));
-#endif // BOOST_VERSION >= 106700
-      requestStream.connect(repoHost, repoPort);
-      if (!requestStream) {
-        std::cerr << "fail to open the stream!" << std::endl;
-        return 1;
-      }
-      requestStream.write(reinterpret_cast<const char*>(certificate.wireEncode().wire()),
-                          certificate.wireEncode().size());
 
-      return 0;
+  if (isRepoOut) {
+    boost::asio::ip::tcp::iostream requestStream;
+#if BOOST_VERSION >= 106700
+    requestStream.expires_after(std::chrono::seconds(10));
+#else
+    requestStream.expires_from_now(boost::posix_time::seconds(10));
+#endif // BOOST_VERSION >= 106700
+    requestStream.connect(repoHost, repoPort);
+    if (!requestStream) {
+      std::cerr << "ERROR: Failed to connect to repo instance" << std::endl;
+      return 1;
     }
+    requestStream.write(reinterpret_cast<const char*>(certificate.wireEncode().wire()),
+                        certificate.wireEncode().size());
+    return 0;
   }
+
+  io::save(certificate, std::cout);
+
   return 0;
 }
 
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;
diff --git a/tools/ndnsec/cert-install.cpp b/tools/ndnsec/cert-install.cpp
index 7bf17a0..9ee4d87 100644
--- a/tools/ndnsec/cert-install.cpp
+++ b/tools/ndnsec/cert-install.cpp
@@ -22,6 +22,12 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
+#include "ndn-cxx/encoding/buffer-stream.hpp"
+#include "ndn-cxx/security/transform/base64-decode.hpp"
+#include "ndn-cxx/security/transform/stream-sink.hpp"
+#include "ndn-cxx/security/transform/stream-source.hpp"
+
+#include <boost/asio/ip/tcp.hpp>
 #if BOOST_VERSION < 106700
 #include <boost/date_time/posix_time/posix_time_duration.hpp>
 #endif // BOOST_VERSION < 106700
@@ -44,9 +50,9 @@
 {
   boost::asio::ip::tcp::iostream requestStream;
 #if BOOST_VERSION >= 106700
-  requestStream.expires_after(std::chrono::seconds(3));
+  requestStream.expires_after(std::chrono::seconds(10));
 #else
-  requestStream.expires_from_now(boost::posix_time::seconds(3));
+  requestStream.expires_from_now(boost::posix_time::seconds(10));
 #endif // BOOST_VERSION >= 106700
 
   requestStream.connect(host, port);
@@ -85,7 +91,7 @@
   while (std::getline(requestStream, header) && header != "\r")
     ;
 
-  ndn::OBufferStream os;
+  OBufferStream os;
   {
     using namespace ndn::security::transform;
     streamSource(requestStream) >> base64Decode(true) >> streamSink(os);
@@ -99,21 +105,29 @@
 {
   namespace po = boost::program_options;
 
-  std::string certFileName;
-  bool isSystemDefault = true;
+  std::string certFile;
   bool isIdentityDefault = false;
   bool isKeyDefault = false;
+  bool isNoDefault = false;
 
-  po::options_description description("General Usage\n  ndnsec cert-install [-h] [-I|K|N] cert-file\nGeneral options");
+  po::options_description description(
+    "Usage: ndnsec cert-install [-h] [-I|-K|-N] [-f] FILE\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
-    ("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")
-    ("key-default,K", "optional, if specified, the certificate will be set as the default certificate of the key")
-    ("no-default,N", "optional, if specified, the certificate will be simply installed")
+    ("cert-file,f",        po::value<std::string>(&certFile),
+                           "file name of the certificate to be imported, '-' for stdin; "
+                           "if it starts with 'http://', the certificate will be fetched "
+                           "using a plain HTTP/1.0 GET request")
+    ("identity-default,I", po::bool_switch(&isIdentityDefault),
+                           "set the imported certificate as the default certificate for the identity")
+    ("key-default,K",      po::bool_switch(&isKeyDefault),
+                           "set the imported certificate as the default certificate for the key")
+    ("no-default,N",       po::bool_switch(&isNoDefault),
+                           "do not change any default settings")
     ;
+
   po::positional_options_description p;
   p.add("cert-file", 1);
 
@@ -123,97 +137,84 @@
     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) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("cert-file") == 0) {
-    std::cerr << "cert_file must be specified" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: you must specify a file name" << std::endl;
+    return 2;
   }
 
-  if (vm.count("identity-default") != 0) {
-    isIdentityDefault = true;
-    isSystemDefault = false;
-  }
-  else if (vm.count("key-default") != 0) {
-    isKeyDefault = true;
-    isSystemDefault = false;
-  }
-  else if (vm.count("no-default") != 0) {
-    // noDefault = true;
-    isSystemDefault = false;
+  if (isIdentityDefault + isKeyDefault + isNoDefault > 1) {
+    std::cerr << "ERROR: at most one of '--identity-default', '--key-default', "
+                 "or '--no-default' may be specified" << std::endl;
+    return 2;
   }
 
   security::v2::Certificate cert;
   try {
-    if (certFileName.find("http://") == 0) {
+    if (certFile.find("http://") == 0) {
       std::string host;
       std::string port;
       std::string path;
 
       size_t pos = 7; // offset of "http://"
-      size_t posSlash = certFileName.find("/", pos);
+      size_t posSlash = certFile.find("/", pos);
 
       if (posSlash == std::string::npos)
         NDN_THROW(HttpException("Request line is not correctly formatted"));
 
-      size_t posPort = certFileName.find(":", pos);
+      size_t posPort = certFile.find(":", pos);
 
       if (posPort != std::string::npos && posPort < posSlash) {
         // port is specified
-        port = certFileName.substr(posPort + 1, posSlash - posPort - 1);
-        host = certFileName.substr(pos, posPort - pos);
+        port = certFile.substr(posPort + 1, posSlash - posPort - 1);
+        host = certFile.substr(pos, posPort - pos);
       }
       else {
         port = "80";
-        host = certFileName.substr(pos, posSlash - pos);
+        host = certFile.substr(pos, posSlash - pos);
       }
 
-      path = certFileName.substr(posSlash, certFileName.size() - posSlash);
+      path = certFile.substr(posSlash, certFile.size() - posSlash);
 
       cert = getCertificateHttp(host, port, path);
     }
     else {
-      cert = loadCertificate(certFileName);
+      cert = loadCertificate(certFile);
     }
   }
   catch (const CannotLoadCertificate&) {
-    std::cerr << "ERROR: Cannot load the certificate " << certFileName << std::endl;
+    std::cerr << "ERROR: Cannot load the certificate from `" << certFile << "`" << std::endl;
     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;
-  }
+
+  auto id = keyChain.getPib().getIdentity(cert.getIdentity());
+  auto key = id.getKey(cert.getKeyName());
 
   keyChain.addCertificate(key, cert);
 
-  if (isSystemDefault) {
-    keyChain.setDefaultIdentity(id);
-    keyChain.setDefaultKey(id, key);
-    keyChain.setDefaultCertificate(key, cert);
-  }
-  else if (isIdentityDefault) {
+  if (isIdentityDefault) {
     keyChain.setDefaultKey(id, key);
     keyChain.setDefaultCertificate(key, cert);
   }
   else if (isKeyDefault) {
     keyChain.setDefaultCertificate(key, cert);
   }
+  else if (!isNoDefault) {
+    keyChain.setDefaultIdentity(id);
+    keyChain.setDefaultKey(id, key);
+    keyChain.setDefaultCertificate(key, cert);
+  }
 
   std::cerr << "OK: certificate with name [" << cert.getName().toUri() << "] "
             << "has been successfully installed" << std::endl;
diff --git a/tools/ndnsec/delete.cpp b/tools/ndnsec/delete.cpp
index 8c08cf0..376e3e3 100644
--- a/tools/ndnsec/delete.cpp
+++ b/tools/ndnsec/delete.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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).
  *
@@ -30,20 +30,22 @@
 {
   namespace po = boost::program_options;
 
-  bool isDeleteKey = false;
-  bool isDeleteCert = false;
+  bool wantDeleteKey = false;
+  bool wantDeleteCert = false;
   std::string name;
 
-  po::options_description description("General Usage\n"
-                                      "ndnsec delete [-h] [-k|c] name\n"
-                                      "General options");
+  po::options_description description(
+    "Usage: ndnsec delete [-h] [-k|-c] [-n] NAME\n"
+    "\n"
+    "Options");
   description.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.");
+    ("delete-key,k",  po::bool_switch(&wantDeleteKey), "delete a key")
+    ("delete-cert,c", po::bool_switch(&wantDeleteCert), "delete a certificate")
+    ("name,n",        po::value<std::string>(&name),
+                      "name of the item to delete. 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;
@@ -55,63 +57,56 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
     return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("name") == 0) {
-    std::cerr << "ERROR: name must be specified" << std::endl;
-    std::cerr << description << std::endl;
+    std::cerr << "ERROR: you must specify a name" << std::endl;
     return 2;
   }
 
-  if (vm.count("delete-cert") != 0) {
-    isDeleteCert = true;
-  }
-  else if (vm.count("delete-key") != 0) {
-    isDeleteKey = true;
+  if (wantDeleteKey && wantDeleteCert) {
+    std::cerr << "ERROR: cannot specify both '--delete-key' and '--delete-cert'" << std::endl;
+    return 2;
   }
 
   security::v2::KeyChain keyChain;
 
   try {
-    if (isDeleteCert) {
+    if (wantDeleteCert) {
       security::Key key = keyChain.getPib()
         .getIdentity(security::v2::extractIdentityFromCertName(name))
         .getKey(security::v2::extractKeyNameFromCertName(name));
 
       keyChain.deleteCertificate(key, key.getCertificate(name).getName());
-      std::cerr << "OK: Delete certificate: " << name << std::endl;
+      std::cerr << "OK: certificate deleted: " << name << std::endl;
     }
-    else if (isDeleteKey) {
+    else if (wantDeleteKey) {
       security::Identity identity = keyChain.getPib()
         .getIdentity(security::v2::extractIdentityFromKeyName(name));
 
       keyChain.deleteKey(identity, identity.getKey(name));
-      std::cerr << "OK: Delete key: " << name << std::endl;
+      std::cerr << "OK: key deleted: " << name << std::endl;
     }
     else {
       keyChain.deleteIdentity(keyChain.getPib().getIdentity(name));
-      std::cerr << "OK: Delete identity: " << name << std::endl;
+      std::cerr << "OK: identity deleted: " << name << std::endl;
     }
   }
   catch (const security::Pib::Error& e) {
     std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
-    return 2;
+    return 1;
   }
   catch (const security::Tpm::Error& e) {
     std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
-    return 2;
-  }
-  catch (const security::v2::KeyChain::Error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 2;
+    return 1;
   }
 
   return 0;
diff --git a/tools/ndnsec/export.cpp b/tools/ndnsec/export.cpp
index a345d44..a11459d 100644
--- a/tools/ndnsec/export.cpp
+++ b/tools/ndnsec/export.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,6 +22,10 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
+#include "ndn-cxx/security/impl/openssl.hpp"
+
+#include <boost/scope_exit.hpp>
+
 namespace ndn {
 namespace ndnsec {
 
@@ -32,16 +36,23 @@
 
   Name identityName;
   std::string output;
-  std::string exportPassword;
+  std::string password;
 
-  po::options_description description("General Usage\n"
-                                      "  ndnsec export [-h] [-o output] [-P passphrase] identity \n"
-                                      "General options");
+  BOOST_SCOPE_EXIT(&password) {
+    OPENSSL_cleanse(&password.front(), password.size());
+  } BOOST_SCOPE_EXIT_END
+
+  po::options_description description(
+    "Usage: ndnsec export [-h] [-o FILE] [-P PASSPHRASE] [-i] IDENTITY\n"
+    "\n"
+    "Options");
   description.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<Name>(&identityName), "Identity to export")
-    ("password,P", po::value<std::string>(&exportPassword), "Passphrase (will prompt if empty or not specified)")
+    ("help,h", "produce help message")
+    ("identity,i", po::value<Name>(&identityName), "name of the identity to export")
+    ("output,o",   po::value<std::string>(&output)->default_value("-"),
+                   "output file, '-' for stdout (the default)")
+    ("password,P", po::value<std::string>(&password),
+                   "passphrase, will prompt if empty or not specified")
     ;
 
   po::positional_options_description p;
@@ -53,58 +64,46 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("identity") == 0) {
-    std::cerr << "ERROR: identity must be specified" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: you must specify an identity" << std::endl;
+    return 2;
   }
 
-  if (vm.count("output") == 0)
-    output = "-";
+  security::v2::KeyChain keyChain;
 
-  try {
-    if (exportPassword.empty()) {
-      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;
-        }
+  auto id = keyChain.getPib().getIdentity(identityName);
+
+  if (password.empty()) {
+    int count = 3;
+    while (!getPassword(password, "Passphrase for the private key: ")) {
+      count--;
+      if (count <= 0) {
+        std::cerr << "ERROR: invalid password" << std::endl;
+        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(*safeBag, std::cout);
-    else
-      io::save(*safeBag, 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;
-  }
+
+  // TODO: export all certificates, selected key pair, selected certificate
+  auto safeBag = keyChain.exportSafeBag(id.getDefaultKey().getDefaultCertificate(),
+                                        password.data(), password.size());
+
+  if (output == "-")
+    io::save(*safeBag, std::cout);
+  else
+    io::save(*safeBag, output);
+
+  return 0;
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/get-default.cpp b/tools/ndnsec/get-default.cpp
index 0e2b499..d59cfba 100644
--- a/tools/ndnsec/get-default.cpp
+++ b/tools/ndnsec/get-default.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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).
  *
@@ -30,23 +30,23 @@
 {
   namespace po = boost::program_options;
 
-  bool isGetDefaultId = true;
-  bool isGetDefaultKey = false;
-  bool isGetDefaultCert = false;
+  bool wantDefaultKey = false;
+  bool wantDefaultCert = false;
   bool isQuiet = false;
   Name identityName;
   Name keyName;
 
-  po::options_description description("General Usage\n"
-                                      "  ndnsec get-default [-h] [-k|c] [-i identity|-K key] [-q]\n"
-                                      "General options");
+  po::options_description description(
+    "Usage: ndnsec get-default [-h] [-k|-c] [-i ID|-K KEY] [-q]\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
-    ("default_key,k", "get default key")
-    ("default_cert,c", "get default certificate")
-    ("identity,i", po::value<Name>(&identityName), "target identity")
-    ("key,K", po::value<Name>(&keyName), "target key")
-    ("quiet,q", "don't output trailing newline")
+    ("default-key,k",  po::bool_switch(&wantDefaultKey), "show default key, instead of identity")
+    ("default-cert,c", po::bool_switch(&wantDefaultCert), "show default certificate, instead of identity")
+    ("identity,i",     po::value<Name>(&identityName), "target identity")
+    ("key,K",          po::value<Name>(&keyName), "target key")
+    ("quiet,q",        po::bool_switch(&isQuiet), "do not print trailing newline")
     ;
 
   po::variables_map vm;
@@ -55,86 +55,75 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
-    ;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
-  if (vm.count("default_cert") != 0) {
-    isGetDefaultCert = true;
-    isGetDefaultId = false;
-  }
-  else if (vm.count("default_key") != 0) {
-    isGetDefaultKey = true;
-    isGetDefaultId = false;
+  if (wantDefaultKey && wantDefaultCert) {
+    std::cerr << "ERROR: cannot specify both '--default-key' and '--default-cert'" << std::endl;
+    return 2;
   }
 
-  if (vm.count("quiet") != 0) {
-    isQuiet = true;
+  if (vm.count("identity") && vm.count("key")) {
+    std::cerr << "ERROR: cannot specify both '--identity' and '--key'" << std::endl;
+    return 2;
   }
 
   security::v2::KeyChain keyChain;
 
-  if (vm.count("key") != 0) {
-    if (isGetDefaultCert) {
-      std::cout << keyChain.getPib()
-        .getIdentity(security::v2::extractIdentityFromKeyName(keyName))
-        .getKey(keyName)
-        .getDefaultCertificate().getName();
-
+  if (vm.count("key") > 0) {
+    if (wantDefaultCert) {
+      auto cert = keyChain.getPib()
+                  .getIdentity(security::v2::extractIdentityFromKeyName(keyName))
+                  .getKey(keyName)
+                  .getDefaultCertificate();
+      std::cout << cert.getName();
       if (!isQuiet) {
         std::cout << std::endl;
       }
       return 0;
     }
-    return 1;
+    return 2;
   }
-  else if (vm.count("identity") != 0) {
-    security::Key key = keyChain.getPib()
-      .getIdentity(identityName)
-      .getDefaultKey();
-
-    if (isGetDefaultKey) {
+  else if (vm.count("identity") > 0) {
+    auto key = keyChain.getPib()
+               .getIdentity(identityName)
+               .getDefaultKey();
+    if (wantDefaultKey) {
       std::cout << key.getName();
       if (!isQuiet)
         std::cout << std::endl;
       return 0;
     }
-    if (isGetDefaultCert) {
+    if (wantDefaultCert) {
       std::cout << key.getDefaultCertificate().getName();
       if (!isQuiet)
         std::cout << std::endl;
       return 0;
     }
-    return 1;
+    return 2;
   }
   else {
-    security::Identity identity = keyChain.getPib().getDefaultIdentity();
-    if (isGetDefaultId) {
-      std::cout << identity.getName();
-      if (!isQuiet)
-        std::cout << std::endl;
-      return 0;
-    }
-    if (isGetDefaultKey) {
+    auto identity = keyChain.getPib()
+                    .getDefaultIdentity();
+    if (wantDefaultKey) {
       std::cout << identity.getDefaultKey().getName();
-      if (!isQuiet)
-        std::cout << std::endl;
-      return 0;
     }
-    if (isGetDefaultCert) {
+    else if (wantDefaultCert) {
       std::cout << identity.getDefaultKey().getDefaultCertificate().getName();
-      if (!isQuiet)
-        std::cout << std::endl;
-      return 0;
     }
-    return 1;
+    else {
+      std::cout << identity.getName();
+    }
+    if (!isQuiet)
+      std::cout << std::endl;
+    return 0;
   }
 }
 
diff --git a/tools/ndnsec/import.cpp b/tools/ndnsec/import.cpp
index b0735e3..f59ce93 100644
--- a/tools/ndnsec/import.cpp
+++ b/tools/ndnsec/import.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,6 +22,10 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
+#include "ndn-cxx/security/impl/openssl.hpp"
+
+#include <boost/scope_exit.hpp>
+
 namespace ndn {
 namespace ndnsec {
 
@@ -30,16 +34,23 @@
 {
   namespace po = boost::program_options;
 
-  std::string input("-");
-  std::string importPassword;
+  std::string input;
+  std::string password;
 
-  po::options_description description("General Usage\n"
-                                      "  ndnsec import [-h] [-P passphrase] input \n"
-                                      "General options");
+  BOOST_SCOPE_EXIT(&password) {
+    OPENSSL_cleanse(&password.front(), password.size());
+  } BOOST_SCOPE_EXIT_END
+
+  po::options_description description(
+    "Usage: ndnsec import [-h] [-P PASSPHRASE] [-i] FILE\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
-    ("input,i", po::value<std::string>(&input), "input source, stdin if -")
-    ("password,P", po::value<std::string>(&importPassword), "Passphrase (will prompt if empty or not specified)")
+    ("input,i",    po::value<std::string>(&input)->default_value("-"),
+                   "input file, '-' for stdin (the default)")
+    ("password,P", po::value<std::string>(&password),
+                   "passphrase, will prompt if empty or not specified")
     ;
 
   po::positional_options_description p;
@@ -51,46 +62,38 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
-  try {
-    security::v2::KeyChain keyChain;
+  security::v2::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::SafeBag> safeBag;
+  if (input == "-")
+    safeBag = io::load<security::SafeBag>(std::cin);
+  else
+    safeBag = io::load<security::SafeBag>(input);
 
-    if (importPassword.empty()) {
-      int count = 3;
-      while (!getPassword(importPassword, "Passphrase for the private key: ", false)) {
-        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;
-        }
+  if (password.empty()) {
+    int count = 3;
+    while (!getPassword(password, "Passphrase for the private key: ", false)) {
+      count--;
+      if (count <= 0) {
+        std::cerr << "ERROR: invalid password" << std::endl;
+        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;
-  }
+  keyChain.importSafeBag(*safeBag, password.data(), password.size());
+
+  return 0;
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/key-gen.cpp b/tools/ndnsec/key-gen.cpp
index 7e50a11..6d4e397 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-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).
  *
@@ -28,37 +28,28 @@
 int
 ndnsec_key_gen(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
   Name identityName;
-  bool isDefault = true;
-  bool isUserSpecified = false;
-  char keyType = 'r';
-  char keyIdTypeChoice = 'r';
-  std::string specifiedKeyId;
-  Name::Component specifiedKeyIdComponent;
-  std::string outputFilename;
-  KeyIdType keyIdType = KeyIdType::RANDOM;
+  bool wantNotDefault = false;
+  char keyTypeChoice;
+  char keyIdTypeChoice;
+  std::string userKeyId;
 
-  po::options_description description("General Usage\n"
-                                      "  ndnsec key-gen [-h] [-n] identity\n"
-                                      "General options");
+  po::options_description description(
+    "Usage: ndnsec key-gen [-h] [-n] [-t TYPE] [-k IDTYPE] [-i] IDENTITY\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
-    ("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")
-    ("type,t", po::value<char>(&keyType),
-     "optional, key type, r for RSA key (default), e for EC key")
-    ("key_id_type,k", po::value<char>(&keyIdTypeChoice),
-     "optional, key id type, r for 64-bit random number (default), h for SHA256 of the public key")
-    ("key_id", po::value<std::string>(&specifiedKeyId),
-     "optional, user-specified key id, cannot be used with key_id_type")
-    // ("size,s", po::value<int>(&keySize)->default_value(2048),
-    // "optional, key size, 2048 (default)")
+    ("identity,i",    po::value<Name>(&identityName), "identity name, e.g., /ndn/edu/ucla/alice")
+    ("not-default,n", po::bool_switch(&wantNotDefault), "do not set the identity as default")
+    ("type,t",        po::value<char>(&keyTypeChoice)->default_value('r'),
+                      "key type, 'r' for RSA, 'e' for ECDSA")
+    ("keyid-type,k",  po::value<char>(&keyIdTypeChoice)->default_value('r'),
+                      "key id type, 'r' for 64-bit random number, 'h' for SHA256 of the public key")
+    ("keyid",         po::value<std::string>(&userKeyId), "user-specified key id")
+    //("size,s",        po::value<int>(&keySize)->default_value(2048), "key size in bits")
     ;
 
   po::positional_options_description p;
@@ -70,101 +61,100 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("identity") == 0) {
-    std::cerr << "identity must be specified\n" << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: you must specify an identity" << std::endl;
+    return 2;
   }
 
-  if (vm.count("not_default") != 0) {
-    isDefault = false;
-  }
+  KeyIdType keyIdType = KeyIdType::RANDOM;
+  Name::Component userKeyIdComponent;
 
-  if (vm.count("key_id_type") != 0) {
-    if (keyIdTypeChoice == 'r') {
-      // KeyIdType has already been set to KeyIdType::RANDOM
+  if (vm.count("keyid") > 0) {
+    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;
     }
-    else if (keyIdTypeChoice == 'h') {
+    if (!userKeyIdComponent.isGeneric()) {
+      std::cerr << "ERROR: key id must be a GenericNameComponent" << std::endl;
+      return 2;
+    }
+  }
+
+  if (vm.count("keyid-type") > 0) {
+    if (keyIdType == KeyIdType::USER_SPECIFIED) {
+      std::cerr << "ERROR: cannot specify both '--keyid' and '--keyid-type'" << std::endl;
+      return 2;
+    }
+
+    switch (keyIdTypeChoice) {
+    case 'r':
+      // KeyIdType::RANDOM is the default
+      break;
+    case 'h':
       keyIdType = KeyIdType::SHA256;
+      break;
+    default:
+      std::cerr << "ERROR: unrecognized key id type '" << keyIdTypeChoice << "'" << std::endl;
+      return 2;
+    }
+  }
+
+  unique_ptr<KeyParams> params;
+  switch (keyTypeChoice) {
+  case 'r':
+    if (keyIdType == KeyIdType::USER_SPECIFIED) {
+      params = make_unique<RsaKeyParams>(userKeyIdComponent);
     }
     else {
-      std::cerr << "Unrecognized key id type\n" << description << std::endl;
-      return 1;
+      params = make_unique<RsaKeyParams>(detail::RsaKeyParamsInfo::getDefaultSize(), keyIdType);
     }
-    if (vm.count("key_id") != 0) {
-      std::cerr << "key_id cannot be used with key_id_type\n" << description << std::endl;
-      return 1;
+    break;
+  case 'e':
+    if (keyIdType == KeyIdType::USER_SPECIFIED) {
+      params = make_unique<EcKeyParams>(userKeyIdComponent);
     }
+    else {
+      params = make_unique<EcKeyParams>(detail::EcKeyParamsInfo::getDefaultSize(), keyIdType);
+    }
+    break;
+  default:
+    std::cerr << "ERROR: unrecognized key type '" << keyTypeChoice << "'" << std::endl;
+    return 2;
   }
 
-  if (vm.count("key_id") != 0) {
-    isUserSpecified = true;
-    specifiedKeyIdComponent = name::Component::fromEscapedString(specifiedKeyId);
-    if (specifiedKeyIdComponent.empty()) {
-      std::cerr << "Key id cannot be an empty name component\n" << description << std::endl;
-      return 1;
-    }
-    if (!specifiedKeyIdComponent.isGeneric()) {
-      std::cerr << "Key id must be a generic name component\n" << description << std::endl;
-      return 1;
-    }
-  }
+  security::v2::KeyChain keyChain;
 
+  security::Identity identity;
+  security::Key key;
   try {
-    unique_ptr<KeyParams> params;
-    if (keyType == 'r') {
-      if (isUserSpecified) {
-        params = make_unique<RsaKeyParams>(specifiedKeyIdComponent);
-      }
-      else {
-        params = make_unique<RsaKeyParams>(detail::RsaKeyParamsInfo::getDefaultSize(), keyIdType);
-      }
-    }
-    else if (keyType == 'e') {
-      if (isUserSpecified) {
-        params = make_unique<EcKeyParams>(specifiedKeyIdComponent);
-      }
-      else {
-        params = make_unique<EcKeyParams>(detail::EcKeyParamsInfo::getDefaultSize(), keyIdType);
-      }
-    }
-    else {
-      std::cerr << "Unrecognized key type\n" << description << std::endl;
-      return 1;
-    }
-
-    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();
-    }
-
-    if (isDefault) {
-      keyChain.setDefaultKey(identity, key);
-      keyChain.setDefaultIdentity(identity);
-    }
-
-    io::save(key.getDefaultCertificate(), std::cout);
+    identity = keyChain.getPib().getIdentity(identityName);
+    key = keyChain.createKey(identity, *params);
   }
-  catch (const std::exception& e) {
-    std::cerr << "Error: " << e.what() << std::endl;
+  catch (const security::Pib::Error&) {
+    // identity doesn't exist, so create it and generate key
+    identity = keyChain.createIdentity(identityName, *params);
+    key = identity.getDefaultKey();
   }
+
+  if (!wantNotDefault) {
+    keyChain.setDefaultKey(identity, key);
+    keyChain.setDefaultIdentity(identity);
+  }
+
+  io::save(key.getDefaultCertificate(), std::cout);
+
   return 0;
 }
 
diff --git a/tools/ndnsec/list.cpp b/tools/ndnsec/list.cpp
index ec38f6e..1aa2d4e 100644
--- a/tools/ndnsec/list.cpp
+++ b/tools/ndnsec/list.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).
  *
@@ -30,13 +30,14 @@
 class Printer
 {
 public:
+  explicit
   Printer(int verboseLevel)
     : m_verboseLevel(verboseLevel)
   {
   }
 
   void
-  printIdentity(const security::Identity& identity, bool isDefault)
+  printIdentity(const security::Identity& identity, bool isDefault) const
   {
     if (isDefault)
       std::cout << "* ";
@@ -63,7 +64,7 @@
   }
 
   void
-  printKey(const security::Key& key, bool isDefault)
+  printKey(const security::Key& key, bool isDefault) const
   {
     if (isDefault)
       std::cout << "  +->* ";
@@ -88,7 +89,7 @@
   }
 
   void
-  printCertificate(const security::v2::Certificate& cert, bool isDefault)
+  printCertificate(const security::v2::Certificate& cert, bool isDefault) const
   {
     if (isDefault)
       std::cout << "       +->* ";
@@ -110,52 +111,49 @@
 int
 ndnsec_list(int argc, char** argv)
 {
-  using namespace ndn;
   namespace po = boost::program_options;
 
+  bool wantKey = false;
+  bool wantCert = false;
   int verboseLevel = 0; // 0 print identity only
                         // 1 print key name
                         // 2 print cert name
                         // 3 print cert content
 
-  po::options_description options("General Usage\n  ndnsec list [-h] [-k|c]\nGeneral options");
-  options.add_options()
-    ("help,h",    "produce help message")
-    ("key,k",     "granularity: key")
-    ("cert,c",    "granularity: certificate")
+  po::options_description description(
+    "Usage: ndnsec list [-h] [-k] [-c] [-v]\n"
+    "\n"
+    "Options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("key,k",     po::bool_switch(&wantKey), "list all keys associated with each identity")
+    ("cert,c",    po::bool_switch(&wantCert), "list all certificates associated with each key")
     ("verbose,v", accumulator<int>(&verboseLevel),
-                  "verbose mode: -v is equivalent to -k, -vv is equivalent to -c")
+                  "verbose mode, can be repeated for increased verbosity: -v is equivalent to -k, "
+                  "-vv is equivalent to -c, -vvv shows detailed information for each certificate")
     ;
 
   po::variables_map vm;
   try {
-    po::store(po::parse_command_line(argc, argv, options), vm);
+    po::store(po::parse_command_line(argc, argv, description), vm);
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << options << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << options << std::endl;
-    ;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
-  int tmpVerboseLevel = 0;
-  if (vm.count("cert") != 0)
-    tmpVerboseLevel = 2;
-  else if (vm.count("key") != 0)
-    tmpVerboseLevel = 1;
-
-  verboseLevel = std::max(verboseLevel, tmpVerboseLevel);
+  verboseLevel = std::max(verboseLevel, wantCert ? 2 : wantKey ? 1 : 0);
 
   security::v2::KeyChain keyChain;
-  Printer printer(verboseLevel);
 
-  // TODO add API to check for default identity (may be from the identity itself)
+  // TODO: add API to check for default identity (may be from the identity itself)
   security::Identity defaultIdentity;
   try {
     defaultIdentity = keyChain.getPib().getDefaultIdentity();
@@ -163,6 +161,8 @@
   catch (const security::Pib::Error&) {
     // no default identity
   }
+
+  Printer printer(verboseLevel);
   for (const auto& identity : keyChain.getPib().getIdentities()) {
     printer.printIdentity(identity, identity == defaultIdentity);
   }
diff --git a/tools/ndnsec/set-default.cpp b/tools/ndnsec/set-default.cpp
index d39abdb..d1647ed 100644
--- a/tools/ndnsec/set-default.cpp
+++ b/tools/ndnsec/set-default.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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).
  *
@@ -30,70 +30,69 @@
 {
   namespace po = boost::program_options;
 
-  std::string certFileName;
-  bool isSetDefaultId = true;
-  bool isSetDefaultKey = false;
-  bool isSetDefaultCert = false;
   Name name;
+  bool wantSetDefaultKey = false;
+  bool wantSetDefaultCert = false;
 
-  po::options_description description("General Usage\n  ndnsec set-default [-h] [-k|c] name\nGeneral options");
+  po::options_description description(
+    "Usage: ndnsec set-default [-h] [-k|-c] [-n] NAME\n"
+    "\n"
+    "Options");
   description.add_options()
     ("help,h", "produce help message")
-    ("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")
+    ("name,n",         po::value<Name>(&name), "the identity/key/certificate name to set")
+    ("default-key,k",  po::bool_switch(&wantSetDefaultKey), "set default key of the identity")
+    ("default-cert,c", po::bool_switch(&wantSetDefaultCert), "set default certificate of the key")
     ;
 
   po::positional_options_description p;
   p.add("name", 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;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("name") == 0) {
-    std::cerr << "ERROR: name is required!" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: you must specify a name" << std::endl;
+    return 2;
   }
 
-  isSetDefaultId = !isSetDefaultKey && !isSetDefaultCert;
+  if (wantSetDefaultKey && wantSetDefaultCert) {
+    std::cerr << "ERROR: cannot specify both '--default-key' and '--default-cert'" << std::endl;
+    return 2;
+  }
 
   security::v2::KeyChain keyChain;
 
-  if (isSetDefaultId) {
-    security::Identity identity = keyChain.getPib().getIdentity(name);
-    keyChain.setDefaultIdentity(identity);
-    return 0;
-  }
-
-  if (isSetDefaultKey) {
-    security::Identity identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
-    security::Key key = identity.getKey(name);
+  if (wantSetDefaultKey) {
+    auto identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
+    auto key = identity.getKey(name);
     keyChain.setDefaultKey(identity, key);
-    return 0;
   }
-
-  if (isSetDefaultCert) {
-    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);
+  else if (wantSetDefaultCert) {
+    auto identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromCertName(name));
+    auto key = identity.getKey(security::v2::extractKeyNameFromCertName(name));
+    auto cert = key.getCertificate(name);
     keyChain.setDefaultCertificate(key, cert);
-    return 0;
+  }
+  else {
+    auto identity = keyChain.getPib().getIdentity(name);
+    keyChain.setDefaultIdentity(identity);
   }
 
-  return 1;
+  return 0;
 }
 
 } // namespace ndnsec
diff --git a/tools/ndnsec/sign-req.cpp b/tools/ndnsec/sign-req.cpp
index 6bfbb2a..d8d7486 100644
--- a/tools/ndnsec/sign-req.cpp
+++ b/tools/ndnsec/sign-req.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).
  *
@@ -34,13 +34,14 @@
   bool isKeyName = false;
 
   po::options_description description(
-    "General Usage\n  ndnsec sign-req [-h] [-k] name\nGeneral options");
-  description
-    .add_options()
+    "Usage: ndnsec sign-req [-h] [-k] [-n] NAME\n"
+    "\n"
+    "Options");
+  description.add_options()
     ("help,h", "produce help message")
-    ("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");
+    ("name,n", po::value<Name>(&name), "identity or key name, e.g., /ndn/edu/ucla/alice")
+    ("key,k",  po::bool_switch(&isKeyName), "the specified name is a key name rather than an identity")
+    ;
 
   po::positional_options_description p;
   p.add("name", 1);
@@ -51,24 +52,19 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
   if (vm.count("name") == 0) {
-    std::cerr << "ERROR: name must be specified" << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
-  }
-
-  if (vm.count("key") != 0) {
-    isKeyName = true;
+    std::cerr << "ERROR: you must specify a name" << std::endl;
+    return 2;
   }
 
   security::v2::KeyChain keyChain;
@@ -109,6 +105,7 @@
   keyChain.sign(certificate, security::SigningInfo(key).setSignatureInfo(signatureInfo));
 
   io::save(certificate, std::cout);
+
   return 0;
 }
 
diff --git a/tools/ndnsec/unlock-tpm.cpp b/tools/ndnsec/unlock-tpm.cpp
index 0d70acc..d79db7f 100644
--- a/tools/ndnsec/unlock-tpm.cpp
+++ b/tools/ndnsec/unlock-tpm.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 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,45 +22,55 @@
 #include "ndnsec.hpp"
 #include "util.hpp"
 
+#include "ndn-cxx/security/impl/openssl.hpp"
+
+#include <cerrno>
+#include <cstring>
+#include <unistd.h>
+
 namespace ndn {
 namespace ndnsec {
 
 int
 ndnsec_unlock_tpm(int argc, char** argv)
 {
-#ifdef NDN_CXX_HAVE_GETPASS
   namespace po = boost::program_options;
 
-  std::string keyName;
-
-  po::options_description description("General Usage\n  ndnsec unlock-tpm [-h] \nGeneral options");
-  description.add_options()("help,h", "produce help message");
+  po::options_description description(
+    "Usage: ndnsec unlock-tpm [-h]\n"
+    "\n"
+    "Options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ;
 
   po::variables_map vm;
-
   try {
     po::store(po::parse_command_line(argc, argv, description), vm);
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    std::cerr << description << std::endl;
-    return 1;
+    std::cerr << "ERROR: " << e.what() << "\n\n"
+              << description << std::endl;
+    return 2;
   }
 
-  if (vm.count("help") != 0) {
-    std::cerr << description << std::endl;
+  if (vm.count("help") > 0) {
+    std::cout << description << std::endl;
     return 0;
   }
 
-  bool isUnlocked = false;
-
+#ifdef NDN_CXX_HAVE_GETPASS
   security::v2::KeyChain keyChain;
 
-  char* password;
-  password = getpass("Password to unlock the TPM: ");
-  isUnlocked = keyChain.getTpm().unlockTpm(password, strlen(password));
-  memset(password, 0, strlen(password));
+  char* password = ::getpass("Password to unlock the TPM: ");
+  if (password == nullptr) {
+    std::cerr << "ERROR: getpass() failed: " << std::strerror(errno) << std::endl;
+    return 1;
+  }
+
+  bool isUnlocked = keyChain.getTpm().unlockTpm(password, std::strlen(password));
+  OPENSSL_cleanse(password, std::strlen(password));
 
   if (isUnlocked) {
     std::cerr << "OK: TPM is unlocked" << std::endl;
diff --git a/tools/ndnsec/util.hpp b/tools/ndnsec/util.hpp
index 8ea6976..90c3284 100644
--- a/tools/ndnsec/util.hpp
+++ b/tools/ndnsec/util.hpp
@@ -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,9 +22,7 @@
 #ifndef NDN_TOOLS_NDNSEC_UTIL_HPP
 #define NDN_TOOLS_NDNSEC_UTIL_HPP
 
-#include "ndn-cxx/encoding/buffer-stream.hpp"
 #include "ndn-cxx/security/key-chain.hpp"
-#include "ndn-cxx/security/transform.hpp"
 #include "ndn-cxx/security/v2/additional-description.hpp"
 #include "ndn-cxx/util/io.hpp"
 
@@ -32,8 +30,6 @@
 #include <iostream>
 #include <string>
 
-#include <boost/asio.hpp>
-#include <boost/exception/all.hpp>
 #include <boost/program_options/options_description.hpp>
 #include <boost/program_options/parsers.hpp>
 #include <boost/program_options/variables_map.hpp>
diff --git a/wscript b/wscript
index 85e35fc..9da459b 100644
--- a/wscript
+++ b/wscript
@@ -297,9 +297,10 @@
             builder='man',
             config='docs/conf.py',
             outdir='docs/manpages',
-            source=bld.path.ant_glob('docs/manpages/**/*.rst'),
+            source=bld.path.ant_glob('docs/manpages/*.rst'),
             install_path='${MANDIR}',
-            VERSION=VERSION)
+            version=VERSION_BASE,
+            release=VERSION)
 
 def docs(bld):
     from waflib import Options
@@ -337,7 +338,8 @@
         config='docs/conf.py',
         outdir='docs',
         source=bld.path.ant_glob('docs/**/*.rst'),
-        VERSION=VERSION)
+        version=VERSION_BASE,
+        release=VERSION)
 
 def version(ctx):
     # don't execute more than once