ndnsec: improve error reporting when loading a Certificate or SafeBag fails

Refs: #5164
Change-Id: I6f594a921bb063ad808f311d8ff978bf0f7d528d
diff --git a/tools/ndnsec/util.hpp b/tools/ndnsec/util.hpp
index 4ce3c04..913198c 100644
--- a/tools/ndnsec/util.hpp
+++ b/tools/ndnsec/util.hpp
@@ -23,6 +23,7 @@
 #define NDN_CXX_TOOLS_NDNSEC_UTIL_HPP
 
 #include "ndn-cxx/security/key-chain.hpp"
+#include "ndn-cxx/util/io.hpp"
 
 #include <iostream>
 
@@ -49,17 +50,29 @@
 getCertificateFromPib(const security::pib::Pib& pib, const Name& name,
                       bool isIdentityName, bool isKeyName, bool isCertName);
 
-class CannotLoadCertificate : public std::runtime_error
+/**
+ * @brief Load a TLV-encoded, base64-armored object from a file named @p filename.
+ */
+template<typename T>
+T
+loadFromFile(const std::string& filename)
 {
-public:
-  CannotLoadCertificate(const std::string& msg)
-    : std::runtime_error(msg)
-  {
-  }
-};
+  try {
+    if (filename == "-") {
+      return io::loadTlv<T>(std::cin, io::BASE64);
+    }
 
-security::Certificate
-loadCertificate(const std::string& fileName);
+    std::ifstream file(filename);
+    if (!file) {
+      NDN_THROW(std::runtime_error("Cannot open '" + filename + "'"));
+    }
+    return io::loadTlv<T>(file, io::BASE64);
+  }
+  catch (const io::Error& e) {
+    NDN_THROW_NESTED(std::runtime_error("Cannot load '" + filename +
+                                        "': malformed TLV or not in base64 format (" + e.what() + ")"));
+  }
+}
 
 bool
 getPassword(std::string& password, const std::string& prompt, bool shouldConfirm = true);