summaryrefslogtreecommitdiff
path: root/nss-tool
diff options
context:
space:
mode:
authorStefan Gschiel <stefan.gschiel.sg@gmail.com>2017-01-13 15:57:39 +0100
committerStefan Gschiel <stefan.gschiel.sg@gmail.com>2017-01-13 15:57:39 +0100
commitf054c1f78afe1a5f6463cadf4b0e186252453848 (patch)
tree3112b1a5c6f9dd637f1577fb47929b4011dc9ca8 /nss-tool
parent555fccb2775b96911844b03ef97d13953623adab (diff)
downloadnss-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-format4
-rw-r--r--nss-tool/common/argparse.cc23
-rw-r--r--nss-tool/common/argparse.h30
-rw-r--r--nss-tool/common/scoped_ptrs.h57
-rw-r--r--nss-tool/db/dbtool.cc131
-rw-r--r--nss-tool/db/dbtool.h20
-rw-r--r--nss-tool/nss_tool.cc43
-rw-r--r--nss-tool/nss_tool.gyp27
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'
+ ],
+ }
+ ],
+}