summaryrefslogtreecommitdiffstats
path: root/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cert/nss_cert_database_chromeos_unittest.cc')
-rw-r--r--chromium/net/cert/nss_cert_database_chromeos_unittest.cc279
1 files changed, 279 insertions, 0 deletions
diff --git a/chromium/net/cert/nss_cert_database_chromeos_unittest.cc b/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
new file mode 100644
index 00000000000..324575d0b1e
--- /dev/null
+++ b/chromium/net/cert/nss_cert_database_chromeos_unittest.cc
@@ -0,0 +1,279 @@
+// 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/message_loop/message_loop_proxy.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;
+}
+
+void SwapCertLists(CertificateList* destination,
+ scoped_ptr<CertificateList> source) {
+ ASSERT_TRUE(destination);
+ ASSERT_TRUE(source);
+
+ destination->swap(*source);
+}
+
+} // 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_1_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current());
+ db_2_.reset(new NSSCertDatabaseChromeOS(
+ crypto::GetPublicSlotForChromeOSUser(user_2_.username_hash()),
+ crypto::GetPrivateSlotForChromeOSUser(
+ user_2_.username_hash(),
+ base::Callback<void(crypto::ScopedPK11Slot)>())));
+ db_2_->SetSlowTaskRunnerForTest(base::MessageLoopProxy::current());
+
+ // 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_->ListCertsSync(&user_1_certlist);
+ db_2_->ListCertsSync(&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());
+
+ // Tests that the new certs are loaded by async ListCerts method.
+ CertificateList user_1_certlist_async;
+ CertificateList user_2_certlist_async;
+ db_1_->ListCerts(
+ base::Bind(&SwapCertLists, base::Unretained(&user_1_certlist_async)));
+ db_2_->ListCerts(
+ base::Bind(&SwapCertLists, base::Unretained(&user_2_certlist_async)));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist_async));
+ EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist_async));
+
+ EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist_async));
+ EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist_async));
+}
+
+// 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_->ListCertsSync(&user_1_certlist);
+ db_2_->ListCertsSync(&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());
+
+ // Tests that the new certs are loaded by async ListCerts method.
+ CertificateList user_1_certlist_async;
+ CertificateList user_2_certlist_async;
+ db_1_->ListCerts(
+ base::Bind(&SwapCertLists, base::Unretained(&user_1_certlist_async)));
+ db_2_->ListCerts(
+ base::Bind(&SwapCertLists, base::Unretained(&user_2_certlist_async)));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsCertInCertificateList(certs_1[0], user_1_certlist_async));
+ EXPECT_FALSE(IsCertInCertificateList(certs_1[0], user_2_certlist_async));
+
+ EXPECT_TRUE(IsCertInCertificateList(certs_2[0], user_2_certlist_async));
+ EXPECT_FALSE(IsCertInCertificateList(certs_2[0], user_1_certlist_async));
+}
+
+// Tests that There is no crash if the database is deleted while ListCerts
+// is being processed on the worker pool.
+TEST_F(NSSCertDatabaseChromeOSTest, NoCrashIfShutdownBeforeDoneOnWorkerPool) {
+ CertificateList certlist;
+ db_1_->ListCerts(base::Bind(&SwapCertLists, base::Unretained(&certlist)));
+ EXPECT_EQ(0U, certlist.size());
+
+ db_1_.reset();
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_LT(0U, certlist.size());
+}
+
+} // namespace net