Index: net/cert/nss_cert_database_chromeos_unittest.cc |
diff --git a/net/cert/nss_cert_database_chromeos_unittest.cc b/net/cert/nss_cert_database_chromeos_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..465d25dde47d4a3c5bab3665e883eb7ebf13826d |
--- /dev/null |
+++ b/net/cert/nss_cert_database_chromeos_unittest.cc |
@@ -0,0 +1,222 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/cert/nss_cert_database_chromeos.h" |
+ |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/run_loop.h" |
+#include "crypto/nss_util.h" |
+#include "crypto/nss_util_internal.h" |
+#include "net/base/test_data_directory.h" |
+#include "net/cert/cert_database.h" |
+#include "net/test/cert_test_util.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace net { |
+ |
+namespace { |
+ |
+bool IsCertInCertificateList(const X509Certificate* cert, |
+ const CertificateList& cert_list) { |
+ for (CertificateList::const_iterator it = cert_list.begin(); |
+ it != cert_list.end(); |
+ ++it) { |
+ if (X509Certificate::IsSameOSCert((*it)->os_cert_handle(), |
+ cert->os_cert_handle())) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+class NSSCertDatabaseChromeOSTest : public testing::Test, |
+ public CertDatabase::Observer { |
+ public: |
+ NSSCertDatabaseChromeOSTest() |
+ : observer_added_(false), user_1_("user1"), user_2_("user2") {} |
+ |
+ virtual void SetUp() OVERRIDE { |
+ // Initialize nss_util slots. |
+ ASSERT_TRUE(user_1_.constructed_successfully()); |
+ ASSERT_TRUE(user_2_.constructed_successfully()); |
+ user_1_.FinishInit(); |
+ user_2_.FinishInit(); |
+ |
+ // Create NSSCertDatabaseChromeOS for each user. |
+ db_1_.reset(new NSSCertDatabaseChromeOS( |
+ crypto::GetPublicSlotForChromeOSUser(user_1_.username_hash()), |
+ crypto::GetPrivateSlotForChromeOSUser( |
+ user_1_.username_hash(), |
+ base::Callback<void(crypto::ScopedPK11Slot)>()))); |
+ db_2_.reset(new NSSCertDatabaseChromeOS( |
+ crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()), |
+ crypto::GetPrivateSlotForChromeOSUser( |
+ user_2_.username_hash(), |
+ base::Callback<void(crypto::ScopedPK11Slot)>()))); |
+ |
+ // Add observer to CertDatabase for checking that notifications from |
+ // NSSCertDatabaseChromeOS are proxied to the CertDatabase. |
+ CertDatabase::GetInstance()->AddObserver(this); |
+ observer_added_ = true; |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ if (observer_added_) |
+ CertDatabase::GetInstance()->RemoveObserver(this); |
+ } |
+ |
+ // CertDatabase::Observer: |
+ virtual void OnCertAdded(const X509Certificate* cert) OVERRIDE { |
+ added_.push_back(cert ? cert->os_cert_handle() : NULL); |
+ } |
+ |
+ virtual void OnCertRemoved(const X509Certificate* cert) OVERRIDE {} |
+ |
+ virtual void OnCACertChanged(const X509Certificate* cert) OVERRIDE { |
+ added_ca_.push_back(cert ? cert->os_cert_handle() : NULL); |
+ } |
+ |
+ protected: |
+ bool observer_added_; |
+ // Certificates that were passed to the CertDatabase observers. |
+ std::vector<CERTCertificate*> added_ca_; |
+ std::vector<CERTCertificate*> added_; |
+ |
+ crypto::ScopedTestNSSChromeOSUser user_1_; |
+ crypto::ScopedTestNSSChromeOSUser user_2_; |
+ scoped_ptr<NSSCertDatabaseChromeOS> db_1_; |
+ scoped_ptr<NSSCertDatabaseChromeOS> db_2_; |
+}; |
+ |
+// Test that ListModules() on each user includes that user's NSS software slot, |
+// and does not include the software slot of the other user. (Does not check the |
+// private slot, since it is the same as the public slot in tests.) |
+TEST_F(NSSCertDatabaseChromeOSTest, ListModules) { |
+ CryptoModuleList modules_1; |
+ CryptoModuleList modules_2; |
+ |
+ db_1_->ListModules(&modules_1, false /* need_rw */); |
+ db_2_->ListModules(&modules_2, false /* need_rw */); |
+ |
+ bool found_1 = false; |
+ for (CryptoModuleList::iterator it = modules_1.begin(); it != modules_1.end(); |
+ ++it) { |
+ EXPECT_NE(db_2_->GetPublicSlot().get(), (*it)->os_module_handle()); |
+ if ((*it)->os_module_handle() == db_1_->GetPublicSlot().get()) |
+ found_1 = true; |
+ } |
+ EXPECT_TRUE(found_1); |
+ |
+ bool found_2 = false; |
+ for (CryptoModuleList::iterator it = modules_2.begin(); it != modules_2.end(); |
+ ++it) { |
+ EXPECT_NE(db_1_->GetPublicSlot().get(), (*it)->os_module_handle()); |
+ if ((*it)->os_module_handle() == db_2_->GetPublicSlot().get()) |
+ found_2 = true; |
+ } |
+ EXPECT_TRUE(found_2); |
+} |
+ |
+// Test that ImportCACerts imports the cert to the correct slot, and that |
+// ListCerts includes the added cert for the correct user, and does not include |
+// it for the other user. |
+TEST_F(NSSCertDatabaseChromeOSTest, ImportCACerts) { |
+ // Load test certs from disk. |
+ CertificateList certs_1 = |
+ CreateCertificateListFromFile(GetTestCertsDirectory(), |
+ "root_ca_cert.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(1U, certs_1.size()); |
+ |
+ CertificateList certs_2 = |
+ CreateCertificateListFromFile(GetTestCertsDirectory(), |
+ "2048-rsa-root.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(1U, certs_2.size()); |
+ |
+ // Import one cert for each user. |
+ NSSCertDatabase::ImportCertFailureList failed; |
+ EXPECT_TRUE( |
+ db_1_->ImportCACerts(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); |
+ EXPECT_EQ(0U, failed.size()); |
+ failed.clear(); |
+ EXPECT_TRUE( |
+ db_2_->ImportCACerts(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); |
+ EXPECT_EQ(0U, failed.size()); |
+ |
+ // Get cert list for each user. |
+ CertificateList user_1_certlist; |
+ CertificateList user_2_certlist; |
+ db_1_->ListCerts(&user_1_certlist); |
+ db_2_->ListCerts(&user_2_certlist); |
+ |
+ // Check that the imported certs only shows up in the list for the user that |
+ // imported them. |
+ EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); |
+ EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); |
+ |
+ EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); |
+ EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); |
+ |
+ // Run the message loop so the observer notifications get processed. |
+ base::RunLoop().RunUntilIdle(); |
+ // Should have gotten two OnCACertChanged notifications. |
+ ASSERT_EQ(2U, added_ca_.size()); |
+ // TODO(mattm): make NSSCertDatabase actually pass the cert to the callback, |
+ // and enable these checks: |
+ // EXPECT_EQ(certs_1[0]->os_cert_handle(), added_ca_[0]); |
+ // EXPECT_EQ(certs_2[0]->os_cert_handle(), added_ca_[1]); |
+ EXPECT_EQ(0U, added_.size()); |
+} |
+ |
+// Test that ImportServerCerts imports the cert to the correct slot, and that |
+// ListCerts includes the added cert for the correct user, and does not include |
+// it for the other user. |
+TEST_F(NSSCertDatabaseChromeOSTest, ImportServerCert) { |
+ // Load test certs from disk. |
+ CertificateList certs_1 = CreateCertificateListFromFile( |
+ GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(1U, certs_1.size()); |
+ |
+ CertificateList certs_2 = |
+ CreateCertificateListFromFile(GetTestCertsDirectory(), |
+ "2048-rsa-ee-by-2048-rsa-intermediate.pem", |
+ X509Certificate::FORMAT_AUTO); |
+ ASSERT_EQ(1U, certs_2.size()); |
+ |
+ // Import one cert for each user. |
+ NSSCertDatabase::ImportCertFailureList failed; |
+ EXPECT_TRUE( |
+ db_1_->ImportServerCert(certs_1, NSSCertDatabase::TRUSTED_SSL, &failed)); |
+ EXPECT_EQ(0U, failed.size()); |
+ failed.clear(); |
+ EXPECT_TRUE( |
+ db_2_->ImportServerCert(certs_2, NSSCertDatabase::TRUSTED_SSL, &failed)); |
+ EXPECT_EQ(0U, failed.size()); |
+ |
+ // Get cert list for each user. |
+ CertificateList user_1_certlist; |
+ CertificateList user_2_certlist; |
+ db_1_->ListCerts(&user_1_certlist); |
+ db_2_->ListCerts(&user_2_certlist); |
+ |
+ // Check that the imported certs only shows up in the list for the user that |
+ // imported them. |
+ EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist)); |
+ EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist)); |
+ |
+ EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist)); |
+ EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist)); |
+ |
+ // Run the message loop so the observer notifications get processed. |
+ base::RunLoop().RunUntilIdle(); |
+ // TODO(mattm): ImportServerCert doesn't actually cause any observers to |
+ // fire. Is that correct? |
+ EXPECT_EQ(0U, added_ca_.size()); |
+ EXPECT_EQ(0U, added_.size()); |
+} |
+ |
+} // namespace net |