tools: Allow specifying passphrase for ndnsec import/export in command line

Change-Id: Ic389249e017df27b0246cdd1fcd3a1431607246b
Refs: #4633
diff --git a/docs/manpages/ndnsec-export.rst b/docs/manpages/ndnsec-export.rst
index fb3c41f..dc94939 100644
--- a/docs/manpages/ndnsec-export.rst
+++ b/docs/manpages/ndnsec-export.rst
@@ -24,6 +24,12 @@
 ``-o output``
   Write to an 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.
+
 ``identity``
   The identity name.
 
diff --git a/docs/manpages/ndnsec-import.rst b/docs/manpages/ndnsec-import.rst
index fbc8bc9..c81964a 100644
--- a/docs/manpages/ndnsec-import.rst
+++ b/docs/manpages/ndnsec-import.rst
@@ -20,6 +20,12 @@
 ``-h``
   Print a help message.
 
+``-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.
+
 ``input``
   Read from an input file. Specify ``-`` to read from the standard input.
 
diff --git a/tools/ndnsec/export.cpp b/tools/ndnsec/export.cpp
index 19ff0d4..a345d44 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-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,11 +34,14 @@
   std::string output;
   std::string exportPassword;
 
-  po::options_description description("General Usage\n  ndnsec export [-h] [-o output] identity \nGeneral options");
+  po::options_description description("General Usage\n"
+                                      "  ndnsec export [-h] [-o output] [-P passphrase] identity \n"
+                                      "General 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)")
     ;
 
   po::positional_options_description p;
@@ -70,13 +73,15 @@
     output = "-";
 
   try {
-    int count = 3;
-    while (!getPassword(exportPassword, "Passphrase for the private key: ")) {
-      count--;
-      if (count <= 0) {
-        std::cerr << "ERROR: invalid password" << std::endl;
-        memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
-        return 1;
+    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;
+        }
       }
     }
 
diff --git a/tools/ndnsec/import.cpp b/tools/ndnsec/import.cpp
index a818a3a..b0735e3 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-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -33,10 +33,13 @@
   std::string input("-");
   std::string importPassword;
 
-  po::options_description description("General Usage\n  ndnsec import [-h] input \nGeneral options");
+  po::options_description description("General Usage\n"
+                                      "  ndnsec import [-h] [-P passphrase] input \n"
+                                      "General 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)")
     ;
 
   po::positional_options_description p;
@@ -67,15 +70,18 @@
     else
       safeBag = io::load<security::SafeBag>(input);
 
-    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 (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;
+        }
       }
     }
+
     keyChain.importSafeBag(*safeBag, importPassword.c_str(), importPassword.size());
     memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
     return 0;