Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1330980 - Add first version of new "nss" tool r=ttaubert
  • Loading branch information
sg-dev1 committed Jan 13, 2017
1 parent 95cfdc5 commit 7bedb8e
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 0 deletions.
1 change: 1 addition & 0 deletions automation/taskcluster/scripts/run_clang_format.sh
Expand Up @@ -41,6 +41,7 @@ else
"$top/gtests/pk11_gtest" \
"$top/gtests/ssl_gtest" \
"$top/gtests/util_gtest" \
"$top/nss-tool" \
)
fi

Expand Down
4 changes: 4 additions & 0 deletions nss-tool/.clang-format
@@ -0,0 +1,4 @@
---
Language: Cpp
BasedOnStyle: Google
...
23 changes: 23 additions & 0 deletions 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);
}
}
}
30 changes: 30 additions & 0 deletions 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__
57 changes: 57 additions & 0 deletions 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
131 changes: 131 additions & 0 deletions 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;
}
}
20 changes: 20 additions & 0 deletions 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__
43 changes: 43 additions & 0 deletions 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;
}
27 changes: 27 additions & 0 deletions 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'
],
}
],
}
1 change: 1 addition & 0 deletions nss.gyp
Expand Up @@ -120,6 +120,7 @@
'cmd/smimetools/smimetools.gyp:cmsutil',
'cmd/ssltap/ssltap.gyp:ssltap',
'cmd/symkeyutil/symkeyutil.gyp:symkeyutil',
'nss-tool/nss_tool.gyp:nss',
],
}],
],
Expand Down

0 comments on commit 7bedb8e

Please sign in to comment.