blob: 2f370ca31f8f9bd0397d284a83b7895d65bc745b [file] [log] [blame]
Darin Petkov3c5e4dc2012-04-02 14:44:27 +02001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/nss.h"
6
7#include <base/logging.h>
8#include <base/string_number_conversions.h>
9#include <base/string_util.h>
10#include <base/stringprintf.h>
11
12#include "shill/glib.h"
13
14using base::HexEncode;
15using base::StringPrintf;
16using std::string;
17using std::vector;
18
19namespace shill {
20
21namespace {
22const char kCertfileBasename[] = "/tmp/nss-cert.";
23const char kNSSGetCertScript[] = SCRIPTDIR "/nss-get-cert";
24} // namespace
25
26// TODO(ers): not using LAZY_INSTANCE_INITIALIZER
27// because of http://crbug.com/114828
28static base::LazyInstance<NSS> g_nss = { 0, {{0}} };
29
30NSS::NSS()
31 : glib_(NULL) {
32 VLOG(2) << __func__;
33}
34
35NSS::~NSS() {
36 VLOG(2) << __func__;
37}
38
39// static
40NSS *NSS::GetInstance() {
41 return g_nss.Pointer();
42}
43
44void NSS::Init(GLib *glib) {
45 glib_ = glib;
46}
47
48FilePath NSS::GetPEMCertfile(const string &nickname, const vector<char> &id) {
49 return GetCertfile(nickname, id, "pem");
50}
51
52FilePath NSS::GetDERCertfile(const string &nickname, const vector<char> &id) {
53 return GetCertfile(nickname, id, "der");
54}
55
56FilePath NSS::GetCertfile(
57 const string &nickname, const vector<char> &id, const string &type) {
58 CHECK(glib_);
59 string filename =
60 kCertfileBasename + StringToLowerASCII(HexEncode(&id[0], id.size()));
61 char *argv[] = {
62 const_cast<char *>(kNSSGetCertScript),
63 const_cast<char *>(nickname.c_str()),
64 const_cast<char *>(type.c_str()),
65 const_cast<char *>(filename.c_str()),
66 NULL
67 };
68 int status = 0;
69 GError *error = NULL;
70 if (!glib_->SpawnSync(NULL,
71 argv,
72 NULL,
73 static_cast<GSpawnFlags>(0),
74 NULL,
75 NULL,
76 NULL,
77 NULL,
78 &status,
79 &error)) {
80 LOG(ERROR) << "nss-get-cert failed: "
81 << glib_->ConvertErrorToMessage(error);
82 return FilePath();
83 }
84 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
85 LOG(ERROR) << "nss-get-cert failed, status=" << status;
86 return FilePath();
87 }
88 return FilePath(filename);
89}
90
91} // namespace shill