OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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 <map> | |
11 | |
12 #include "base/bind.h" | |
13 #include "base/lazy_instance.h" | |
14 #include "base/stl_util.h" | |
15 #include "base/threading/non_thread_safe.h" | |
16 #include "crypto/nss_util.h" | |
17 #include "crypto/nss_util_internal.h" | |
18 #include "net/base/crypto_module.h" | |
19 #include "net/cert/x509_certificate.h" | |
20 | |
21 namespace net { | |
22 | |
23 class NSSCertDatabaseChromeOS::Manager : public base::NonThreadSafe { | |
24 public: | |
25 ~Manager() { | |
26 STLDeleteValues(&user_db_map_); | |
27 } | |
28 | |
29 NSSCertDatabase* GetForUser( | |
30 const std::string& username_hash, | |
31 const base::Callback<void(NSSCertDatabase*)>& callback) { | |
32 DCHECK(CalledOnValidThread()); | |
33 UserDBMap::iterator it = user_db_map_.find(username_hash); | |
34 if (it != user_db_map_.end()) { | |
35 if (it->second->ready_) | |
36 return it->second; | |
37 it->second->OnReady(callback); | |
38 return NULL; | |
39 } | |
40 | |
41 crypto::ScopedPK11Slot public_slot( | |
42 crypto::GetPublicSlotForChromeOSUser(username_hash)); | |
43 if (!public_slot) { | |
44 // Invalid user, or someone called us before InitializeNSSForChromeOSUser | |
45 // got called for the user. | |
46 NOTREACHED(); | |
47 return NULL; | |
48 } | |
49 | |
50 DVLOG(1) << "Creating DB for: " << username_hash; | |
51 NSSCertDatabaseChromeOS* db = | |
52 new NSSCertDatabaseChromeOS(public_slot.Pass()); | |
53 user_db_map_[username_hash] = db; | |
54 | |
55 crypto::ScopedPK11Slot private_slot(crypto::GetPrivateSlotForChromeOSUser( | |
56 username_hash, | |
57 base::Bind(&NSSCertDatabaseChromeOS::SetPrivateSlot, | |
58 base::Unretained(db)))); | |
59 if (private_slot) | |
60 db->SetPrivateSlot(private_slot.Pass()); | |
61 | |
62 if (db->ready_) | |
63 return db; | |
64 | |
65 db->OnReady(callback); | |
66 return NULL; | |
67 } | |
68 | |
69 void RemoveUserForTesting(const std::string& username_hash) { | |
70 DCHECK(CalledOnValidThread()); | |
71 UserDBMap::iterator it = user_db_map_.find(username_hash); | |
72 if (it == user_db_map_.end()) | |
73 return; | |
74 delete it->second; | |
75 user_db_map_.erase(it); | |
76 } | |
77 | |
78 private: | |
79 friend struct base::DefaultLazyInstanceTraits<Manager>; | |
80 | |
81 Manager() {} | |
82 | |
83 typedef std::map<std::string, NSSCertDatabaseChromeOS*> UserDBMap; | |
84 UserDBMap user_db_map_; | |
85 }; | |
86 | |
87 namespace { | |
88 base::LazyInstance<NSSCertDatabaseChromeOS::Manager>::Leaky | |
89 g_nss_cert_database_chromeos_manager = LAZY_INSTANCE_INITIALIZER; | |
90 } // namespace | |
91 | |
92 // static | |
93 NSSCertDatabase* NSSCertDatabaseChromeOS::GetForUser( | |
94 const std::string& username_hash, | |
95 const base::Callback<void(NSSCertDatabase*)>& callback) { | |
96 return g_nss_cert_database_chromeos_manager.Get().GetForUser(username_hash, | |
97 callback); | |
98 } | |
99 | |
100 NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS( | |
101 crypto::ScopedPK11Slot public_slot) | |
102 : ready_(false), public_slot_(public_slot.Pass()) {} | |
103 | |
104 NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() {} | |
105 | |
106 void NSSCertDatabaseChromeOS::ListCerts(CertificateList* certs) { | |
107 DCHECK(ready_); | |
108 NSSCertDatabase::ListCerts(certs); | |
109 | |
110 size_t pre_size = certs->size(); | |
111 certs->erase(std::remove_if( | |
112 certs->begin(), | |
Ryan Sleevi
2013/12/13 19:16:59
is this clang-format'd? I would assume it would be
mattm
2013/12/18 04:00:50
Yeah, this is clang-formatted.
| |
113 certs->end(), | |
114 NSSProfileFilterChromeOS::CertNotAllowedForProfilePredicate( | |
115 profile_filter_)), | |
116 certs->end()); | |
117 DVLOG(1) << "filtered " << pre_size - certs->size() << " of " << pre_size | |
118 << " certs"; | |
119 } | |
120 | |
121 crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetPublicSlot() const { | |
122 return crypto::ScopedPK11Slot( | |
123 public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) : NULL); | |
124 } | |
125 | |
126 crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetPrivateSlot() const { | |
127 return crypto::ScopedPK11Slot( | |
128 private_slot_ ? PK11_ReferenceSlot(private_slot_.get()) : NULL); | |
129 } | |
130 | |
131 void NSSCertDatabaseChromeOS::ListModules(CryptoModuleList* modules, | |
132 bool need_rw) const { | |
133 DCHECK(ready_); | |
134 NSSCertDatabase::ListModules(modules, need_rw); | |
135 | |
136 size_t pre_size = modules->size(); | |
137 modules->erase( | |
138 std::remove_if( | |
139 modules->begin(), | |
140 modules->end(), | |
141 NSSProfileFilterChromeOS::ModuleNotAllowedForProfilePredicate( | |
142 profile_filter_)), | |
143 modules->end()); | |
144 DVLOG(1) << "filtered " << pre_size - modules->size() << " of " << pre_size | |
145 << " modules"; | |
146 } | |
147 | |
148 void NSSCertDatabaseChromeOS::SetPrivateSlot( | |
149 crypto::ScopedPK11Slot private_slot) { | |
150 DCHECK(!ready_); | |
151 if (!private_slot) | |
152 LOG(WARNING) << "initializing with NULL private_slot."; | |
153 private_slot_ = private_slot.Pass(); | |
154 profile_filter_.Init(GetPublicSlot(), GetPrivateSlot()); | |
155 ready_ = true; | |
156 | |
157 ReadyCallbackList callback_list; | |
158 callback_list.swap(ready_callback_list_); | |
159 for (ReadyCallbackList::iterator i = callback_list.begin(); | |
160 i != callback_list.end(); | |
161 ++i) { | |
162 (*i).Run(this); | |
163 } | |
164 } | |
165 | |
166 void NSSCertDatabaseChromeOS::OnReady( | |
167 const base::Callback<void(NSSCertDatabase*)>& callback) { | |
168 DCHECK(!ready_); | |
169 ready_callback_list_.push_back(callback); | |
170 } | |
171 | |
172 // static | |
173 void NSSCertDatabaseChromeOS::RemoveUserForTesting( | |
174 const std::string& username_hash) { | |
175 return g_nss_cert_database_chromeos_manager.Get().RemoveUserForTesting( | |
176 username_hash); | |
177 } | |
178 | |
179 } // namespace net | |
OLD | NEW |