| 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 22 matching lines...) Expand all Loading... |
| 91 scoped_ptr<NSSCertDatabaseChromeOS> db_2_; | 102 scoped_ptr<NSSCertDatabaseChromeOS> db_2_; |
| 92 }; | 103 }; |
| 93 | 104 |
| 94 // Test that ListModules() on each user includes that user's NSS software slot, | 105 // Test that ListModules() on each user includes that user's NSS software slot, |
| 95 // and does not include the software slot of the other user. (Does not check the | 106 // and does not include the software slot of the other user. (Does not check the |
| 96 // private slot, since it is the same as the public slot in tests.) | 107 // private slot, since it is the same as the public slot in tests.) |
| 97 TEST_F(NSSCertDatabaseChromeOSTest, ListModules) { | 108 TEST_F(NSSCertDatabaseChromeOSTest, ListModules) { |
| 98 CryptoModuleList modules_1; | 109 CryptoModuleList modules_1; |
| 99 CryptoModuleList modules_2; | 110 CryptoModuleList modules_2; |
| 100 | 111 |
| 101 db_1_->ListModules(&modules_1, false /* need_rw */); | 112 db_1_->ListModulesSync(&modules_1, false /* need_rw */); |
| 102 db_2_->ListModules(&modules_2, false /* need_rw */); | 113 db_2_->ListModulesSync(&modules_2, false /* need_rw */); |
| 103 | 114 |
| 104 bool found_1 = false; | 115 bool found_1 = false; |
| 105 for (CryptoModuleList::iterator it = modules_1.begin(); it != modules_1.end(); | 116 for (CryptoModuleList::iterator it = modules_1.begin(); it != modules_1.end(); |
| 106 ++it) { | 117 ++it) { |
| 107 EXPECT_NE(db_2_->GetPublicSlot().get(), (*it)->os_module_handle()); | 118 EXPECT_NE(db_2_->GetPublicSlot().get(), (*it)->os_module_handle()); |
| 108 if ((*it)->os_module_handle() == db_1_->GetPublicSlot().get()) | 119 if ((*it)->os_module_handle() == db_1_->GetPublicSlot().get()) |
| 109 found_1 = true; | 120 found_1 = true; |
| 110 } | 121 } |
| 111 EXPECT_TRUE(found_1); | 122 EXPECT_TRUE(found_1); |
| 112 | 123 |
| (...skipping 30 matching lines...) Expand all 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 |