diff options
author | Stefan Gschiel <stefan.gschiel.sg@gmail.com> | 2017-01-13 15:57:39 +0100 |
---|---|---|
committer | Stefan Gschiel <stefan.gschiel.sg@gmail.com> | 2017-01-13 15:57:39 +0100 |
commit | f054c1f78afe1a5f6463cadf4b0e186252453848 (patch) | |
tree | 3112b1a5c6f9dd637f1577fb47929b4011dc9ca8 /nss-tool | |
parent | 555fccb2775b96911844b03ef97d13953623adab (diff) | |
download | nss-hg-f054c1f78afe1a5f6463cadf4b0e186252453848.tar.gz |
Bug 1330980 - Add first version of new "nss" tool r=ttaubert
Differential Revision: https://nss-review.dev.mozaws.net/D84
Diffstat (limited to 'nss-tool')
-rw-r--r-- | nss-tool/.clang-format | 4 | ||||
-rw-r--r-- | nss-tool/common/argparse.cc | 23 | ||||
-rw-r--r-- | nss-tool/common/argparse.h | 30 | ||||
-rw-r--r-- | nss-tool/common/scoped_ptrs.h | 57 | ||||
-rw-r--r-- | nss-tool/db/dbtool.cc | 131 | ||||
-rw-r--r-- | nss-tool/db/dbtool.h | 20 | ||||
-rw-r--r-- | nss-tool/nss_tool.cc | 43 | ||||
-rw-r--r-- | nss-tool/nss_tool.gyp | 27 |
8 files changed, 335 insertions, 0 deletions
diff --git a/nss-tool/.clang-format b/nss-tool/.clang-format new file mode 100644 index 000000000..06e3c5115 --- /dev/null +++ b/nss-tool/.clang-format @@ -0,0 +1,4 @@ +--- +Language: Cpp +BasedOnStyle: Google +... diff --git a/nss-tool/common/argparse.cc b/nss-tool/common/argparse.cc new file mode 100644 index 000000000..3b7c73891 --- /dev/null +++ b/nss-tool/common/argparse.cc @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "argparse.h" + +ArgParser::ArgParser(const std::vector<std::string>& arguments) { + for (size_t i = 0; i < arguments.size(); i++) { + std::string arg = arguments.at(i); + if (arg.find("--") == 0) { + // look for an option argument + if (i + 1 < arguments.size() && arguments.at(i + 1).find("--") != 0) { + programArgs_[arg] = arguments.at(i + 1); + i++; + } else { + programArgs_[arg] = ""; + } + } else { + // positional argument (e.g. required argument) + positionalArgs_.push_back(arg); + } + } +} diff --git a/nss-tool/common/argparse.h b/nss-tool/common/argparse.h new file mode 100644 index 000000000..9f9d55f6d --- /dev/null +++ b/nss-tool/common/argparse.h @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef argparse_h__ +#define argparse_h__ + +#include <string> +#include <unordered_map> +#include <vector> + +class ArgParser { + public: + ArgParser(const std::vector<std::string>& arguments); + + bool Has(std::string arg) { return programArgs_.count(arg) > 0; } + + std::string Get(std::string arg) { return programArgs_[arg]; } + + size_t GetPositionalArgumentCount() { return positionalArgs_.size(); } + std::string GetPositionalArgument(size_t pos) { + return positionalArgs_.at(pos); + } + + private: + std::unordered_map<std::string, std::string> programArgs_; + std::vector<std::string> positionalArgs_; +}; + +#endif // argparse_h__ diff --git a/nss-tool/common/scoped_ptrs.h b/nss-tool/common/scoped_ptrs.h new file mode 100644 index 000000000..6752a32b4 --- /dev/null +++ b/nss-tool/common/scoped_ptrs.h @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef scoped_ptrs_h__ +#define scoped_ptrs_h__ + +#include <memory> +#include "cert.h" +#include "keyhi.h" +#include "pk11pub.h" + +struct ScopedDelete { + void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); } + void operator()(CERTCertificateList* list) { + CERT_DestroyCertificateList(list); + } + void operator()(CERTSubjectPublicKeyInfo* spki) { + SECKEY_DestroySubjectPublicKeyInfo(spki); + } + void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); } + void operator()(PK11SymKey* key) { PK11_FreeSymKey(key); } + void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); } + void operator()(SECItem* item) { SECITEM_FreeItem(item, true); } + void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); } + void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); } + + void operator()(CERTCertList* list) { CERT_DestroyCertList(list); } +}; + +template <class T> +struct ScopedMaybeDelete { + void operator()(T* ptr) { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; + +#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped##x + +SCOPED(CERTCertificate); +SCOPED(CERTCertificateList); +SCOPED(CERTSubjectPublicKeyInfo); +SCOPED(PK11SlotInfo); +SCOPED(PK11SymKey); +SCOPED(SECAlgorithmID); +SCOPED(SECItem); +SCOPED(SECKEYPublicKey); +SCOPED(SECKEYPrivateKey); + +SCOPED(CERTCertList); + +#undef SCOPED + +#endif diff --git a/nss-tool/db/dbtool.cc b/nss-tool/db/dbtool.cc new file mode 100644 index 000000000..413a83d91 --- /dev/null +++ b/nss-tool/db/dbtool.cc @@ -0,0 +1,131 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "dbtool.h" +#include "argparse.h" +#include "scoped_ptrs.h" + +#include <iomanip> +#include <iostream> +#include <memory> +#include <sstream> + +#include <cert.h> +#include <certdb.h> +#include <nss.h> + +static std::string PrintFlags(unsigned int flags) { + std::stringstream ss; + if ((flags & CERTDB_VALID_CA) && !(flags & CERTDB_TRUSTED_CA) && + !(flags & CERTDB_TRUSTED_CLIENT_CA)) { + ss << "c"; + } + if ((flags & CERTDB_TERMINAL_RECORD) && !(flags & CERTDB_TRUSTED)) { + ss << "p"; + } + if (flags & CERTDB_TRUSTED_CA) { + ss << "C"; + } + if (flags & CERTDB_TRUSTED_CLIENT_CA) { + ss << "T"; + } + if (flags & CERTDB_TRUSTED) { + ss << "P"; + } + if (flags & CERTDB_USER) { + ss << "u"; + } + if (flags & CERTDB_SEND_WARN) { + ss << "w"; + } + if (flags & CERTDB_INVISIBLE_CA) { + ss << "I"; + } + if (flags & CERTDB_GOVT_APPROVED_CA) { + ss << "G"; + } + return ss.str(); +} + +void DBTool::Usage() { + std::cerr << "Usage: nss db [--path <directory>] --list-certs" << std::endl; +} + +bool DBTool::Run(const std::vector<std::string> &arguments) { + ArgParser parser(arguments); + + std::string initDir("."); + if (parser.Has("--path")) { + initDir = parser.Get("--path"); + } + + if (!parser.Has("--list-certs")) { + return false; + } + std::cout << "Using database directory: " << initDir << std::endl + << std::endl; + + // init NSS + const char *certPrefix = ""; // certutil -P option --- can leave this empty + SECStatus rv = + NSS_Initialize(initDir.c_str(), certPrefix, certPrefix, "secmod.db", 0); + if (rv != SECSuccess) { + std::cerr << "NSS init failed!" << std::endl; + return false; + } + + ListCertificates(); + + // shutdown nss + if (NSS_Shutdown() != SECSuccess) { + std::cerr << "NSS Shutdown failed!" << std::endl; + return false; + } + + return true; +} + +void DBTool::ListCertificates() { + ScopedCERTCertList list(PK11_ListCerts(PK11CertListAll, nullptr)); + CERTCertListNode *node; + + std::cout << std::setw(60) << std::left << "Certificate Nickname" + << " " + << "Trust Attributes" << std::endl; + std::cout << std::setw(60) << std::left << "" + << " " + << "SSL,S/MIME,JAR/XPI" << std::endl + << std::endl; + + for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); + node = CERT_LIST_NEXT(node)) { + CERTCertificate *cert = node->cert; + + std::string name("(unknown)"); + char *appData = static_cast<char *>(node->appData); + if (appData && strlen(appData) > 0) { + name = appData; + } else if (cert->nickname && strlen(cert->nickname) > 0) { + name = cert->nickname; + } else if (cert->emailAddr && strlen(cert->emailAddr) > 0) { + name = cert->emailAddr; + } + + CERTCertTrust trust; + std::string trusts; + if (CERT_GetCertTrust(cert, &trust) == SECSuccess) { + std::stringstream ss; + ss << PrintFlags(trust.sslFlags); + ss << ","; + ss << PrintFlags(trust.emailFlags); + ss << ","; + ss << PrintFlags(trust.objectSigningFlags); + trusts = ss.str(); + } else { + trusts = ",,"; + } + std::cout << std::setw(60) << std::left << name << " " << trusts + << std::endl; + } +} diff --git a/nss-tool/db/dbtool.h b/nss-tool/db/dbtool.h new file mode 100644 index 000000000..606d14cd1 --- /dev/null +++ b/nss-tool/db/dbtool.h @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef dbtool_h__ +#define dbtool_h__ + +#include <string> + +class DBTool { + public: + bool Run(const std::vector<std::string>& arguments); + + void Usage(); + + private: + void ListCertificates(); +}; + +#endif // dbtool_h__ diff --git a/nss-tool/nss_tool.cc b/nss-tool/nss_tool.cc new file mode 100644 index 000000000..c857db132 --- /dev/null +++ b/nss-tool/nss_tool.cc @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <iostream> +#include <string> +#include <vector> + +#include <prinit.h> + +#include "argparse.h" +#include "db/dbtool.h" + +static void Usage() { + std::cerr << "Usage: nss <command> <subcommand> [options]" << std::endl; + std::cerr << " nss db [--path <directory>] --list-certs" << std::endl; +} + +int main(int argc, char **argv) { + if (argc < 2) { + Usage(); + return 1; + } + + if (std::string(argv[1]) != "db") { + Usage(); + return 1; + } + + int exit_code = 0; + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + + std::vector<std::string> arguments(argv + 2, argv + argc); + DBTool tool; + if (!tool.Run(arguments)) { + tool.Usage(); + exit_code = 1; + } + + PR_Cleanup(); + + return exit_code; +} diff --git a/nss-tool/nss_tool.gyp b/nss-tool/nss_tool.gyp new file mode 100644 index 000000000..2882b70be --- /dev/null +++ b/nss-tool/nss_tool.gyp @@ -0,0 +1,27 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes' : [ + '../coreconf/config.gypi', + '../cmd/platlibs.gypi', + ], + 'targets' : [ + { + 'target_name' : 'nss', + 'type' : 'executable', + 'sources' : [ + 'nss_tool.cc', + 'common/argparse.cc', + 'db/dbtool.cc', + ], + 'include_dirs': [ + 'common', + ], + 'dependencies' : [ + '<(DEPTH)/exports.gyp:dbm_exports', + '<(DEPTH)/exports.gyp:nss_exports' + ], + } + ], +} |