ndnsec: improve error reporting when loading a Certificate or SafeBag fails
Refs: #5164
Change-Id: I6f594a921bb063ad808f311d8ff978bf0f7d528d
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 5a388d7..9f86f1c 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.cpp
@@ -22,8 +22,6 @@
#include "ndnsec.hpp"
#include "util.hpp"
-#include "ndn-cxx/util/io.hpp"
-
#include <boost/asio/ip/tcp.hpp>
#if BOOST_VERSION < 106700
#include <boost/date_time/posix_time/posix_time_duration.hpp>
@@ -109,13 +107,7 @@
security::Certificate certificate;
if (isFileName) {
- try {
- certificate = loadCertificate(name);
- }
- catch (const CannotLoadCertificate&) {
- std::cerr << "ERROR: Cannot load the certificate from `" << name << "`" << std::endl;
- return 1;
- }
+ certificate = loadFromFile<security::Certificate>(name);
}
else {
KeyChain keyChain;
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index 9c11ca4..8772062 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -124,14 +124,7 @@
KeyChain keyChain;
- security::Certificate certRequest;
- try {
- certRequest = loadCertificate(requestFile);
- }
- catch (const CannotLoadCertificate&) {
- std::cerr << "ERROR: Cannot load the request from `" << requestFile << "`" << std::endl;
- return 1;
- }
+ auto certRequest = loadFromFile<security::Certificate>(requestFile);
// validate that the content is a public key
Buffer keyContent = certRequest.getPublicKey();
@@ -165,9 +158,9 @@
keyChain.sign(cert, security::SigningInfo(identity).setSignatureInfo(signatureInfo));
- const Block& wire = cert.wireEncode();
{
using namespace security::transform;
+ const auto& wire = cert.wireEncode();
bufferSource(wire.wire(), wire.size()) >> base64Encode(true) >> streamSink(std::cout);
}
diff --git a/tools/ndnsec/cert-install.cpp b/tools/ndnsec/cert-install.cpp
index 7a6afa2..caa10b6 100644
--- a/tools/ndnsec/cert-install.cpp
+++ b/tools/ndnsec/cert-install.cpp
@@ -159,8 +159,8 @@
}
security::Certificate cert;
- try {
- if (certFile.find("http://") == 0) {
+ if (certFile.find("http://") == 0) {
+ try {
std::string host;
std::string port;
std::string path;
@@ -172,7 +172,6 @@
NDN_THROW(HttpException("Request line is not correctly formatted"));
size_t posPort = certFile.find(':', pos);
-
if (posPort != std::string::npos && posPort < posSlash) {
// port is specified
port = certFile.substr(posPort + 1, posSlash - posPort - 1);
@@ -187,13 +186,14 @@
cert = getCertificateHttp(host, port, path);
}
- else {
- cert = loadCertificate(certFile);
+ catch (const std::runtime_error& e) {
+ std::cerr << "ERROR: Cannot download the certificate from '" << certFile
+ << "': " << e.what() << std::endl;
+ return 1;
}
}
- catch (const CannotLoadCertificate&) {
- std::cerr << "ERROR: Cannot load the certificate from `" << certFile << "`" << std::endl;
- return 1;
+ else {
+ cert = loadFromFile<security::Certificate>(certFile);
}
KeyChain keyChain;
diff --git a/tools/ndnsec/export.cpp b/tools/ndnsec/export.cpp
index f0a9395..f11cc96 100644
--- a/tools/ndnsec/export.cpp
+++ b/tools/ndnsec/export.cpp
@@ -23,7 +23,6 @@
#include "util.hpp"
#include "ndn-cxx/security/impl/openssl.hpp"
-#include "ndn-cxx/util/io.hpp"
#include "ndn-cxx/util/scope.hpp"
namespace ndn {
diff --git a/tools/ndnsec/import.cpp b/tools/ndnsec/import.cpp
index 7e27bee..2fb6755 100644
--- a/tools/ndnsec/import.cpp
+++ b/tools/ndnsec/import.cpp
@@ -23,7 +23,6 @@
#include "util.hpp"
#include "ndn-cxx/security/impl/openssl.hpp"
-#include "ndn-cxx/util/io.hpp"
#include "ndn-cxx/util/scope.hpp"
namespace ndn {
@@ -74,11 +73,7 @@
KeyChain keyChain;
- shared_ptr<security::SafeBag> safeBag;
- if (input == "-")
- safeBag = io::load<security::SafeBag>(std::cin);
- else
- safeBag = io::load<security::SafeBag>(input);
+ auto safeBag = loadFromFile<security::SafeBag>(input);
if (password.empty()) {
int count = 3;
@@ -91,7 +86,7 @@
}
}
- keyChain.importSafeBag(*safeBag, password.data(), password.size());
+ keyChain.importSafeBag(safeBag, password.data(), password.size());
return 0;
}
diff --git a/tools/ndnsec/key-gen.cpp b/tools/ndnsec/key-gen.cpp
index 2090f74..6773e72 100644
--- a/tools/ndnsec/key-gen.cpp
+++ b/tools/ndnsec/key-gen.cpp
@@ -22,8 +22,6 @@
#include "ndnsec.hpp"
#include "util.hpp"
-#include "ndn-cxx/util/io.hpp"
-
namespace ndn {
namespace ndnsec {
diff --git a/tools/ndnsec/main.cpp b/tools/ndnsec/main.cpp
index 024e5d5..e731b5c 100644
--- a/tools/ndnsec/main.cpp
+++ b/tools/ndnsec/main.cpp
@@ -22,6 +22,7 @@
#include "ndnsec.hpp"
#include "ndn-cxx/util/logger.hpp"
+#include "ndn-cxx/util/logging.hpp"
#include "ndn-cxx/version.hpp"
#include <boost/exception/diagnostic_information.hpp>
@@ -111,6 +112,7 @@
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
NDN_LOG_ERROR(boost::diagnostic_information(e));
+ ndn::util::Logging::flush();
return 1;
}
diff --git a/tools/ndnsec/ndnsec-pch.hpp b/tools/ndnsec/ndnsec-pch.hpp
index c72b650..c059d36 100644
--- a/tools/ndnsec/ndnsec-pch.hpp
+++ b/tools/ndnsec/ndnsec-pch.hpp
@@ -24,8 +24,6 @@
#include "util.hpp"
-#include "ndn-cxx/util/io.hpp"
-
#include <boost/asio/ip/tcp.hpp>
#endif // NDN_CXX_TOOLS_NDNSEC_NDNSEC_PCH_HPP
diff --git a/tools/ndnsec/sign-req.cpp b/tools/ndnsec/sign-req.cpp
index 3548228..6151714 100644
--- a/tools/ndnsec/sign-req.cpp
+++ b/tools/ndnsec/sign-req.cpp
@@ -22,8 +22,6 @@
#include "ndnsec.hpp"
#include "util.hpp"
-#include "ndn-cxx/util/io.hpp"
-
namespace ndn {
namespace ndnsec {
diff --git a/tools/ndnsec/util.cpp b/tools/ndnsec/util.cpp
index 0ff7e74..d79df47 100644
--- a/tools/ndnsec/util.cpp
+++ b/tools/ndnsec/util.cpp
@@ -22,7 +22,6 @@
#include "util.hpp"
#include "ndn-cxx/security/impl/openssl.hpp"
-#include "ndn-cxx/util/io.hpp"
#include <unistd.h>
@@ -90,20 +89,5 @@
NDN_CXX_UNREACHABLE;
}
-security::Certificate
-loadCertificate(const std::string& fileName)
-{
- shared_ptr<security::Certificate> cert;
- if (fileName == "-")
- cert = io::load<security::Certificate>(std::cin);
- else
- cert = io::load<security::Certificate>(fileName);
-
- if (cert == nullptr) {
- NDN_THROW(CannotLoadCertificate(fileName));
- }
- return *cert;
-}
-
} // namespace ndnsec
} // namespace ndn
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);