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/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>(¬BeforeStr),
- "certificate starting date, YYYYMMDDhhmmss (default: now)")
+ "certificate validity start date/time in YYYYMMDDhhmmss format (default: now)")
("not-after,E", po::value<std::string>(¬AfterStr),
- "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>