OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/nss_cert_database_chromeos.h" | 5 #include "net/cert/nss_cert_database_chromeos.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/message_loop/message_loop_proxy.h" |
9 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
10 #include "crypto/nss_util.h" | 11 #include "crypto/nss_util.h" |
11 #include "crypto/nss_util_internal.h" | 12 #include "crypto/nss_util_internal.h" |
12 #include "net/base/test_data_directory.h" | 13 #include "net/base/test_data_directory.h" |
13 #include "net/cert/cert_database.h" | 14 #include "net/cert/cert_database.h" |
14 #include "net/test/cert_test_util.h" | 15 #include "net/test/cert_test_util.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 bool IsCertInCertificateList(const X509Certificate* cert, | 22 bool IsCertInCertificateList(const X509Certificate* cert, |
22 const CertificateList& cert_list) { | 23 const CertificateList& cert_list) { |
23 for (CertificateList::const_iterator it = cert_list.begin(); | 24 for (CertificateList::const_iterator it = cert_list.begin(); |
24 it != cert_list.end(); | 25 it != cert_list.end(); |
25 ++it) { | 26 ++it) { |
26 if (X509Certificate::IsSameOSCert((*it)->os_cert_handle(), | 27 if (X509Certificate::IsSameOSCert((*it)->os_cert_handle(), |
27 cert->os_cert_handle())) | 28 cert->os_cert_handle())) |
28 return true; | 29 return true; |
29 } | 30 } |
30 return false; | 31 return false; |
31 } | 32 } |
32 | 33 |
| 34 void SwapCertLists(CertificateList* destination, |
| 35 scoped_ptr<CertificateList> source) { |
| 36 ASSERT_TRUE(destination); |
| 37 ASSERT_TRUE(source); |
| 38 |
| 39 destination->swap(*source); |
| 40 } |
| 41 |
33 } // namespace | 42 } // namespace |
34 | 43 |
35 class NSSCertDatabaseChromeOSTest : public testing::Test, | 44 class NSSCertDatabaseChromeOSTest : public testing::Test, |
36 public CertDatabase::Observer { | 45 public CertDatabase::Observer { |
37 public: | 46 public: |
38 NSSCertDatabaseChromeOSTest() | 47 NSSCertDatabaseChromeOSTest() |
39 : observer_added_(false), user_1_("user1"), user_2_("user2") {} | 48 : observer_added_(false), user_1_("user1"), user_2_("user2") {} |
40 | 49 |
41 virtual void SetUp() OVERRIDE { | 50 virtual void SetUp() OVERRIDE { |
42 // Initialize nss_util slots. | 51 // Initialize nss_util slots. |
43 ASSERT_TRUE(user_1_.constructed_successfully()); | 52 ASSERT_TRUE(user_1_.constructed_successfully()); |
44 ASSERT_TRUE(user_2_.constructed_successfully()); | 53 ASSERT_TRUE(user_2_.constructed_successfully()); |
45 user_1_.FinishInit(); | 54 user_1_.FinishInit(); |
46 user_2_.FinishInit(); | 55 user_2_.FinishInit(); |
47 | 56 |
48 // Create NSSCertDatabaseChromeOS for each user. | 57 // Create NSSCertDatabaseChromeOS for each user. |
49 db_1_.reset(new NSSCertDatabaseChromeOS( | 58 db_1_.reset(new NSSCertDatabaseChromeOS( |
50 crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()), | 59 crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()), |
51 crypto::GetPrivateSlotForChromeOSUser( | 60 crypto::GetPrivateSlotForChromeOSUser( |
52 user_1_.username_hash(), | 61 user_1_.username_hash(), |
53 base::Callback<void(crypto::ScopedPK11Slot)>()))); | 62 base::Callback<void(crypto::ScopedPK11Slot)>()))); |
| 63 db_1_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current()); |
54 db_2_.reset(new NSSCertDatabaseChromeOS( | 64 db_2_.reset(new NSSCertDatabaseChromeOS( |
55 crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()), | 65 crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()), |
56 crypto::GetPrivateSlotForChromeOSUser( | 66 crypto::GetPrivateSlotForChromeOSUser( |
57 user_2_.username_hash(), | 67 user_2_.username_hash(), |
58 base::Callback<void(crypto::ScopedPK11Slot)>()))); | 68 base::Callback<void(crypto::ScopedPK11Slot)>()))); |
| 69 db_2_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current()); |
59 | 70 |
60 // Add observer to CertDatabase for checking that notifications from | 71 // Add observer to CertDatabase for checking that notifications from |
61 // NSSCertDatabaseChromeOS are proxied to the CertDatabase. | 72 // NSSCertDatabaseChromeOS are proxied to the CertDatabase. |
62 CertDatabase::GetInstance()->AddObserver(this); | 73 CertDatabase::GetInstance()->AddObserver(this); |
63 observer_added_ = true; | 74 observer_added_ = true; |
64 } | 75 } |
65 | 76 |
66 virtual void TearDown() OVERRIDE { | 77 virtual void TearDown() OVERRIDE { |
67 if (observer_added_) | 78 if (observer_added_) |
68 CertDatabase::GetInstance()->RemoveObserver(this); | 79 CertDatabase::GetInstance()->RemoveObserver(this); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 db_1_->ImportCACerts(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); | 154 db_1_->ImportCACerts(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); |
144 EXPECT_EQ(0U, failed.size()); | 155 EXPECT_EQ(0U, failed.size()); |
145 failed.clear(); | 156 failed.clear(); |
146 EXPECT_TRUE( | 157 EXPECT_TRUE( |
147 db_2_->ImportCACerts(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); | 158 db_2_->ImportCACerts(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); |
148 EXPECT_EQ(0U, failed.size()); | 159 EXPECT_EQ(0U, failed.size()); |
149 | 160 |
150 // Get cert list for each user. | 161 // Get cert list for each user. |
151 CertificateList user_1_certlist; | 162 CertificateList user_1_certlist; |
152 CertificateList user_2_certlist; | 163 CertificateList user_2_certlist; |
153 db_1_->ListCerts(&user_1_certlist); | 164 db_1_->ListCertsSync(&user_1_certlist); |
154 db_2_->ListCerts(&user_2_certlist); | 165 db_2_->ListCertsSync(&user_2_certlist); |
155 | 166 |
156 // Check that the imported certs only shows up in the list for the user that | 167 // Check that the imported certs only shows up in the list for the user that |
157 // imported them. | 168 // imported them. |
158 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); | 169 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); |
159 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); | 170 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); |
160 | 171 |
161 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); | 172 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); |
162 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); | 173 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); |
163 | 174 |
164 // Run the message loop so the observer notifications get processed. | 175 // Run the message loop so the observer notifications get processed. |
165 base::RunLoop().RunUntilIdle(); | 176 base::RunLoop().RunUntilIdle(); |
166 // Should have gotten two OnCACertChanged notifications. | 177 // Should have gotten two OnCACertChanged notifications. |
167 ASSERT_EQ(2U, added_ca_.size()); | 178 ASSERT_EQ(2U, added_ca_.size()); |
168 // TODO(mattm): make NSSCertDatabase actually pass the cert to the callback, | 179 // TODO(mattm): make NSSCertDatabase actually pass the cert to the callback, |
169 // and enable these checks: | 180 // and enable these checks: |
170 // EXPECT_EQ(certs_1[0]->os_cert_handle(), added_ca_[0]); | 181 // EXPECT_EQ(certs_1[0]->os_cert_handle(), added_ca_[0]); |
171 // EXPECT_EQ(certs_2[0]->os_cert_handle(), added_ca_[1]); | 182 // EXPECT_EQ(certs_2[0]->os_cert_handle(), added_ca_[1]); |
172 EXPECT_EQ(0U, added_.size()); | 183 EXPECT_EQ(0U, added_.size()); |
| 184 |
| 185 // Tests that the new certs are loaded by async ListCerts method. |
| 186 CertificateList user_1_certlist_async; |
| 187 CertificateList user_2_certlist_async; |
| 188 db_1_->ListCerts( |
| 189 base::Bind(&SwapCertLists, base::Unretained(&user_1_certlist_async))); |
| 190 db_2_->ListCerts( |
| 191 base::Bind(&SwapCertLists, base::Unretained(&user_2_certlist_async))); |
| 192 |
| 193 base::RunLoop().RunUntilIdle(); |
| 194 |
| 195 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist_async)); |
| 196 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist_async)); |
| 197 |
| 198 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist_async)); |
| 199 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist_async)); |
173 } | 200 } |
174 | 201 |
175 // Test that ImportServerCerts imports the cert to the correct slot, and that | 202 // Test that ImportServerCerts imports the cert to the correct slot, and that |
176 // ListCerts includes the added cert for the correct user, and does not include | 203 // ListCerts includes the added cert for the correct user, and does not include |
177 // it for the other user. | 204 // it for the other user. |
178 TEST_F(NSSCertDatabaseChromeOSTest, ImportServerCert) { | 205 TEST_F(NSSCertDatabaseChromeOSTest, ImportServerCert) { |
179 // Load test certs from disk. | 206 // Load test certs from disk. |
180 CertificateList certs_1 = CreateCertificateListFromFile( | 207 CertificateList certs_1 = CreateCertificateListFromFile( |
181 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO); | 208 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO); |
182 ASSERT_EQ(1U, certs_1.size()); | 209 ASSERT_EQ(1U, certs_1.size()); |
(...skipping 10 matching lines...) Expand all Loading... |
193 db_1_->ImportServerCert(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); | 220 db_1_->ImportServerCert(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); |
194 EXPECT_EQ(0U, failed.size()); | 221 EXPECT_EQ(0U, failed.size()); |
195 failed.clear(); | 222 failed.clear(); |
196 EXPECT_TRUE( | 223 EXPECT_TRUE( |
197 db_2_->ImportServerCert(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); | 224 db_2_->ImportServerCert(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); |
198 EXPECT_EQ(0U, failed.size()); | 225 EXPECT_EQ(0U, failed.size()); |
199 | 226 |
200 // Get cert list for each user. | 227 // Get cert list for each user. |
201 CertificateList user_1_certlist; | 228 CertificateList user_1_certlist; |
202 CertificateList user_2_certlist; | 229 CertificateList user_2_certlist; |
203 db_1_->ListCerts(&user_1_certlist); | 230 db_1_->ListCertsSync(&user_1_certlist); |
204 db_2_->ListCerts(&user_2_certlist); | 231 db_2_->ListCertsSync(&user_2_certlist); |
205 | 232 |
206 // Check that the imported certs only shows up in the list for the user that | 233 // Check that the imported certs only shows up in the list for the user that |
207 // imported them. | 234 // imported them. |
208 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); | 235 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); |
209 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); | 236 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); |
210 | 237 |
211 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); | 238 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); |
212 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); | 239 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); |
213 | 240 |
214 // Run the message loop so the observer notifications get processed. | 241 // Run the message loop so the observer notifications get processed. |
215 base::RunLoop().RunUntilIdle(); | 242 base::RunLoop().RunUntilIdle(); |
216 // TODO(mattm): ImportServerCert doesn't actually cause any observers to | 243 // TODO(mattm): ImportServerCert doesn't actually cause any observers to |
217 // fire. Is that correct? | 244 // fire. Is that correct? |
218 EXPECT_EQ(0U, added_ca_.size()); | 245 EXPECT_EQ(0U, added_ca_.size()); |
219 EXPECT_EQ(0U, added_.size()); | 246 EXPECT_EQ(0U, added_.size()); |
| 247 |
| 248 // Tests that the new certs are loaded by async ListCerts method. |
| 249 CertificateList user_1_certlist_async; |
| 250 CertificateList user_2_certlist_async; |
| 251 db_1_->ListCerts( |
| 252 base::Bind(&SwapCertLists, base::Unretained(&user_1_certlist_async))); |
| 253 db_2_->ListCerts( |
| 254 base::Bind(&SwapCertLists, base::Unretained(&user_2_certlist_async))); |
| 255 |
| 256 base::RunLoop().RunUntilIdle(); |
| 257 |
| 258 EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist_async)); |
| 259 EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist_async)); |
| 260 |
| 261 EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist_async)); |
| 262 EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist_async)); |
| 263 } |
| 264 |
| 265 // Tests that There is no crash if the database is deleted while ListCerts |
| 266 // is being processed on the worker pool. |
| 267 TEST_F(NSSCertDatabaseChromeOSTest, NoCrashIfShutdownBeforeDoneOnWorkerPool) { |
| 268 CertificateList certlist; |
| 269 db_1_->ListCerts(base::Bind(&SwapCertLists, base::Unretained(&certlist))); |
| 270 EXPECT_EQ(0U, certlist.size()); |
| 271 |
| 272 db_1_.reset(); |
| 273 |
| 274 base::RunLoop().RunUntilIdle(); |
| 275 |
| 276 EXPECT_LT(0U, certlist.size()); |
220 } | 277 } |
221 | 278 |
222 } // namespace net | 279 } // namespace net |
OLD | NEW |