blob: 8e8db1b12ceb281a25bbd161147b25412671aa94 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cert.h>
#include <nspr.h>
#include <nss.h>
#include <string>
#include <base/command_line.h>
#include <base/file_path.h>
#include <base/logging.h>
#include <chromeos/syslog_logging.h>
#include "shill/byte_string.h"
#include "shill/shims/certificates.h"
using shill::ByteString;
using shill::shims::Certificates;
using std::string;
namespace {
const char kCertDBDir[] = "sql:/home/chronos/user/.pki/nssdb";
class ScopedNSS {
public:
ScopedNSS() : initialized_(false) {}
~ScopedNSS();
bool Init(const string &config_dir);
private:
bool initialized_;
};
ScopedNSS::~ScopedNSS() {
if (initialized_) {
NSS_Shutdown();
initialized_ = false;
}
}
bool ScopedNSS::Init(const string &config_dir) {
if (!initialized_ && (NSS_Init(config_dir.c_str()) != SECSuccess)) {
LOG(ERROR) << "Unable to initialize NSS in " << config_dir
<< ". Error code: " << PR_GetError();
return false;
}
initialized_ = true;
return true;
}
bool GetDERCertificate(const string &nickname, ByteString *der_cert) {
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
if (!handle) {
LOG(ERROR) << "Null certificate database handle.";
return false;
}
CERTCertificate *cert = CERT_FindCertByNickname(handle, nickname.c_str());
if (!cert) {
LOG(ERROR) << "Couldn't find certificate: " << nickname;
return false;
}
*der_cert = ByteString(cert->derCert.data, cert->derCert.len);
CERT_DestroyCertificate(cert);
return true;
}
} // namespace
int main(int argc, char **argv) {
CommandLine::Init(argc, argv);
chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogHeader);
if (argc != 4) {
LOG(ERROR) << "Usage: nss-get-cert <cert-nickname> <der|pem> <outfile>";
return EXIT_FAILURE;
}
const string nickname = argv[1];
const string format_str = argv[2];
const FilePath outfile(argv[3]);
ScopedNSS nss;
ByteString cert;
if (!nss.Init(kCertDBDir) || !GetDERCertificate(nickname, &cert)) {
return EXIT_FAILURE;
}
if (format_str == "pem") {
cert = Certificates::ConvertDERToPEM(cert);
} else if (format_str != "der") {
LOG(ERROR) << "Invalid format parameter: " << format_str;
return EXIT_FAILURE;
}
return Certificates::Write(cert, outfile) ? EXIT_SUCCESS : EXIT_FAILURE;
}