tools: Convert ndnsec to v2::KeyChain
This commit removes the following tools:
- cert-revoke (wasn't working properly before and need a new
design)
- set-acl (wasn't working before)
- dsk-gen (no longer makes sense with the new certificate naming
conventions, new tools for creating derivative certificates will
be created later)
This commit also fixes Bug #3644 causing import command to ask for
unnecessary password confirmation.
ndnsec main now catch all exceptions logs the extended message
Change-Id: Ib50e0994970020bcf0a1840aca6bc3942818094b
Refs: #3098, #3644
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 83c34a3..60f57b1 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.cpp
@@ -124,41 +124,50 @@
return 1;
}
- shared_ptr<security::v1::IdentityCertificate> certificate;
+ security::v2::Certificate certificate;
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
- if (isIdentityName || isKeyName || isCertName) {
- if (isIdentityName) {
- Name certName = keyChain.getDefaultCertificateNameForIdentity(name);
- certificate = keyChain.getCertificate(certName);
+ 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))
+ .getDefaultCertificate();
+ }
}
- else if (isKeyName) {
- Name certName = keyChain.getDefaultCertificateNameForKey(name);
- certificate = keyChain.getCertificate(certName);
- }
- else
- certificate = keyChain.getCertificate(name);
-
- if (certificate == nullptr) {
- std::cerr << "No certificate found!" << std::endl;
- return 1;
+ else {
+ certificate = loadCertificate(name);
}
}
- else {
- certificate = getIdentityCertificate(name);
- if (certificate == nullptr) {
- std::cerr << "No certificate read!" << std::endl;
- return 1;
- }
+ catch (const security::Pib::Error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ return 1;
+ }
+ catch (const CannotLoadCertificate&) {
+ std::cerr << "Cannot load certificate from `" << name << "`" << std::endl;
+ return 1;
}
if (isPretty) {
- std::cout << *certificate << std::endl;
+ std::cout << certificate << std::endl;
}
else {
if (isStdOut) {
- io::save(*certificate, std::cout);
+ io::save(certificate, std::cout);
return 0;
}
if (isRepoOut) {
@@ -170,8 +179,8 @@
std::cerr << "fail to open the stream!" << std::endl;
return 1;
}
- request_stream.write(reinterpret_cast<const char*>(certificate->wireEncode().wire()),
- certificate->wireEncode().size());
+ request_stream.write(reinterpret_cast<const char*>(certificate.wireEncode().wire()),
+ certificate.wireEncode().size());
return 0;
}
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index f1b2512..c1f8868 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -32,22 +32,20 @@
using boost::escaped_list_separator;
namespace po = boost::program_options;
+ namespace t = security::transform;
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
std::string notBeforeStr;
std::string notAfterStr;
- std::string subjectName;
std::string requestFile("-");
Name signId;
- std::string subjectInfo;
- std::vector<std::string> signedInfo;
- Name certPrefix = security::v1::KeyChain::DEFAULT_PREFIX; // to avoid displaying the default value
+ std::vector<std::string> infos;
+ std::string issuerId;
po::options_description description(
"General Usage\n"
- " ndnsec cert-gen [-h] [-S date] [-E date] [-N subject-name] [-I subject-info] "
- "[-s sign-id] [-p cert-prefix] request\n"
+ " ndnsec cert-gen [-h] [-S date] [-E date] [-I info] [-s sign-id] request\n"
"General options");
description.add_options()
@@ -56,22 +54,17 @@
"certificate starting date, YYYYMMDDhhmmss (default: now)")
("not-after,E", po::value<std::string>(¬AfterStr),
"certificate ending date, YYYYMMDDhhmmss (default: now + 365 days)")
- ("subject-name,N", po::value<std::string>(&subjectName),
- "subject name")
- ("subject-info,I", po::value<std::string>(&subjectInfo),
- "(deprecated, uses 'signed-info') subject info, pairs of OID and string "
- " description: \"2.5.4.10 'University of California, Los Angeles'\"")
- ("signed-info", po::value<std::vector<std::string> >(&signedInfo),
- "a pair of OID and string (must be separated by a single space), e.g., "
- "\"2.5.4.10 University of California, Los Angeles\". "
+ ("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)->default_value(keyChain.getDefaultIdentity()),
+ ("sign-id,s", po::value<Name>(&signId),
"signing identity")
- ("cert-prefix,p", po::value<Name>(&certPrefix),
- "cert prefix, which is the part of certificate name before "
- "KEY component")
("request,r", po::value<std::string>(&requestFile)->default_value("-"),
"request file name, - for stdin")
+ ("issuer-id,i", po::value<std::string>(&issuerId)->default_value("NA"),
+ "issuer's ID to be included as part of the issued certificate name")
;
po::positional_options_description p;
@@ -99,44 +92,18 @@
return 1;
}
- std::vector<security::v1::CertificateSubjectDescription> subjectDescription;
- subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName));
+ security::v2::AdditionalDescription additionalDescription;
- // 'subjectInfo' is deprecated and the following block will be removed eventually
- tokenizer<escaped_list_separator<char>> subjectInfoItems(subjectInfo,
- escaped_list_separator<char>("\\", " \t",
- "'\""));
-
- tokenizer<escaped_list_separator<char>>::iterator it = subjectInfoItems.begin();
-
- while (it != subjectInfoItems.end()) {
- std::string oid = *it;
-
- it++;
- if (it == subjectInfoItems.end()) {
- std::cerr << "ERROR: unmatched info for oid [" << oid << "]" << std::endl;
- return 1;
- }
-
- std::string value = *it;
-
- subjectDescription.push_back(security::v1::CertificateSubjectDescription(Oid(oid), value));
-
- it++;
- }
-
- // new 'signedInfo' processing
- for (std::vector<std::string>::const_iterator info = signedInfo.begin(); info != signedInfo.end();
- ++info) {
- size_t pos = info->find(" ");
+ for (const auto& info : infos) {
+ size_t pos = info.find(" ");
if (pos == std::string::npos) {
- std::cerr << "ERROR: incorrectly formatted signed info block [" << *info << "]" << std::endl;
+ std::cerr << "ERROR: incorrectly formatted info block [" << info << "]" << std::endl;
return 1;
}
- Oid oid(info->substr(0, pos));
- std::string value = info->substr(pos + 1);
+ std::string key = info.substr(0, pos);
+ std::string value = info.substr(pos + 1);
- subjectDescription.push_back(security::v1::CertificateSubjectDescription(oid, value));
+ additionalDescription.set(key, value);
}
time::system_clock::TimePoint notBefore;
@@ -170,39 +137,52 @@
return 1;
}
- shared_ptr<security::v1::IdentityCertificate> selfSignedCertificate = getIdentityCertificate(requestFile);
+ security::v2::Certificate certRequest = loadCertificate(requestFile);
- if (selfSignedCertificate == nullptr) {
- std::cerr << "ERROR: input error" << std::endl;
+ // validate that the content is a public key
+ try {
+ Buffer keyContent = certRequest.getPublicKey();
+ t::PublicKey pubKey;
+ pubKey.loadPkcs8(keyContent.buf(), keyContent.size());
+ }
+ catch (const std::exception& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
- Name keyName = selfSignedCertificate->getPublicKeyName();
+ security::v2::Certificate cert;
- shared_ptr<security::v1::IdentityCertificate> certificate =
- keyChain.prepareUnsignedIdentityCertificate(keyName, selfSignedCertificate->getPublicKeyInfo(),
- signId, notBefore, notAfter, subjectDescription,
- certPrefix);
+ Name certName = certRequest.getKeyName();
+ certName
+ .append(issuerId)
+ .appendVersion();
- if (certificate == nullptr) {
- std::cerr << "ERROR: key name is not formated correctly or does not match certificate name"
- << std::endl;
- return 1;
+ cert.setName(certName);
+ cert.setContent(certRequest.getContent());
+
+ // @TODO add ability to customize
+ cert.setFreshnessPeriod(time::hours(1));
+
+ SignatureInfo signatureInfo;
+ signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
+
+ security::Identity identity;
+ if (vm.count("sign-id") == 0) {
+ identity = keyChain.getPib().getDefaultIdentity();
+ }
+ else {
+ identity = keyChain.getPib().getIdentity(signId);
}
- keyChain.createIdentity(signId);
- Name signingCertificateName = keyChain.getDefaultCertificateNameForIdentity(signId);
- keyChain.sign(*certificate,
- security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT,
- signingCertificateName));
+ keyChain.sign(cert, security::SigningInfo(identity).setSignatureInfo(signatureInfo));
- Block wire = certificate->wireEncode();
+ Block wire = cert.wireEncode();
- namespace t = security::transform;
+
try {
t::bufferSource(wire.wire(), wire.size()) >> t::base64Encode(true) >> t::streamSink(std::cout);
}
- catch (const security::transform::Error& e) {
+ catch (const t::Error& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
diff --git a/tools/ndnsec/cert-install.cpp b/tools/ndnsec/cert-install.cpp
index 72a82bd..c506a53 100644
--- a/tools/ndnsec/cert-install.cpp
+++ b/tools/ndnsec/cert-install.cpp
@@ -35,7 +35,7 @@
}
};
-shared_ptr<security::v1::IdentityCertificate>
+security::v2::Certificate
getCertificateHttp(const std::string& host, const std::string& port, const std::string& path)
{
using namespace boost::asio::ip;
@@ -84,17 +84,12 @@
streamSource(requestStream) >> base64Decode(true) >> streamSink(os);
}
- auto identityCertificate = std::make_shared<security::v1::IdentityCertificate>();
- identityCertificate->wireDecode(ndn::Block(os.buf()));
-
- return identityCertificate;
+ return security::v2::Certificate(Block(os.buf()));
}
int
ndnsec_cert_install(int argc, char** argv)
{
- using namespace ndn;
- using namespace ndn::security;
namespace po = boost::program_options;
std::string certFileName;
@@ -149,8 +144,9 @@
isSystemDefault = false;
}
- shared_ptr<security::v1::IdentityCertificate> cert;
+ security::v2::Certificate cert;
+ try {
if (certFileName.find("http://") == 0) {
std::string host;
std::string port;
@@ -179,32 +175,42 @@
cert = getCertificateHttp(host, port, path);
}
else {
- cert = getIdentityCertificate(certFileName);
+ cert = loadCertificate(certFileName);
+ }
+ }
+ catch (const CannotLoadCertificate&) {
+ std::cerr << "ERROR: Cannot load the certificate " << certFileName << std::endl;
+ return 1;
}
- if (cert == nullptr)
- 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;
+ }
- security::v1::KeyChain keyChain;
+ keyChain.addCertificate(key, cert);
if (isSystemDefault) {
- keyChain.addCertificateAsIdentityDefault(*cert);
- Name keyName = cert->getPublicKeyName();
- Name identity = keyName.getSubName(0, keyName.size() - 1);
- keyChain.setDefaultIdentity(identity);
+ keyChain.setDefaultIdentity(id);
+ keyChain.setDefaultKey(id, key);
+ keyChain.setDefaultCertificate(key, cert);
}
else if (isIdentityDefault) {
- keyChain.addCertificateAsIdentityDefault(*cert);
+ keyChain.setDefaultKey(id, key);
+ keyChain.setDefaultCertificate(key, cert);
}
else if (isKeyDefault) {
- keyChain.addCertificateAsKeyDefault(*cert);
- }
- else {
- keyChain.addCertificate(*cert);
+ keyChain.setDefaultCertificate(key, cert);
}
- std::cerr << "OK: certificate with name [" << cert->getName().toUri()
- << "] has been successfully installed" << std::endl;
+ std::cerr << "OK: certificate with name [" << cert.getName().toUri() << "] "
+ << "has been successfully installed" << std::endl;
return 0;
}
diff --git a/tools/ndnsec/cert-revoke.cpp b/tools/ndnsec/cert-revoke.cpp
deleted file mode 100644
index f7de148..0000000
--- a/tools/ndnsec/cert-revoke.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_cert_revoke(int argc, char** argv)
-{
- using namespace ndn;
- using namespace ndn::security;
- namespace po = boost::program_options;
-
- security::v1::KeyChain keyChain;
-
- std::string requestFile("-");
- Name signId = keyChain.getDefaultIdentity();
- bool hasSignId = false;
- Name certPrefix = security::v1::KeyChain::DEFAULT_PREFIX;
-
- po::options_description description("General Usage\n ndnsec cert-revoke [-h] request\n"
- "General options");
- description.add_options()
- ("help,h", "produce help message")
- ("sign-id,s", po::value<Name>(&signId),
- "signing identity (default: use the same as in the revoked certificate)")
- ("cert-prefix,p", po::value<Name>(&certPrefix),
- "cert prefix, which is the part of certificate name before "
- "KEY component (default: use the same as in the revoked certificate)")
- ("request,r", po::value<std::string>(&requestFile)->default_value("-"),
- "request file name, - for stdin")
- ;
-
- po::positional_options_description p;
- p.add("request", 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;
- return 1;
- }
-
- if (vm.count("help") != 0) {
- std::cerr << description << std::endl;
- return 0;
- }
-
- hasSignId = (vm.count("sign-id") != 0);
-
- if (vm.count("request") == 0) {
- std::cerr << "request file must be specified" << std::endl;
- return 1;
- }
-
- shared_ptr<security::v1::IdentityCertificate> revokedCertificate = getIdentityCertificate(requestFile);
-
- if (revokedCertificate == nullptr) {
- std::cerr << "ERROR: input error" << std::endl;
- return 1;
- }
-
- Block wire;
-
- try {
- Name keyName;
-
- if (hasSignId) {
- keyName = keyChain.getDefaultKeyNameForIdentity(signId);
- }
- else {
- const Signature& signature = revokedCertificate->getSignature();
- if (!signature.hasKeyLocator() ||
- signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name) {
- std::cerr << "ERROR: Invalid certificate to revoke" << std::endl;
- return 1;
- }
-
- keyName = security::v1::IdentityCertificate::certificateNameToPublicKeyName(signature.getKeyLocator().getName());
- }
-
- Name certName;
- if (certPrefix == security::v1::KeyChain::DEFAULT_PREFIX) {
- certName = revokedCertificate->getName().getPrefix(-1);
- }
- else {
- Name revokedKeyName = revokedCertificate->getPublicKeyName();
-
- if (certPrefix.isPrefixOf(revokedKeyName) && certPrefix != revokedKeyName) {
- certName.append(certPrefix)
- .append("KEY")
- .append(revokedKeyName.getSubName(certPrefix.size()))
- .append("ID-CERT");
- }
- else {
- std::cerr << "ERROR: certificate prefix does not match the revoked certificate" << std::endl;
- return 1;
- }
- }
- certName.appendVersion().append("REVOKED");
-
- Data revocationCert;
- revocationCert.setName(certName);
-
- if (keyChain.doesPublicKeyExist(keyName)) {
- Name signingCertificateName = keyChain.getDefaultCertificateNameForKey(keyName);
- keyChain.sign(revocationCert,
- SigningInfo(SigningInfo::SIGNER_TYPE_CERT, signingCertificateName));
- }
- else {
- std::cerr << "ERROR: Cannot find the signing key!" << std::endl;
- return 1;
- }
-
- wire = revocationCert.wireEncode();
- }
- catch (const Signature::Error& e) {
- std::cerr << "ERROR: No valid signature!" << std::endl;
- return 1;
- }
- catch (const KeyLocator::Error& e) {
- std::cerr << "ERROR: No valid KeyLocator!" << std::endl;
- return 1;
- }
- catch (const security::v1::IdentityCertificate::Error& e) {
- std::cerr << "ERROR: Cannot determine the signing key!" << std::endl;
- return 1;
- }
- catch (const security::v1::SecPublicInfo::Error& e) {
- std::cerr << "ERROR: Incomplete or corrupted PIB (" << e.what() << ")" << std::endl;
- return 1;
- }
-
- try {
- transform::bufferSource(wire.wire(), wire.size()) >> transform::base64Encode(true) >>
- transform::streamSink(std::cout);
- }
- catch (const transform::Error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- return 1;
- }
-
- return 0;
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/delete.cpp b/tools/ndnsec/delete.cpp
index cfda520..8c08cf0 100644
--- a/tools/ndnsec/delete.cpp
+++ b/tools/ndnsec/delete.cpp
@@ -28,7 +28,6 @@
int
ndnsec_delete(int argc, char** argv)
{
- using namespace ndn;
namespace po = boost::program_options;
bool isDeleteKey = false;
@@ -41,9 +40,7 @@
description.add_options()
("help,h", "produce help message")
("delete-key,k", "(Optional) delete a key if specified.")
- ("delete-key2,K", "(Optional) delete a key if specified.")
("delete-cert,c", "(Optional) delete a certificate if specified.")
- ("delete-cert2,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.");
@@ -74,52 +71,45 @@
return 2;
}
- if (vm.count("delete-cert") != 0 || vm.count("delete-cert2") != 0)
+ if (vm.count("delete-cert") != 0) {
isDeleteCert = true;
-
- else if (vm.count("delete-key") != 0 || vm.count("delete-key2") != 0)
+ }
+ else if (vm.count("delete-key") != 0) {
isDeleteKey = true;
+ }
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
try {
if (isDeleteCert) {
- if (!keyChain.doesCertificateExist(name)) {
- std::cerr << "ERROR: Certificate does not exist: " << name << std::endl;
- return 1;
- }
+ security::Key key = keyChain.getPib()
+ .getIdentity(security::v2::extractIdentityFromCertName(name))
+ .getKey(security::v2::extractKeyNameFromCertName(name));
- keyChain.deleteCertificate(name);
+ keyChain.deleteCertificate(key, key.getCertificate(name).getName());
std::cerr << "OK: Delete certificate: " << name << std::endl;
}
else if (isDeleteKey) {
- if (!keyChain.doesPublicKeyExist(name) && !keyChain.doesKeyExistInTpm(name, KeyClass::PRIVATE)) {
- std::cerr << "ERROR: Key does not exist: " << name << std::endl;
- return 1;
- }
+ security::Identity identity = keyChain.getPib()
+ .getIdentity(security::v2::extractIdentityFromKeyName(name));
- keyChain.deleteKey(name);
+ keyChain.deleteKey(identity, identity.getKey(name));
std::cerr << "OK: Delete key: " << name << std::endl;
}
else {
- if (!keyChain.doesIdentityExist(name)) {
- std::cerr << "ERROR: Identity does not exist: " << name << std::endl;
- return 1;
- }
-
- keyChain.deleteIdentity(name);
+ keyChain.deleteIdentity(keyChain.getPib().getIdentity(name));
std::cerr << "OK: Delete identity: " << name << std::endl;
}
}
- catch (const security::v1::SecPublicInfo::Error& e) {
+ catch (const security::Pib::Error& e) {
std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
return 2;
}
- catch (const security::v1::SecTpm::Error& e) {
+ catch (const security::Tpm::Error& e) {
std::cerr << "ERROR: Cannot delete the item: " << e.what() << std::endl;
return 2;
}
- catch (const security::v1::KeyChain::Error& e) {
+ catch (const security::v2::KeyChain::Error& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 2;
}
diff --git a/tools/ndnsec/dsk-gen.cpp b/tools/ndnsec/dsk-gen.cpp
deleted file mode 100644
index a9109ee..0000000
--- a/tools/ndnsec/dsk-gen.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_dsk_gen(int argc, char** argv)
-{
- using namespace ndn;
- using namespace ndn::security;
- namespace po = boost::program_options;
-
- std::string identityName;
- char keyType = 'r';
-
- po::options_description description("General Usage\n"
- " ndnsec dsk-gen [-h] [-t keyType] identity\n"
- "General options");
- description.add_options()
- ("help,h", "produce help message")
- ("identity,i", po::value<std::string>(&identityName),
- "identity name, for example, /ndn/ucla.edu/alice")
- ("type,t", po::value<char>(&keyType)->default_value('r'),
- "optional, key type, r for RSA key (default), e for EC key.")
- // ("size,s", po::value<int>(&keySize)->default_value(2048),
- // "optional, key size, 2048 (default)")
- ;
-
- po::positional_options_description p;
- p.add("identity", 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;
- }
-
- if (vm.count("help") != 0) {
- std::cerr << description << std::endl;
- return 0;
- }
-
- if (vm.count("identity") == 0) {
- std::cerr << "identity must be specified" << std::endl;
- std::cerr << description << std::endl;
- return 1;
- }
-
- shared_ptr<security::v1::IdentityCertificate> kskCert;
- Name signingCertName;
-
- security::v1::KeyChain keyChain;
-
- try {
- Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
- bool isDefaultDsk = false;
- std::string keyUsageTag = defaultCertName.get(-3).toUri().substr(0, 4);
- if (keyUsageTag == "ksk-")
- isDefaultDsk = false;
- else if (keyUsageTag == "dsk-")
- isDefaultDsk = true;
- else {
- std::cerr << "ERROR: Unknown key usage tag: " << keyUsageTag << std::endl;
- return 1;
- }
-
- if (isDefaultDsk) {
- shared_ptr<security::v1::IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
-
- if (dskCert != nullptr) {
- SignatureSha256WithRsa sha256sig(dskCert->getSignature());
-
- Name keyLocatorName = sha256sig.getKeyLocator().getName();
-
- Name kskName = security::v1::IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
- Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
- signingCertName = kskCertName;
- kskCert = keyChain.getCertificate(kskCertName);
- }
- else {
- std::cerr << "ERROR: The default certificate is missing." << std::endl;
- return 1;
- }
- }
- else {
- signingCertName = defaultCertName;
- kskCert = keyChain.getCertificate(defaultCertName);
- }
-
- if (kskCert == nullptr) {
- std::cerr << "ERROR: KSK certificate is missing." << std::endl;
- return 1;
- }
-
- Name newKeyName;
- switch (keyType) {
- case 'r': {
- RsaKeyParams params;
- newKeyName = keyChain.generateRsaKeyPair(Name(identityName), false, params.getKeySize());
- if (0 == newKeyName.size()) {
- std::cerr << "ERROR: Fail to generate RSA key!" << std::endl;
- return 1;
- }
- break;
- }
- case 'e': {
- EcKeyParams params;
- newKeyName = keyChain.generateEcKeyPair(Name(identityName), false, params.getKeySize());
- if (0 == newKeyName.size()) {
- std::cerr << "ERROR: Fail to generate EC key!" << std::endl;
- return 1;
- }
- break;
- }
- default:
- std::cerr << "ERROR: Unrecongized key type"
- << "\n";
- std::cerr << description << std::endl;
- return 1;
- }
-
- Name certName = newKeyName.getPrefix(-1);
- certName.append("KEY").append(newKeyName.get(-1)).append("ID-CERT").appendVersion();
-
- shared_ptr<security::v1::IdentityCertificate> certificate =
- keyChain.prepareUnsignedIdentityCertificate(newKeyName,
- Name(identityName),
- kskCert->getNotBefore(),
- kskCert->getNotAfter(),
- kskCert->getSubjectDescriptionList());
-
- if (certificate != nullptr)
- certificate->encode();
- else {
- std::cerr << "ERROR: Cannot format the certificate of the requested dsk."
- << "\n";
- return 1;
- }
-
- keyChain.sign(*certificate,
- security::SigningInfo(security::SigningInfo::SIGNER_TYPE_CERT, signingCertName));
-
- keyChain.addCertificateAsIdentityDefault(*certificate);
-
- std::cerr << "OK: dsk certificate with name [" << certificate->getName()
- << "] has been successfully installed\n";
- return 0;
- }
- catch (const std::runtime_error& e) {
- std::cerr << "ERROR: other runtime errors: " << e.what() << "\n";
- return 1;
- }
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/export.cpp b/tools/ndnsec/export.cpp
index 9b7a0e9..4de938e 100644
--- a/tools/ndnsec/export.cpp
+++ b/tools/ndnsec/export.cpp
@@ -28,20 +28,17 @@
int
ndnsec_export(int argc, char** argv)
{
- using namespace ndn;
namespace po = boost::program_options;
- std::string identityStr;
+ Name identityName;
std::string output;
std::string exportPassword;
- bool isPrivateExport = false;
po::options_description description("General Usage\n ndnsec export [-h] [-o output] [-p] identity \nGeneral options");
description.add_options()
("help,h", "Produce help message")
("output,o", po::value<std::string>(&output), "(Optional) output file, stdout if not specified")
- ("private,p", "export info contains private key")
- ("identity,i", po::value<std::string>(&identityStr), "Identity to export")
+ ("identity,i", po::value<Name>(&identityName), "Identity to export")
;
po::positional_options_description p;
@@ -69,55 +66,39 @@
return 1;
}
- if (vm.count("private") != 0)
- isPrivateExport = true;
-
if (vm.count("output") == 0)
output = "-";
- Name identity(identityStr);
- if (!isPrivateExport) {
- security::v1::KeyChain keyChain;
- shared_ptr<security::v1::IdentityCertificate> cert =
- keyChain.getCertificate(keyChain.getDefaultCertificateNameForIdentity(identity));
+ 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;
+ }
+ }
+
+ 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(*cert, std::cout);
+ io::save(*safeBag, std::cout);
else
- io::save(*cert, output);
+ io::save(*safeBag, output);
return 0;
}
- else {
- Block wire;
- try {
- security::v1::KeyChain keyChain;
-
- 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;
- }
- }
- shared_ptr<security::v1::SecuredBag> securedBag =
- keyChain.exportIdentity(identity, exportPassword);
- memset(const_cast<char*>(exportPassword.c_str()), 0, exportPassword.size());
-
- if (output == "-")
- io::save(*securedBag, std::cout);
- else
- io::save(*securedBag, 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;
- }
+ 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;
}
}
diff --git a/tools/ndnsec/get-default.cpp b/tools/ndnsec/get-default.cpp
index 96ee12e..0e2b499 100644
--- a/tools/ndnsec/get-default.cpp
+++ b/tools/ndnsec/get-default.cpp
@@ -28,15 +28,14 @@
int
ndnsec_get_default(int argc, char** argv)
{
- using namespace ndn;
namespace po = boost::program_options;
bool isGetDefaultId = true;
bool isGetDefaultKey = false;
bool isGetDefaultCert = false;
bool isQuiet = false;
- std::string identityString;
- std::string keyName;
+ Name identityName;
+ Name keyName;
po::options_description description("General Usage\n"
" ndnsec get-default [-h] [-k|c] [-i identity|-K key] [-q]\n"
@@ -45,8 +44,8 @@
("help,h", "produce help message")
("default_key,k", "get default key")
("default_cert,c", "get default certificate")
- ("identity,i", po::value<std::string>(&identityString), "target identity")
- ("key,K", po::value<std::string>(&keyName), "target key")
+ ("identity,i", po::value<Name>(&identityName), "target identity")
+ ("key,K", po::value<Name>(&keyName), "target key")
("quiet,q", "don't output trailing newline")
;
@@ -80,53 +79,57 @@
isQuiet = true;
}
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
if (vm.count("key") != 0) {
- Name keyNdnName(keyName);
if (isGetDefaultCert) {
- std::cout << keyChain.getDefaultCertificateNameForKey(keyNdnName);
- if (!isQuiet)
+ std::cout << keyChain.getPib()
+ .getIdentity(security::v2::extractIdentityFromKeyName(keyName))
+ .getKey(keyName)
+ .getDefaultCertificate().getName();
+
+ if (!isQuiet) {
std::cout << std::endl;
+ }
return 0;
}
return 1;
}
else if (vm.count("identity") != 0) {
- Name identity(identityString);
+ security::Key key = keyChain.getPib()
+ .getIdentity(identityName)
+ .getDefaultKey();
if (isGetDefaultKey) {
- std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+ std::cout << key.getName();
if (!isQuiet)
std::cout << std::endl;
-
return 0;
}
if (isGetDefaultCert) {
- std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+ std::cout << key.getDefaultCertificate().getName();
if (!isQuiet)
std::cout << std::endl;
-
return 0;
}
return 1;
}
else {
- Name identity = keyChain.getDefaultIdentity();
+ security::Identity identity = keyChain.getPib().getDefaultIdentity();
if (isGetDefaultId) {
- std::cout << identity;
+ std::cout << identity.getName();
if (!isQuiet)
std::cout << std::endl;
return 0;
}
if (isGetDefaultKey) {
- std::cout << keyChain.getDefaultKeyNameForIdentity(identity);
+ std::cout << identity.getDefaultKey().getName();
if (!isQuiet)
std::cout << std::endl;
return 0;
}
if (isGetDefaultCert) {
- std::cout << keyChain.getDefaultCertificateNameForIdentity(identity);
+ std::cout << identity.getDefaultKey().getDefaultCertificate().getName();
if (!isQuiet)
std::cout << std::endl;
return 0;
diff --git a/tools/ndnsec/import.cpp b/tools/ndnsec/import.cpp
index 57b9f1b..4bb9b63 100644
--- a/tools/ndnsec/import.cpp
+++ b/tools/ndnsec/import.cpp
@@ -28,17 +28,14 @@
int
ndnsec_import(int argc, char** argv)
{
- using namespace ndn;
namespace po = boost::program_options;
std::string input("-");
std::string importPassword;
- bool isPrivateImport = false;
po::options_description description("General Usage\n ndnsec import [-h] [-p] input \nGeneral options");
description.add_options()
("help,h", "produce help message")
- ("private,p", "import info contains private key")
("input,i", po::value<std::string>(&input), "input source, stdin if -")
;
@@ -61,44 +58,33 @@
return 0;
}
- if (vm.count("private") != 0)
- isPrivateImport = true;
+ try {
+ security::v2::KeyChain keyChain;
- if (!isPrivateImport) {
- std::cerr << "You are trying to import certificate!\n"
- << "Please use ndnsec cert-install!" << std::endl;
- return 1;
- }
- else {
- try {
- security::v1::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::v1::SecuredBag> securedBag;
- if (input == "-")
- securedBag = io::load<security::v1::SecuredBag>(std::cin);
- else
- securedBag = io::load<security::v1::SecuredBag>(input);
-
- int count = 3;
- while (!getPassword(importPassword, "Passphrase for the private key: ")) {
- 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;
- }
+ int count = 3;
+ while (!getPassword(importPassword, "Passphrase for the private key: ")) {
+ 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.importIdentity(*securedBag, importPassword);
- memset(const_cast<char*>(importPassword.c_str()), 0, importPassword.size());
}
- 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, 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;
+ }
}
} // namespace ndnsec
diff --git a/tools/ndnsec/key-gen.cpp b/tools/ndnsec/key-gen.cpp
index 584b79c..81e5d39 100644
--- a/tools/ndnsec/key-gen.cpp
+++ b/tools/ndnsec/key-gen.cpp
@@ -31,7 +31,7 @@
using namespace ndn;
namespace po = boost::program_options;
- std::string identityName;
+ Name identityName;
bool isDefault = true;
char keyType = 'r';
std::string outputFilename;
@@ -41,14 +41,13 @@
"General options");
description.add_options()
("help,h", "produce help message")
- ("identity,i", po::value<std::string>(&identityName),
+ ("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")
- ("dsk,d", "generate Data-Signing-Key (DSK) instead of the default Key-Signing-Key (KSK)")
("type,t", po::value<char>(&keyType)->default_value('r'),
- "optional, key type, r for RSA key (default), e for EC key")
+ "optional, key type, r for RSA key (default), e for EC key")
// ("size,s", po::value<int>(&keySize)->default_value(2048),
// "optional, key size, 2048 (default)")
;
@@ -78,21 +77,18 @@
return 1;
}
- if (vm.count("not_default") != 0)
+ if (vm.count("not_default") != 0) {
isDefault = false;
-
- bool isKsk = (vm.count("dsk") == 0);
-
- security::v1::KeyChain keyChain;
- Name keyName;
+ }
try {
+ unique_ptr<KeyParams> params;
switch (keyType) {
case 'r':
- keyName = keyChain.generateRsaKeyPair(Name(identityName), isKsk, RsaKeyParams().getKeySize());
+ params = make_unique<RsaKeyParams>();
break;
case 'e':
- keyName = keyChain.generateEcKeyPair(Name(identityName), isKsk, EcKeyParams().getKeySize());
+ params = make_unique<EcKeyParams>();
break;
default:
std::cerr << "Unrecongized key type\n"
@@ -100,19 +96,27 @@
return 1;
}
- if (keyName.empty()) {
- std::cerr << "Error: failed to generate key" << std::endl;
- return 1;
+ // @TODO set other parameters based on whatever user specified
+
+ 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();
}
- keyChain.setDefaultKeyNameForIdentity(keyName);
+ if (isDefault) {
+ keyChain.setDefaultKey(identity, key);
+ keyChain.setDefaultIdentity(identity);
+ }
- shared_ptr<security::v1::IdentityCertificate> identityCert = keyChain.selfSign(keyName);
-
- if (isDefault)
- keyChain.setDefaultIdentity(Name(identityName));
-
- io::save(*identityCert, std::cout);
+ io::save(key.getDefaultCertificate(), std::cout);
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
diff --git a/tools/ndnsec/list.cpp b/tools/ndnsec/list.cpp
index f6adbfe..36026d7 100644
--- a/tools/ndnsec/list.cpp
+++ b/tools/ndnsec/list.cpp
@@ -21,82 +21,90 @@
#include "ndnsec.hpp"
#include "util.hpp"
+#include "util/indented-stream.hpp"
namespace ndn {
namespace ndnsec {
-void
-printCertificate(security::v1::KeyChain& keyChain,
- const ndn::Name& certName,
- bool isDefault,
- int verboseLevel)
+class Printer
{
- if (isDefault)
- std::cout << " +->* ";
- else
- std::cout << " +-> ";
-
- std::cout << certName << std::endl;
-
- if (verboseLevel >= 3) {
- shared_ptr<security::v1::IdentityCertificate> certificate = keyChain.getCertificate(certName);
- if (certificate != nullptr)
- certificate->printCertificate(std::cout, " ");
+public:
+ Printer(int verboseLevel)
+ : m_verboseLevel(verboseLevel)
+ {
}
-}
-void
-printKey(security::v1::KeyChain& keyChain, const ndn::Name& keyName, bool isDefault, int verboseLevel)
-{
- if (isDefault)
- std::cout << " +->* ";
- else
- std::cout << " +-> ";
+ void
+ printIdentity(const security::Identity& identity, bool isDefault)
+ {
+ if (isDefault)
+ std::cout << "* ";
+ else
+ std::cout << " ";
- std::cout << keyName << std::endl;
+ std::cout << identity.getName() << std::endl;
- if (verboseLevel >= 2) {
- std::vector<ndn::Name> defaultCertificates;
- keyChain.getAllCertificateNamesOfKey(keyName, defaultCertificates, true);
+ if (m_verboseLevel >= 1) {
+ security::Key defaultKey;
+ try {
+ defaultKey = identity.getDefaultKey();
+ }
+ catch (const security::Pib::Error&) {
+ // no default key
+ }
- for (const auto& certName : defaultCertificates)
- printCertificate(keyChain, certName, true, verboseLevel);
+ for (const auto& key : identity.getKeys()) {
+ printKey(key, key == defaultKey);
+ }
- std::vector<ndn::Name> otherCertificates;
- keyChain.getAllCertificateNamesOfKey(keyName, otherCertificates, false);
- for (const auto& certName : otherCertificates)
- printCertificate(keyChain, certName, false, verboseLevel);
- }
-}
-
-void
-printIdentity(security::v1::KeyChain& keyChain,
- const ndn::Name& identity,
- bool isDefault,
- int verboseLevel)
-{
- if (isDefault)
- std::cout << "* ";
- else
- std::cout << " ";
-
- std::cout << identity << std::endl;
-
- if (verboseLevel >= 1) {
- std::vector<ndn::Name> defaultKeys;
- keyChain.getAllKeyNamesOfIdentity(identity, defaultKeys, true);
- for (const auto& keyName : defaultKeys)
- printKey(keyChain, keyName, true, verboseLevel);
-
- std::vector<ndn::Name> otherKeys;
- keyChain.getAllKeyNamesOfIdentity(identity, otherKeys, false);
- for (const auto& keyName : otherKeys) {
- printKey(keyChain, keyName, false, verboseLevel);
+ std::cout << std::endl;
}
-
- std::cout << std::endl;
}
-}
+
+ void
+ printKey(const security::Key& key, bool isDefault)
+ {
+ if (isDefault)
+ std::cout << " +->* ";
+ else
+ std::cout << " +-> ";
+
+ std::cout << key.getName() << std::endl;
+
+ if (m_verboseLevel >= 2) {
+ security::v2::Certificate defaultCert;
+ try {
+ defaultCert = key.getDefaultCertificate();
+ }
+ catch (const security::Pib::Error&) {
+ // no default certificate
+ }
+
+ for (const auto& cert : key.getCertificates()) {
+ printCertificate(cert, cert == defaultCert);
+ }
+ }
+ }
+
+ void
+ printCertificate(const security::v2::Certificate& cert, bool isDefault)
+ {
+ if (isDefault)
+ std::cout << " +->* ";
+ else
+ std::cout << " +-> ";
+
+ std::cout << cert.getName() << std::endl;
+
+ if (m_verboseLevel >= 3) {
+ util::IndentedStream os(std::cout, " ");
+ os << cert;
+ }
+ }
+
+private:
+ int m_verboseLevel;
+};
int
ndnsec_list(int argc, char** argv)
@@ -118,17 +126,9 @@
"verbose mode: -v is equivalent to -k, -vv is equivalent to -c")
;
- po::options_description oldOptions;
- oldOptions.add_options()
- ("key2,K", "granularity: key")
- ("cert2,C", "granularity: certificate");
-
- po::options_description allOptions;
- allOptions.add(options).add(oldOptions);
-
po::variables_map vm;
try {
- po::store(po::parse_command_line(argc, argv, allOptions), vm);
+ po::store(po::parse_command_line(argc, argv, options), vm);
po::notify(vm);
}
catch (const std::exception& e) {
@@ -144,25 +144,26 @@
}
int tmpVerboseLevel = 0;
- if (vm.count("cert") != 0 || vm.count("cert2") != 0)
+ if (vm.count("cert") != 0)
tmpVerboseLevel = 2;
- else if (vm.count("key") != 0 || vm.count("key2") != 0)
+ else if (vm.count("key") != 0)
tmpVerboseLevel = 1;
verboseLevel = std::max(verboseLevel, tmpVerboseLevel);
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
+ Printer printer(verboseLevel);
- std::vector<Name> defaultIdentities;
- keyChain.getAllIdentities(defaultIdentities, true);
- for (const auto& identity : defaultIdentities) {
- printIdentity(keyChain, identity, true, verboseLevel);
+ // TODO add API to check for default identity (may be from the identity itself)
+ security::Identity defaultIdentity;
+ try {
+ keyChain.getPib().getDefaultIdentity();
}
-
- std::vector<Name> otherIdentities;
- keyChain.getAllIdentities(otherIdentities, false);
- for (const auto& identity : otherIdentities) {
- printIdentity(keyChain, identity, false, verboseLevel);
+ catch (const security::Pib::Error&) {
+ // no default identity
+ }
+ for (const auto& identity : keyChain.getPib().getIdentities()) {
+ printer.printIdentity(identity, identity == defaultIdentity);
}
return 0;
diff --git a/tools/ndnsec/main.cpp b/tools/ndnsec/main.cpp
index 6a2572a..351c29b 100644
--- a/tools/ndnsec/main.cpp
+++ b/tools/ndnsec/main.cpp
@@ -22,24 +22,26 @@
#include "ndnsec.hpp"
#include "util.hpp"
#include "version.hpp"
+#include "util/logger.hpp"
-std::string ndnsec_helper = R"STR(
+#include <boost/exception/get_error_info.hpp>
+
+NDN_LOG_INIT(ndnsec);
+
+std::string ndnsec_helper = R"STR(\
help Show all commands
version Show version and exit
list Display information in PublicInfo
get-default Get default setting info
set-default Configure default setting
key-gen Generate a Key-Signing-Key for an identity
- dsk-gen Generate a Data-Signing-Key for an identity
sign-req Generate a certificate signing request
cert-gen Generate an identity certificate
- cert-revoke Revoke an identity certificate
cert-dump Dump a certificate from PublicInfo
cert-install Install a certificate into PublicInfo
delete Delete identity/key/certificate
export Export an identity package
import Import an identity package
- set-acl Configure ACL of a private key
unlock-tpm Unlock Tpm
)STR";
@@ -61,24 +63,35 @@
else if (command == "get-default") { return ndnsec_get_default(argc - 1, argv + 1); }
else if (command == "set-default") { return ndnsec_set_default(argc - 1, argv + 1); }
else if (command == "key-gen") { return ndnsec_key_gen(argc - 1, argv + 1); }
- else if (command == "dsk-gen") { return ndnsec_dsk_gen(argc - 1, argv + 1); }
else if (command == "sign-req") { return ndnsec_sign_req(argc - 1, argv + 1); }
else if (command == "cert-gen") { return ndnsec_cert_gen(argc - 1, argv + 1); }
- else if (command == "cert-revoke") { return ndnsec_cert_revoke(argc - 1, argv + 1); }
else if (command == "cert-dump") { return ndnsec_cert_dump(argc - 1, argv + 1); }
else if (command == "cert-install") { return ndnsec_cert_install(argc - 1, argv + 1); }
else if (command == "delete") { return ndnsec_delete(argc - 1, argv + 1); }
else if (command == "export") { return ndnsec_export(argc - 1, argv + 1); }
else if (command == "import") { return ndnsec_import(argc - 1, argv + 1); }
- else if (command == "set-acl") { return ndnsec_set_acl(argc - 1, argv + 1); }
else if (command == "unlock-tpm") { return ndnsec_unlock_tpm(argc - 1, argv + 1); }
else {
std::cerr << ndnsec_helper << std::endl;
return 1;
}
}
- catch (const std::runtime_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
+ catch (const std::exception& e) {
+
+ std::cerr << "ERROR: " << e.what();
+
+ std::ostringstream extendedError;
+ const char* const* file = boost::get_error_info<boost::throw_file>(e);
+ const int* line = boost::get_error_info<boost::throw_line>(e);
+ const char* const* func = boost::get_error_info<boost::throw_function>(e);
+ if (file && line) {
+ extendedError << " [from " << *file << ":" << *line;
+ if (func) {
+ extendedError << " in " << *func;
+ }
+ extendedError << "]";
+ }
+ NDN_LOG_ERROR(e.what() << extendedError.str());
return 1;
}
diff --git a/tools/ndnsec/ndnsec.hpp b/tools/ndnsec/ndnsec.hpp
index b64a6b2..dd34dd9 100644
--- a/tools/ndnsec/ndnsec.hpp
+++ b/tools/ndnsec/ndnsec.hpp
@@ -25,6 +25,8 @@
namespace ndn {
namespace ndnsec {
+// TODO convert to tool registry (may be)
+
int
ndnsec_list(int argc, char** argv);
@@ -38,18 +40,12 @@
ndnsec_key_gen(int argc, char** argv);
int
-ndnsec_dsk_gen(int argc, char** argv);
-
-int
ndnsec_sign_req(int argc, char** argv);
int
ndnsec_cert_gen(int argc, char** argv);
int
-ndnsec_cert_revoke(int argc, char** argv);
-
-int
ndnsec_cert_dump(int argc, char** argv);
int
@@ -65,9 +61,6 @@
ndnsec_import(int argc, char** argv);
int
-ndnsec_set_acl(int argc, char** argv);
-
-int
ndnsec_unlock_tpm(int argc, char** argv);
} // namespace ndnsec
diff --git a/tools/ndnsec/set-acl.cpp b/tools/ndnsec/set-acl.cpp
deleted file mode 100644
index 3f73f27..0000000
--- a/tools/ndnsec/set-acl.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2017 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndnsec.hpp"
-#include "util.hpp"
-
-namespace ndn {
-namespace ndnsec {
-
-int
-ndnsec_set_acl(int argc, char** argv)
-{
- using namespace ndn;
- namespace po = boost::program_options;
-
- std::string keyName;
- std::string appPath;
-
- po::options_description description("General Usage\n ndnsec set-acl [-h] keyName appPath \nGeneral options");
- description.add_options()
- ("help,h", "produce help message")
- ("keyName,k", po::value<std::string>(&keyName), "Key name.")
- ("appPath,p", po::value<std::string>(&appPath), "Application path.")
- ;
-
- po::positional_options_description p;
- p.add("keyName", 1);
- p.add("appPath", 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;
- return 1;
- }
-
- if (vm.count("help") != 0) {
- std::cerr << description << std::endl;
- return 0;
- }
-
- if (vm.count("keyName") == 0) {
- std::cerr << "ERROR: keyName is required!" << std::endl;
- std::cerr << description << std::endl;
- return 1;
- }
-
- if (vm.count("appPath") == 0) {
- std::cerr << "ERROR: appPath is required!" << std::endl;
- std::cerr << description << std::endl;
- return 1;
- }
-
- security::v1::KeyChain keyChain;
- keyChain.addAppToAcl(keyName, KeyClass::PRIVATE, appPath, AclType::PRIVATE);
-
- return 0;
-}
-
-} // namespace ndnsec
-} // namespace ndn
diff --git a/tools/ndnsec/set-default.cpp b/tools/ndnsec/set-default.cpp
index ab045ef..d39abdb 100644
--- a/tools/ndnsec/set-default.cpp
+++ b/tools/ndnsec/set-default.cpp
@@ -28,21 +28,20 @@
int
ndnsec_set_default(int argc, char** argv)
{
- using namespace ndn;
namespace po = boost::program_options;
std::string certFileName;
bool isSetDefaultId = true;
bool isSetDefaultKey = false;
bool isSetDefaultCert = false;
- std::string name;
+ Name name;
po::options_description description("General Usage\n ndnsec set-default [-h] [-k|c] name\nGeneral options");
description.add_options()
("help,h", "produce help message")
- ("default_key,k", "set default key of the identity")
- ("default_cert,c", "set default certificate of the key")
- ("name,n", po::value<std::string>(&name), "the name to set")
+ ("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")
;
po::positional_options_description p;
@@ -69,30 +68,28 @@
return 1;
}
- security::v1::KeyChain keyChain;
+ isSetDefaultId = !isSetDefaultKey && !isSetDefaultCert;
- if (vm.count("default_key") != 0) {
- isSetDefaultKey = true;
- isSetDefaultId = false;
- }
- else if (vm.count("default_cert") != 0) {
- isSetDefaultCert = true;
- isSetDefaultId = false;
- }
+ security::v2::KeyChain keyChain;
if (isSetDefaultId) {
- Name idName(name);
- keyChain.setDefaultIdentity(idName);
+ security::Identity identity = keyChain.getPib().getIdentity(name);
+ keyChain.setDefaultIdentity(identity);
return 0;
}
+
if (isSetDefaultKey) {
- Name keyName(name);
- keyChain.setDefaultKeyNameForIdentity(keyName);
+ security::Identity identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
+ security::Key key = identity.getKey(name);
+ keyChain.setDefaultKey(identity, key);
return 0;
}
if (isSetDefaultCert) {
- keyChain.setDefaultCertificateNameForKey(name);
+ 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);
+ keyChain.setDefaultCertificate(key, cert);
return 0;
}
diff --git a/tools/ndnsec/sign-req.cpp b/tools/ndnsec/sign-req.cpp
index eced361..da330cf 100644
--- a/tools/ndnsec/sign-req.cpp
+++ b/tools/ndnsec/sign-req.cpp
@@ -28,19 +28,19 @@
int
ndnsec_sign_req(int argc, char** argv)
{
- using namespace ndn;
- using namespace ndn::security;
namespace po = boost::program_options;
- std::string name;
+ Name name;
bool isKeyName = false;
po::options_description description(
"General Usage\n ndnsec sign-req [-h] [-k] name\nGeneral options");
- description.add_options()
+ description
+ .add_options()
("help,h", "produce help message")
- ("key,k", "optional, if specified, name is keyName (e.g. /ndn/edu/ucla/alice/ksk-123456789), otherwise identity name")
- ("name,n", po::value<std::string>(&name), "name, for example, /ndn/edu/ucla/alice");
+ ("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");
po::positional_options_description p;
p.add("name", 1);
@@ -67,28 +67,49 @@
return 1;
}
- if (vm.count("key") != 0)
+ if (vm.count("key") != 0) {
isKeyName = true;
-
- shared_ptr<security::v1::IdentityCertificate> selfSignCert;
-
- security::v1::KeyChain keyChain;
-
- if (isKeyName)
- selfSignCert = keyChain.selfSign(name);
- else {
- Name keyName = keyChain.getDefaultKeyNameForIdentity(name);
- selfSignCert = keyChain.selfSign(keyName);
}
- if (selfSignCert != nullptr) {
- io::save(*selfSignCert, std::cout);
- return 0;
+ security::v2::KeyChain keyChain;
+
+ security::Identity identity;
+ security::Key key;
+ if (!isKeyName) {
+ identity = keyChain.getPib().getIdentity(name);
+ key = identity.getDefaultKey();
}
else {
- std::cerr << "ERROR: Public key does not exist" << std::endl;
- return 1;
+ identity = keyChain.getPib().getIdentity(security::v2::extractIdentityFromKeyName(name));
+ key = identity.getKey(name);
}
+
+ // Create signing request (similar to self-signed certificate)
+ security::v2::Certificate certificate;
+
+ // set name
+ Name certificateName = key.getName();
+ certificateName
+ .append("cert-request")
+ .appendVersion();
+ certificate.setName(certificateName);
+
+ // set metainfo
+ certificate.setContentType(tlv::ContentType_Key);
+ certificate.setFreshnessPeriod(time::hours(1));
+
+ // set content
+ certificate.setContent(key.getPublicKey().buf(), key.getPublicKey().size());
+
+ // set signature-info
+ SignatureInfo signatureInfo;
+ signatureInfo.setValidityPeriod(security::ValidityPeriod(time::system_clock::now(),
+ time::system_clock::now() + time::days(10)));
+
+ keyChain.sign(certificate, security::SigningInfo(key).setSignatureInfo(signatureInfo));
+
+ io::save(certificate, std::cout);
+ return 0;
}
} // namespace ndnsec
diff --git a/tools/ndnsec/unlock-tpm.cpp b/tools/ndnsec/unlock-tpm.cpp
index 86d7635..0d70acc 100644
--- a/tools/ndnsec/unlock-tpm.cpp
+++ b/tools/ndnsec/unlock-tpm.cpp
@@ -29,7 +29,6 @@
ndnsec_unlock_tpm(int argc, char** argv)
{
#ifdef NDN_CXX_HAVE_GETPASS
- using namespace ndn;
namespace po = boost::program_options;
std::string keyName;
@@ -56,11 +55,11 @@
bool isUnlocked = false;
- security::v1::KeyChain keyChain;
+ security::v2::KeyChain keyChain;
char* password;
password = getpass("Password to unlock the TPM: ");
- isUnlocked = keyChain.unlockTpm(password, strlen(password), true);
+ isUnlocked = keyChain.getTpm().unlockTpm(password, strlen(password));
memset(password, 0, strlen(password));
if (isUnlocked) {
diff --git a/tools/ndnsec/util.cpp b/tools/ndnsec/util.cpp
index 7afa036..52657f7 100644
--- a/tools/ndnsec/util.cpp
+++ b/tools/ndnsec/util.cpp
@@ -25,11 +25,9 @@
namespace ndnsec {
bool
-getPassword(std::string& password, const std::string& prompt)
+getPassword(std::string& password, const std::string& prompt, bool shouldConfirm)
{
#ifdef NDN_CXX_HAVE_GETPASS
- bool isReady = false;
-
char* pw0 = nullptr;
pw0 = getpass(prompt.c_str());
@@ -38,6 +36,10 @@
std::string password1 = pw0;
memset(pw0, 0, strlen(pw0));
+ if (!shouldConfirm) {
+ return true;
+ }
+
pw0 = getpass("Confirm:");
if (!pw0) {
char* pw1 = const_cast<char*>(password1.c_str());
@@ -45,6 +47,8 @@
return false;
}
+ bool isReady = false;
+
if (!password1.compare(pw0)) {
isReady = true;
password.swap(password1);
@@ -63,13 +67,19 @@
#endif // NDN_CXX_HAVE_GETPASS
}
-shared_ptr<security::v1::IdentityCertificate>
-getIdentityCertificate(const std::string& fileName)
+security::v2::Certificate
+loadCertificate(const std::string& fileName)
{
+ shared_ptr<security::v2::Certificate> cert;
if (fileName == "-")
- return io::load<security::v1::IdentityCertificate>(std::cin);
+ cert = io::load<security::v2::Certificate>(std::cin);
else
- return io::load<security::v1::IdentityCertificate>(fileName);
+ cert = io::load<security::v2::Certificate>(fileName);
+
+ if (cert == nullptr) {
+ BOOST_THROW_EXCEPTION(CannotLoadCertificate(fileName));
+ }
+ return *cert;
}
} // namespace ndnsec
diff --git a/tools/ndnsec/util.hpp b/tools/ndnsec/util.hpp
index 4f6cee4..0173b51 100644
--- a/tools/ndnsec/util.hpp
+++ b/tools/ndnsec/util.hpp
@@ -24,7 +24,8 @@
#include "encoding/buffer-stream.hpp"
#include "security/transform.hpp"
-#include "security/v1/key-chain.hpp"
+#include "security/key-chain.hpp"
+#include "security/v2/additional-description.hpp"
#include "util/io.hpp"
#include <fstream>
@@ -37,16 +38,24 @@
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
-#include <boost/tokenizer.hpp>
namespace ndn {
namespace ndnsec {
-bool
-getPassword(std::string& password, const std::string& prompt);
+class CannotLoadCertificate : public std::runtime_error
+{
+public:
+ CannotLoadCertificate(const std::string& msg)
+ : std::runtime_error(msg)
+ {
+ }
+};
-shared_ptr<security::v1::IdentityCertificate>
-getIdentityCertificate(const std::string& fileName);
+bool
+getPassword(std::string& password, const std::string& prompt, bool shouldConfirm = true);
+
+security::v2::Certificate
+loadCertificate(const std::string& fileName);
/**
* @brief An accumulating option value to handle multiple incrementing options.