| Index: net/ssl/client_cert_store_chromeos_unittest.cc
|
| diff --git a/net/ssl/client_cert_store_chromeos_unittest.cc b/net/ssl/client_cert_store_chromeos_unittest.cc
|
| index 3bd6d60718a736538aaad98d5c22aefbce13d00c..12a1b43b3c4d665d9b34dec61ecea8472706ca95 100644
|
| --- a/net/ssl/client_cert_store_chromeos_unittest.cc
|
| +++ b/net/ssl/client_cert_store_chromeos_unittest.cc
|
| @@ -14,6 +14,7 @@
|
| #include "crypto/nss_util_internal.h"
|
| #include "crypto/rsa_private_key.h"
|
| #include "crypto/scoped_test_nss_chromeos_user.h"
|
| +#include "crypto/scoped_test_system_nss_key_slot.h"
|
| #include "net/base/test_data_directory.h"
|
| #include "net/cert/cert_type.h"
|
| #include "net/cert/x509_certificate.h"
|
| @@ -42,15 +43,28 @@ bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,
|
| return true;
|
| }
|
|
|
| +enum ReadFromSlot {
|
| + READ_FROM_SLOT_USER,
|
| + READ_FROM_SLOT_SYSTEM
|
| +};
|
| +
|
| +enum SystemSlotAvailability {
|
| + SYSTEM_SLOT_AVAILABILITY_ENABLED,
|
| + SYSTEM_SLOT_AVAILABILITY_DISABLED
|
| +};
|
| +
|
| } // namespace
|
|
|
| // Define a delegate to be used for instantiating the parameterized test set
|
| // ClientCertStoreTest.
|
| +template <ReadFromSlot read_from,
|
| + SystemSlotAvailability system_slot_availability>
|
| class ClientCertStoreChromeOSTestDelegate {
|
| public:
|
| ClientCertStoreChromeOSTestDelegate()
|
| : user_("scopeduser"),
|
| - store_(user_.username_hash(),
|
| + store_(system_slot_availability == SYSTEM_SLOT_AVAILABILITY_ENABLED,
|
| + user_.username_hash(),
|
| ClientCertStoreChromeOS::PasswordDelegateFactory()) {
|
| // Defer futher initialization and checks to SelectClientCerts, because the
|
| // constructor doesn't allow us to return an initialization result. Could be
|
| @@ -72,10 +86,19 @@ class ClientCertStoreChromeOSTestDelegate {
|
| }
|
| user_.FinishInit();
|
|
|
| - crypto::ScopedPK11Slot slot(
|
| - crypto::GetPublicSlotForChromeOSUser(user_.username_hash()));
|
| + crypto::ScopedPK11Slot slot;
|
| + switch (read_from) {
|
| + case READ_FROM_SLOT_USER:
|
| + slot = crypto::GetPublicSlotForChromeOSUser(user_.username_hash());
|
| + break;
|
| + case READ_FROM_SLOT_SYSTEM:
|
| + slot.reset(PK11_ReferenceSlot(system_db_.slot()));
|
| + break;
|
| + default:
|
| + CHECK(false);
|
| + }
|
| if (!slot) {
|
| - LOG(ERROR) << "Could not get the user's public slot";
|
| + LOG(ERROR) << "Could not get the NSS key slot";
|
| return false;
|
| }
|
|
|
| @@ -104,6 +127,7 @@ class ClientCertStoreChromeOSTestDelegate {
|
|
|
| private:
|
| crypto::ScopedTestNSSChromeOSUser user_;
|
| + crypto::ScopedTestSystemNSSKeySlot system_db_;
|
| ClientCertStoreChromeOS store_;
|
| };
|
|
|
| @@ -112,26 +136,43 @@ class ClientCertStoreChromeOSTestDelegate {
|
| // To verify that this delegation is functional, run the same filtering tests as
|
| // for the other implementations. These tests are defined in
|
| // client_cert_store_unittest-inl.h and are instantiated for each platform.
|
| -INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS,
|
| +
|
| +// In this case, all requested certs are read from the user's slot and the
|
| +// system slot is not enabled in the store.
|
| +typedef ClientCertStoreChromeOSTestDelegate<READ_FROM_SLOT_USER,
|
| + SYSTEM_SLOT_AVAILABILITY_DISABLED>
|
| + DelegateReadUserDisableSystem;
|
| +INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadUserDisableSystem,
|
| + ClientCertStoreTest,
|
| + DelegateReadUserDisableSystem);
|
| +
|
| +// In this case, all requested certs are read from the user's slot and the
|
| +// system slot is enabled in the store.
|
| +typedef ClientCertStoreChromeOSTestDelegate<READ_FROM_SLOT_USER,
|
| + SYSTEM_SLOT_AVAILABILITY_ENABLED>
|
| + DelegateReadUserEnableSystem;
|
| +INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadUserEnableSystem,
|
| + ClientCertStoreTest,
|
| + DelegateReadUserEnableSystem);
|
| +
|
| +// In this case, all requested certs are read from the system slot, therefore
|
| +// the system slot is enabled in the store.
|
| +typedef ClientCertStoreChromeOSTestDelegate<READ_FROM_SLOT_SYSTEM,
|
| + SYSTEM_SLOT_AVAILABILITY_ENABLED>
|
| + DelegateReadSystem;
|
| +INSTANTIATE_TYPED_TEST_CASE_P(ChromeOS_ReadSystem,
|
| ClientCertStoreTest,
|
| - ClientCertStoreChromeOSTestDelegate);
|
| + DelegateReadSystem);
|
|
|
| class ClientCertStoreChromeOSTest : public ::testing::Test {
|
| public:
|
| - scoped_refptr<X509Certificate> ImportCertForUser(
|
| - const std::string& username_hash,
|
| + scoped_refptr<X509Certificate> ImportCertToSlot(
|
| const std::string& cert_filename,
|
| - const std::string& key_filename) {
|
| - crypto::ScopedPK11Slot slot(
|
| - crypto::GetPublicSlotForChromeOSUser(username_hash));
|
| - if (!slot) {
|
| - LOG(ERROR) << "No slot for user " << username_hash;
|
| - return NULL;
|
| - }
|
| -
|
| + const std::string& key_filename,
|
| + PK11SlotInfo* slot) {
|
| if (!ImportSensitiveKeyFromFile(
|
| - GetTestCertsDirectory(), key_filename, slot.get())) {
|
| - LOG(ERROR) << "Could not import private key for user " << username_hash;
|
| + GetTestCertsDirectory(), key_filename, slot)) {
|
| + LOG(ERROR) << "Could not import private key from file " << key_filename;
|
| return NULL;
|
| }
|
|
|
| @@ -143,7 +184,7 @@ class ClientCertStoreChromeOSTest : public ::testing::Test {
|
| return NULL;
|
| }
|
|
|
| - if (!ImportClientCertToSlot(cert, slot.get()))
|
| + if (!ImportClientCertToSlot(cert, slot))
|
| return NULL;
|
|
|
| // |cert| continues to point to the original X509Certificate before the
|
| @@ -151,6 +192,21 @@ class ClientCertStoreChromeOSTest : public ::testing::Test {
|
| // test.
|
| return cert;
|
| }
|
| +
|
| + scoped_refptr<X509Certificate> ImportCertForUser(
|
| + const std::string& username_hash,
|
| + const std::string& cert_filename,
|
| + const std::string& key_filename) {
|
| + crypto::ScopedPK11Slot slot(
|
| + crypto::GetPublicSlotForChromeOSUser(username_hash));
|
| + if (!slot) {
|
| + LOG(ERROR) << "No slot for user " << username_hash;
|
| + return NULL;
|
| + }
|
| +
|
| + return ImportCertToSlot(cert_filename, key_filename, slot.get());
|
| + }
|
| +
|
| };
|
|
|
| // Ensure that cert requests, that are started before the user's NSS DB is
|
| @@ -158,8 +214,13 @@ class ClientCertStoreChromeOSTest : public ::testing::Test {
|
| TEST_F(ClientCertStoreChromeOSTest, RequestWaitsForNSSInitAndSucceeds) {
|
| crypto::ScopedTestNSSChromeOSUser user("scopeduser");
|
| ASSERT_TRUE(user.constructed_successfully());
|
| +
|
| + crypto::ScopedTestSystemNSSKeySlot system_slot;
|
| +
|
| ClientCertStoreChromeOS store(
|
| - user.username_hash(), ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| + true /* use system slot */,
|
| + user.username_hash(),
|
| + ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| scoped_refptr<X509Certificate> cert_1(
|
| ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8"));
|
| ASSERT_TRUE(cert_1);
|
| @@ -194,8 +255,12 @@ TEST_F(ClientCertStoreChromeOSTest, RequestsAfterNSSInitSucceed) {
|
| ASSERT_TRUE(user.constructed_successfully());
|
| user.FinishInit();
|
|
|
| + crypto::ScopedTestSystemNSSKeySlot system_slot;
|
| +
|
| ClientCertStoreChromeOS store(
|
| - user.username_hash(), ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| + true /* use system slot */,
|
| + user.username_hash(),
|
| + ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| scoped_refptr<X509Certificate> cert_1(
|
| ImportCertForUser(user.username_hash(), "client_1.pem", "client_1.pk8"));
|
| ASSERT_TRUE(cert_1);
|
| @@ -213,7 +278,7 @@ TEST_F(ClientCertStoreChromeOSTest, RequestsAfterNSSInitSucceed) {
|
| // This verifies that a request in the context of User1 doesn't see certificates
|
| // of User2, and the other way round. We check both directions, to ensure that
|
| // the behavior doesn't depend on initialization order of the DBs, for example.
|
| -TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSecondDB) {
|
| +TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadOtherUserDB) {
|
| crypto::ScopedTestNSSChromeOSUser user1("scopeduser1");
|
| ASSERT_TRUE(user1.constructed_successfully());
|
| crypto::ScopedTestNSSChromeOSUser user2("scopeduser2");
|
| @@ -222,10 +287,14 @@ TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSecondDB) {
|
| user1.FinishInit();
|
| user2.FinishInit();
|
|
|
| + crypto::ScopedTestSystemNSSKeySlot system_slot;
|
| +
|
| ClientCertStoreChromeOS store1(
|
| + true /* use system slot */,
|
| user1.username_hash(),
|
| ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| ClientCertStoreChromeOS store2(
|
| + true /* use system slot */,
|
| user2.username_hash(),
|
| ClientCertStoreChromeOS::PasswordDelegateFactory());
|
|
|
| @@ -259,4 +328,40 @@ TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSecondDB) {
|
| EXPECT_TRUE(cert_2->Equals(selected_certs2[0]));
|
| }
|
|
|
| +// This verifies that a request in the context of User1 doesn't see certificates
|
| +// of the system store if the system store is disabled.
|
| +TEST_F(ClientCertStoreChromeOSTest, RequestDoesCrossReadSystemDB) {
|
| + crypto::ScopedTestNSSChromeOSUser user1("scopeduser1");
|
| + ASSERT_TRUE(user1.constructed_successfully());
|
| +
|
| + user1.FinishInit();
|
| +
|
| + crypto::ScopedTestSystemNSSKeySlot system_slot;
|
| +
|
| + ClientCertStoreChromeOS store(
|
| + false /* do not use system slot */,
|
| + user1.username_hash(),
|
| + ClientCertStoreChromeOS::PasswordDelegateFactory());
|
| +
|
| + scoped_refptr<X509Certificate> cert_1(
|
| + ImportCertForUser(user1.username_hash(), "client_1.pem", "client_1.pk8"));
|
| + ASSERT_TRUE(cert_1);
|
| + scoped_refptr<X509Certificate> cert_2(
|
| + ImportCertToSlot("client_2.pem", "client_2.pk8", system_slot.slot()));
|
| + ASSERT_TRUE(cert_2);
|
| +
|
| + scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
|
| +
|
| + base::RunLoop run_loop;
|
| +
|
| + CertificateList selected_certs;
|
| + store.GetClientCerts(*request_all, &selected_certs, run_loop.QuitClosure());
|
| +
|
| + run_loop.Run();
|
| +
|
| + // store should only return certs of the user, namely cert_1.
|
| + ASSERT_EQ(1u, selected_certs.size());
|
| + EXPECT_TRUE(cert_1->Equals(selected_certs[0]));
|
| +}
|
| +
|
| } // namespace net
|
|
|