tools: ndnsec-delete reports success or failure

Change-Id: I9b53fcc030fbca34acdf0c7dc3afc8ae8e8d523d
Refs: #2275
diff --git a/docs/manpages/ndnsec-delete.rst b/docs/manpages/ndnsec-delete.rst
index e501592..3c808af 100644
--- a/docs/manpages/ndnsec-delete.rst
+++ b/docs/manpages/ndnsec-delete.rst
@@ -18,6 +18,7 @@
 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.
 
+
 Options
 -------
 
@@ -27,6 +28,13 @@
 ``-c``
   Interpret ``name`` as a certificate name and delete the certificate.
 
+Exit Status
+-----------
+
+Normally, the exit status is 0 if the requested entity is deleted successfully.
+If the entity to be deleted does not exist, the exit status is 1.
+For other errors, the exit status is 2.
+
 Examples
 --------
 
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index 9360671..758c2f5 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -679,32 +679,12 @@
 void
 KeyChain::deleteCertificate(const Name& certificateName)
 {
-  try
-    {
-      if (m_pib->getDefaultCertificateName() == certificateName)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the certificate
-    }
-
   m_pib->deleteCertificateInfo(certificateName);
 }
 
 void
 KeyChain::deleteKey(const Name& keyName)
 {
-  try
-    {
-      if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the key
-    }
-
   m_pib->deletePublicKeyInfo(keyName);
   m_tpm->deleteKeyPairInTpm(keyName);
 }
@@ -712,25 +692,14 @@
 void
 KeyChain::deleteIdentity(const Name& identity)
 {
-  try
-    {
-      if (m_pib->getDefaultIdentity() == identity)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the identity
-    }
-
-  std::vector<Name> nameList;
-  m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
-  m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
+  std::vector<Name> keyNames;
+  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, true);
+  m_pib->getAllKeyNamesOfIdentity(identity, keyNames, false);
 
   m_pib->deleteIdentityInfo(identity);
 
-  std::vector<Name>::const_iterator it = nameList.begin();
-  for(; it != nameList.end(); it++)
-    m_tpm->deleteKeyPairInTpm(*it);
+  for (const auto& keyName : keyNames)
+    m_tpm->deleteKeyPairInTpm(keyName);
 }
 
 }
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 28de735..1973c77 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -278,10 +278,8 @@
   /**
    * @brief delete a certificate.
    *
-   * If the certificate to be deleted is current default system default,
-   * the method will not delete the certificate and return immediately.
-   *
    * @param certificateName The certificate to be deleted.
+   * @throws KeyChain::Error if certificate cannot be deleted.
    */
   void
   deleteCertificate(const Name& certificateName);
@@ -289,10 +287,8 @@
   /**
    * @brief delete a key.
    *
-   * If the key to be deleted is current default system default,
-   * the method will not delete the key and return immediately.
-   *
    * @param keyName The key to be deleted.
+   * @throws KeyChain::Error if key cannot be deleted.
    */
   void
   deleteKey(const Name& keyName);
@@ -300,10 +296,8 @@
   /**
    * @brief delete an identity.
    *
-   * If the identity to be deleted is current default system default,
-   * the method will not delete the identity and return immediately.
-   *
    * @param identity The identity to be deleted.
+   * @throws KeyChain::Error if identity cannot be deleted.
    */
   void
   deleteIdentity(const Name& identity);
diff --git a/tools/ndnsec/delete.hpp b/tools/ndnsec/delete.hpp
index 629440f..bd871bc 100644
--- a/tools/ndnsec/delete.hpp
+++ b/tools/ndnsec/delete.hpp
@@ -32,12 +32,13 @@
   using namespace ndn;
   namespace po = boost::program_options;
 
-  // bool deleteId = true;
   bool isDeleteKey = false;
   bool isDeleteCert = false;
   std::string name;
 
-  po::options_description description("General Usage\n  ndnsec delete [-h] [-k|c] name\nGeneral options");
+  po::options_description description("General Usage\n"
+                                      "ndnsec delete [-h] [-k|c] name\n"
+                                      "General options");
   description.add_options()
     ("help,h", "produce help message")
     ("delete-key,k", "(Optional) delete a key if specified.")
@@ -53,57 +54,78 @@
   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;
-    }
+  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 2;
+  }
 
-  if (vm.count("help") != 0)
-    {
-      std::cerr << description << std::endl;;
-      return 0;
-    }
+  if (vm.count("help") != 0) {
+    std::cerr << 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("name") == 0) {
+    std::cerr << "ERROR: name must be specified" << std::endl;
+    std::cerr << description << std::endl;
+    return 2;
+  }
 
   if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0)
-    {
-      isDeleteCert = true;
-      // deleteId = false;
-    }
+    isDeleteCert = true;
+
   else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0)
-    {
-      isDeleteKey = true;
-      // deleteId = false;
-    }
+    isDeleteKey = true;
 
   KeyChain keyChain;
 
-  if (isDeleteCert)
-    {
+  try {
+    if (isDeleteCert) {
+      if (!keyChain.doesCertificateExist(name)) {
+        std::cerr << "ERROR: Certificate does not exist: " << name << std::endl;
+        return 1;
+      }
+
       keyChain.deleteCertificate(name);
+      std::cerr << "OK: Delete certificate: " << name << std::endl;
     }
-  else if (isDeleteKey)
-    {
+    else if (isDeleteKey) {
+      if (!keyChain.doesPublicKeyExist(name) &&
+          !keyChain.doesKeyExistInTpm(name, KEY_CLASS_PRIVATE)) {
+        std::cerr << "ERROR: Key does not exist: " << name << std::endl;
+        return 1;
+      }
+
       keyChain.deleteKey(name);
+      std::cerr << "OK: Delete key: " << name << std::endl;
     }
-  else
-    {
+    else {
+      if (!keyChain.doesIdentityExist(name)) {
+        std::cerr << "ERROR: Identity does not exist: " << name << std::endl;
+        return 1;
+      }
+
       keyChain.deleteIdentity(name);
+      std::cerr << "OK: Delete identity: " << name << std::endl;
     }
+  }
+  catch (const SecPublicInfo::Error& e) {
+    std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
+    return 2;
+  }
+  catch (const SecTpm::Error& e) {
+    std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
+    return 2;
+  }
+  catch (const KeyChain::Error& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
 
   return 0;
 }