1// Copyright 2013 The Chromium 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 "net/cert/nss_cert_database_chromeos.h"
6
7#include <cert.h>
8#include <pk11pub.h>
9
10#include <algorithm>
11
12#include "base/bind.h"
13#include "base/callback.h"
14#include "base/location.h"
15#include "base/task_runner.h"
16#include "net/base/crypto_module.h"
17#include "net/cert/x509_certificate.h"
18
19namespace net {
20
21NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS(
22    crypto::ScopedPK11Slot public_slot,
23    crypto::ScopedPK11Slot private_slot)
24    : NSSCertDatabase(public_slot.Pass(), private_slot.Pass()) {
25  // By default, don't use a system slot. Only if explicitly set by
26  // SetSystemSlot, the system slot will be used.
27  profile_filter_.Init(GetPublicSlot(),
28                       GetPrivateSlot(),
29                       crypto::ScopedPK11Slot() /* no system slot */);
30}
31
32NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() {}
33
34void NSSCertDatabaseChromeOS::SetSystemSlot(
35    crypto::ScopedPK11Slot system_slot) {
36  system_slot_ = system_slot.Pass();
37  profile_filter_.Init(GetPublicSlot(), GetPrivateSlot(), GetSystemSlot());
38}
39
40void NSSCertDatabaseChromeOS::ListCertsSync(CertificateList* certs) {
41  ListCertsImpl(profile_filter_, certs);
42}
43
44void NSSCertDatabaseChromeOS::ListCerts(
45    const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) {
46  scoped_ptr<CertificateList> certs(new CertificateList());
47
48  // base::Pased will NULL out |certs|, so cache the underlying pointer here.
49  CertificateList* raw_certs = certs.get();
50  GetSlowTaskRunner()->PostTaskAndReply(
51      FROM_HERE,
52      base::Bind(&NSSCertDatabaseChromeOS::ListCertsImpl,
53                 profile_filter_,
54                 base::Unretained(raw_certs)),
55      base::Bind(callback, base::Passed(&certs)));
56}
57
58crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetSystemSlot() const {
59  if (system_slot_)
60    return crypto::ScopedPK11Slot(PK11_ReferenceSlot(system_slot_.get()));
61  return crypto::ScopedPK11Slot();
62}
63
64void NSSCertDatabaseChromeOS::ListModules(CryptoModuleList* modules,
65                                          bool need_rw) const {
66  NSSCertDatabase::ListModules(modules, need_rw);
67
68  size_t pre_size = modules->size();
69  modules->erase(
70      std::remove_if(
71          modules->begin(),
72          modules->end(),
73          NSSProfileFilterChromeOS::ModuleNotAllowedForProfilePredicate(
74              profile_filter_)),
75      modules->end());
76  DVLOG(1) << "filtered " << pre_size - modules->size() << " of " << pre_size
77           << " modules";
78}
79
80void NSSCertDatabaseChromeOS::ListCertsImpl(
81    const NSSProfileFilterChromeOS& profile_filter,
82    CertificateList* certs) {
83  NSSCertDatabase::ListCertsImpl(crypto::ScopedPK11Slot(), certs);
84
85  size_t pre_size = certs->size();
86  certs->erase(std::remove_if(
87                   certs->begin(),
88                   certs->end(),
89                   NSSProfileFilterChromeOS::CertNotAllowedForProfilePredicate(
90                       profile_filter)),
91               certs->end());
92  DVLOG(1) << "filtered " << pre_size - certs->size() << " of " << pre_size
93           << " certs";
94}
95
96}  // namespace net
97