Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: chromeos/cert_loader_unittest.cc

Issue 135193007: Use user specific NSSDatabase in CertLoader. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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 "chromeos/cert_loader.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "crypto/nss_util.h"
13 #include "crypto/nss_util_internal.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/cert/nss_cert_database_chromeos.h"
17 #include "net/cert/x509_certificate.h"
18 #include "net/test/cert_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace chromeos {
22 namespace {
23
24 bool IsCertInCertificateList(const net::X509Certificate* cert,
25 const net::CertificateList& cert_list) {
26 for (net::CertificateList::const_iterator it = cert_list.begin();
27 it != cert_list.end();
28 ++it) {
29 if (net::X509Certificate::IsSameOSCert((*it)->os_cert_handle(),
30 cert->os_cert_handle()))
31 return true;
32 }
33 return false;
34 }
35
36 void NotReachedPrivateSlotCallback(crypto::ScopedPK11Slot slot) {
37 ASSERT_FALSE(true) << "GetPrivateSlotForChromeOSUser callback called even "
38 << "though the private slot had been initialized.";
stevenjb 2014/01/23 18:17:42 nit: align
tbarzic 2014/01/23 19:18:37 Done.
39 }
40
41 class CertLoaderTest : public testing::Test,
42 public CertLoader::Observer {
43 public:
44 CertLoaderTest() : cert_loader_(NULL),
45 primary_user_("primary"),
46 new_certificates_loaded_events_count_(0U) {
47 }
48
49 virtual ~CertLoaderTest() {}
50
51 virtual void SetUp() OVERRIDE {
52 ASSERT_TRUE(primary_user_.constructed_successfully());
53 ASSERT_TRUE(
54 crypto::GetPublicSlotForChromeOSUser(primary_user_.username_hash()));
55
56 CertLoader::Initialize();
57 cert_loader_ = CertLoader::Get();
58 cert_loader_->AddObserver(this);
59 cert_loader_->SetCryptoTaskRunner(message_loop_.message_loop_proxy());
60 }
61
62 virtual void TearDown() {
63 cert_loader_->RemoveObserver(this);
64 CertLoader::Shutdown();
65 }
66
67 protected:
68 // CertLoader::Observer:
69 // The test keeps count of times the observer method was called.
70 virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
71 bool initial_load) OVERRIDE {
72 new_certificates_loaded_events_count_++;
73 }
74
75 // Checks if the number of |OnCertificatesLoaded| calls observed since the
76 // last call to this method equals |value|.
77 bool NewCertificatesLoadedEventsCountEquals(size_t value) {
78 bool result = value == new_certificates_loaded_events_count_;
79 new_certificates_loaded_events_count_ = 0;
80 return result;
81 }
82
83 // Finishes initialization for the |user| and returns a user's NSS database
84 // instance.
85 scoped_ptr<net::NSSCertDatabaseChromeOS> FinishUserInitAndGetDatabase(
86 crypto::ScopedTestNSSChromeOSUser* user) {
87 scoped_ptr<net::NSSCertDatabaseChromeOS> database;
88 if (!user->constructed_successfully())
89 return database.Pass();
90
91 user->FinishInit();
92
93 crypto::ScopedPK11Slot private_slot(
94 crypto::GetPrivateSlotForChromeOSUser(
95 user->username_hash(),
96 base::Bind(&NotReachedPrivateSlotCallback)));
97 if (!private_slot)
98 return database.Pass();
99
100 database.reset(new net::NSSCertDatabaseChromeOS(
101 crypto::GetPublicSlotForChromeOSUser(user->username_hash()),
102 private_slot.Pass()));
103 return database.Pass();
104 }
105
106 int GetDbPrivateSlotId(net::NSSCertDatabase* db) {
107 return static_cast<int>(PK11_GetSlotID(db->GetPrivateSlot().get()));
108 }
109
110 bool ImportCACerts(const std::string& cert_file,
111 net::NSSCertDatabase* database,
112 net::CertificateList* imported_certs) {
113 if (!database || !imported_certs)
114 return false;
115
116 // Add a certificate to the user's db.
117 *imported_certs = net::CreateCertificateListFromFile(
118 net::GetTestCertsDirectory(),
119 cert_file,
120 net::X509Certificate::FORMAT_AUTO);
121
122 net::NSSCertDatabase::ImportCertFailureList failed;
123 bool success = database->ImportCACerts(
124 *imported_certs, net::NSSCertDatabase::TRUSTED_SSL, &failed);
125 success = success && failed.empty();
126
127 if (!success)
128 imported_certs->clear();
129 return success;
130 }
131
132 bool ImportClientCertAndKey(const std::string& pkcs12_file,
133 net::NSSCertDatabase* database,
134 net::CertificateList* imported_certs) {
135 std::string pkcs12_data;
136 base::FilePath pkcs12_file_path =
137 net::GetTestCertsDirectory().Append(pkcs12_file);
138 if (!base::ReadFileToString(pkcs12_file_path, &pkcs12_data))
139 return false;
140
141 net::CertificateList client_cert_list;
142 scoped_refptr<net::CryptoModule> module(net::CryptoModule::CreateFromHandle(
143 database->GetPrivateSlot().get()));
144 return net::OK ==
145 database->ImportFromPKCS12(module, pkcs12_data, base::string16(), false,
146 imported_certs);
147 }
148
149 CertLoader* cert_loader_;
150
151 // The user is primary as the one whose certificates CertLoader handles, it
152 // has nothing to do with crypto::InitializeNSSForChromeOSUser is_primary_user
153 // parameter (which is irrelevant for these tests).
154 crypto::ScopedTestNSSChromeOSUser primary_user_;
155 scoped_ptr<net::NSSCertDatabaseChromeOS> primary_db_;
156
157 base::MessageLoop message_loop_;
158
159 private:
160 size_t new_certificates_loaded_events_count_;
161 };
162
163 TEST_F(CertLoaderTest, Basic) {
164 EXPECT_FALSE(cert_loader_->CertificatesLoading());
165 EXPECT_FALSE(cert_loader_->certificates_loaded());
166 EXPECT_FALSE(cert_loader_->is_hardware_backed());
167
168 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
169 ASSERT_TRUE(primary_db_);
170
171 cert_loader_->StartWithNSSDB(primary_db_.get());
172
173 EXPECT_FALSE(cert_loader_->certificates_loaded());
174 EXPECT_TRUE(cert_loader_->CertificatesLoading());
175 EXPECT_TRUE(cert_loader_->cert_list().empty());
176
177 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
178 base::RunLoop().RunUntilIdle();
179 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
180
181 EXPECT_TRUE(cert_loader_->certificates_loaded());
182 EXPECT_FALSE(cert_loader_->CertificatesLoading());
183 EXPECT_FALSE(cert_loader_->is_hardware_backed());
184 EXPECT_EQ(GetDbPrivateSlotId(primary_db_.get()),
185 cert_loader_->tpm_token_slot_id());
186
187 // Default CA cert roots should get loaded.
188 EXPECT_FALSE(cert_loader_->cert_list().empty());
189 }
190
191 TEST_F(CertLoaderTest, CertLoaderUpdatesCertListOnNewCert) {
192 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
193 ASSERT_TRUE(primary_db_);
194
195 cert_loader_->StartWithNSSDB(primary_db_.get());
196 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
197 base::RunLoop().RunUntilIdle();
198 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
199
200 ASSERT_TRUE(cert_loader_->certificates_loaded());
201 ASSERT_FALSE(cert_loader_->cert_list().empty());
202
203 net::CertificateList certs;
204 ASSERT_TRUE(ImportCACerts("root_ca_cert.pem", primary_db_.get(), &certs));
205 ASSERT_EQ(1U, certs.size());
206
207 // Certs are loaded asynchronously, so the new cert should not yet be in the
208 // cert list.
209 EXPECT_FALSE(IsCertInCertificateList(certs[0], cert_loader_->cert_list()));
210
211 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
212 base::RunLoop().RunUntilIdle();
213 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
214
215 // The certificate list should be updated now, as the message loop's been run.
216 EXPECT_TRUE(IsCertInCertificateList(certs[0], cert_loader_->cert_list()));
217 }
218
219 TEST_F(CertLoaderTest, CertLoaderNoUpdateOnSecondaryDbChanges) {
220 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
221 ASSERT_TRUE(primary_db_);
222 cert_loader_->StartWithNSSDB(primary_db_.get());
223
224 crypto::ScopedTestNSSChromeOSUser secondary_user("secondary");
225 scoped_ptr<net::NSSCertDatabaseChromeOS> secondary_db =
226 FinishUserInitAndGetDatabase(&secondary_user);
227 ASSERT_TRUE(secondary_db);
228
229 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
230 base::RunLoop().RunUntilIdle();
231 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
232
233 ASSERT_TRUE(cert_loader_->certificates_loaded());
234 ASSERT_FALSE(cert_loader_->cert_list().empty());
235
236 net::CertificateList certs;
237 ASSERT_TRUE(ImportCACerts("root_ca_cert.pem", secondary_db.get(), &certs));
238 ASSERT_EQ(1U, certs.size());
239
240 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
241 base::RunLoop().RunUntilIdle();
242 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
243
244 EXPECT_FALSE(IsCertInCertificateList(certs[0], cert_loader_->cert_list()));
245 }
246
247 TEST_F(CertLoaderTest, ClientLoaderUpdateOnNewClientCert) {
248 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
249 ASSERT_TRUE(primary_db_);
250 cert_loader_->StartWithNSSDB(primary_db_.get());
251 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
252 base::RunLoop().RunUntilIdle();
253 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
254
255 ASSERT_TRUE(cert_loader_->certificates_loaded());
256 ASSERT_FALSE(cert_loader_->cert_list().empty());
257
258 net::CertificateList client_certs;
259 ASSERT_TRUE(ImportClientCertAndKey("websocket_client_cert.p12",
260 primary_db_.get(),
261 &client_certs));
262 ASSERT_EQ(1U, client_certs.size());
263
264 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
265 base::RunLoop().RunUntilIdle();
266 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
267
268 EXPECT_TRUE(IsCertInCertificateList(client_certs[0],
269 cert_loader_->cert_list()));
270 }
271
272 TEST_F(CertLoaderTest, CertLoaderNoUpdateOnNewClientCertInSecondaryDb) {
273 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
274 ASSERT_TRUE(primary_db_);
275 cert_loader_->StartWithNSSDB(primary_db_.get());
276
277 crypto::ScopedTestNSSChromeOSUser secondary_user("secondary");
278 scoped_ptr<net::NSSCertDatabaseChromeOS> secondary_db =
279 FinishUserInitAndGetDatabase(&secondary_user);
280 ASSERT_TRUE(secondary_db);
281
282 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
283 base::RunLoop().RunUntilIdle();
284 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
285
286 ASSERT_TRUE(cert_loader_->certificates_loaded());
287 ASSERT_FALSE(cert_loader_->cert_list().empty());
288
289 net::CertificateList client_certs;
290 ASSERT_TRUE(ImportClientCertAndKey("websocket_client_cert.p12",
291 secondary_db.get(),
292 &client_certs));
293 ASSERT_EQ(1U, client_certs.size());
294
295 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
296 base::RunLoop().RunUntilIdle();
297 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
298
299 EXPECT_FALSE(
300 IsCertInCertificateList(client_certs[0], cert_loader_->cert_list()));
301 }
302
303 TEST_F(CertLoaderTest, UpdatedOnCertRemoval) {
304 primary_db_ = FinishUserInitAndGetDatabase(&primary_user_);
305 ASSERT_TRUE(primary_db_);
306 cert_loader_->StartWithNSSDB(primary_db_.get());
307
308 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
309 base::RunLoop().RunUntilIdle();
310 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
311
312 ASSERT_TRUE(cert_loader_->certificates_loaded());
313 ASSERT_FALSE(cert_loader_->cert_list().empty());
314
315 net::CertificateList client_certs;
316 ASSERT_TRUE(ImportClientCertAndKey("websocket_client_cert.p12",
317 primary_db_.get(),
318 &client_certs));
319 ASSERT_EQ(1U, client_certs.size());
320 base::RunLoop().RunUntilIdle();
321 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
322 ASSERT_TRUE(IsCertInCertificateList(client_certs[0],
323 cert_loader_->cert_list()));
324
325 primary_db_->DeleteCertAndKey(client_certs[0]);
326
327 ASSERT_TRUE(NewCertificatesLoadedEventsCountEquals(0U));
328 base::RunLoop().RunUntilIdle();
329 EXPECT_TRUE(NewCertificatesLoadedEventsCountEquals(1U));
330
331 ASSERT_FALSE(IsCertInCertificateList(client_certs[0],
332 cert_loader_->cert_list()));
333 }
334
335 } // namespace
336 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698