15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/cert_loader.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/nss_util_internal.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "crypto/scoped_nss_types.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "crypto/scoped_test_nss_chromeos_user.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/test_data_directory.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cert/nss_cert_database_chromeos.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cert/x509_certificate.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/cert_test_util.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsCertInCertificateList(const net::X509Certificate* cert,
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             const net::CertificateList& cert_list) {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (net::CertificateList::const_iterator it = cert_list.begin();
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != cert_list.end();
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (net::X509Certificate::IsSameOSCert((*it)->os_cert_handle(),
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            cert->os_cert_handle())) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FailOnPrivateSlotCallback(crypto::ScopedPK11Slot slot) {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(true) << "GetPrivateSlotForChromeOSUser callback called even "
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     << "though the private slot had been initialized.";
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CertLoaderTest : public testing::Test,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       public CertLoader::Observer {
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CertLoaderTest() : cert_loader_(NULL),
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     primary_user_("primary"),
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     certificates_loaded_events_count_(0U) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~CertLoaderTest() {}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(primary_user_.constructed_successfully());
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        crypto::GetPublicSlotForChromeOSUser(primary_user_.username_hash()));
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CertLoader::Initialize();
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cert_loader_ = CertLoader::Get();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cert_loader_->AddObserver(this);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void TearDown() {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cert_loader_->RemoveObserver(this);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CertLoader::Shutdown();
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void StartCertLoaderWithPrimaryUser() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FinishUserInitAndGetDatabase(&primary_user_, &primary_db_);
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cert_loader_->StartWithNSSDB(primary_db_.get());
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetAndResetCertificatesLoadedEventsCount();
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CertLoader::Observer:
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The test keeps count of times the observer method was called.
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnCertificatesLoaded(const net::CertificateList& cert_list,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    bool initial_load) OVERRIDE {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(certificates_loaded_events_count_ == 0 || !initial_load);
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    certificates_loaded_events_count_++;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns the number of |OnCertificatesLoaded| calls observed since the
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // last call to this method equals |value|.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t GetAndResetCertificatesLoadedEventsCount() {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    size_t result = certificates_loaded_events_count_;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    certificates_loaded_events_count_ = 0;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Finishes initialization for the |user| and returns a user's NSS database
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // instance.
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void FinishUserInitAndGetDatabase(
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      crypto::ScopedTestNSSChromeOSUser* user,
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<net::NSSCertDatabaseChromeOS>* database) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(user->constructed_successfully());
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    user->FinishInit();
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    crypto::ScopedPK11Slot private_slot(
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        crypto::GetPrivateSlotForChromeOSUser(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            user->username_hash(),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            base::Bind(&FailOnPrivateSlotCallback)));
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(private_slot);
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    database->reset(new net::NSSCertDatabaseChromeOS(
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        crypto::GetPublicSlotForChromeOSUser(user->username_hash()),
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        private_slot.Pass()));
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    (*database)->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy());
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int GetDbPrivateSlotId(net::NSSCertDatabase* db) {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<int>(PK11_GetSlotID(db->GetPrivateSlot().get()));
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ImportCACert(const std::string& cert_file,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    net::NSSCertDatabase* database,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    net::CertificateList* imported_certs) {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(database);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(imported_certs);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Add a certificate to the user's db.
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *imported_certs = net::CreateCertificateListFromFile(
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        net::GetTestCertsDirectory(),
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cert_file,
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        net::X509Certificate::FORMAT_AUTO);
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(1U, imported_certs->size());
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::NSSCertDatabase::ImportCertFailureList failed;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(database->ImportCACerts(*imported_certs,
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        net::NSSCertDatabase::TRUST_DEFAULT,
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        &failed));
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(failed.empty());
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ImportClientCertAndKey(const std::string& pkcs12_file,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              net::NSSCertDatabase* database,
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              net::CertificateList* imported_certs) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(database);
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(imported_certs);
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string pkcs12_data;
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::FilePath pkcs12_file_path =
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        net::GetTestCertsDirectory().Append(pkcs12_file);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(base::ReadFileToString(pkcs12_file_path, &pkcs12_data));
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::CertificateList client_cert_list;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<net::CryptoModule> module(net::CryptoModule::CreateFromHandle(
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        database->GetPrivateSlot().get()));
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(net::OK,
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              database->ImportFromPKCS12(module.get(),
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         pkcs12_data,
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         base::string16(),
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         false,
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         imported_certs));
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(1U, imported_certs->size());
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CertLoader* cert_loader_;
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The user is primary as the one whose certificates CertLoader handles, it
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // has nothing to do with crypto::InitializeNSSForChromeOSUser is_primary_user
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // parameter (which is irrelevant for these tests).
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  crypto::ScopedTestNSSChromeOSUser primary_user_;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<net::NSSCertDatabaseChromeOS> primary_db_;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop message_loop_;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t certificates_loaded_events_count_;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, Basic) {
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->CertificatesLoading());
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->certificates_loaded());
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->IsHardwareBacked());
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FinishUserInitAndGetDatabase(&primary_user_, &primary_db_);
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_loader_->StartWithNSSDB(primary_db_.get());
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->certificates_loaded());
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cert_loader_->CertificatesLoading());
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cert_loader_->cert_list().empty());
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cert_loader_->certificates_loaded());
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->CertificatesLoading());
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Default CA cert roots should get loaded.
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cert_loader_->cert_list().empty());
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, CertLoaderUpdatesCertListOnNewCert) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportCACert("root_ca_cert.pem", primary_db_.get(), &certs);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Certs are loaded asynchronously, so the new cert should not yet be in the
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // cert list.
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The certificate list should be updated now, as the message loop's been run.
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, CertLoaderNoUpdateOnSecondaryDbChanges) {
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  crypto::ScopedTestNSSChromeOSUser secondary_user("secondary");
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<net::NSSCertDatabaseChromeOS> secondary_db;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FinishUserInitAndGetDatabase(&secondary_user, &secondary_db);
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportCACert("root_ca_cert.pem", secondary_db.get(), &certs);
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, ClientLoaderUpdateOnNewClientCert) {
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportClientCertAndKey("websocket_client_cert.p12",
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         primary_db_.get(),
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         &certs);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, CertLoaderNoUpdateOnNewClientCertInSecondaryDb) {
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  crypto::ScopedTestNSSChromeOSUser secondary_user("secondary");
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<net::NSSCertDatabaseChromeOS> secondary_db;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FinishUserInitAndGetDatabase(&secondary_user, &secondary_db);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportClientCertAndKey("websocket_client_cert.p12",
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         secondary_db.get(),
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         &certs);
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, UpdatedOnCertRemoval) {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportClientCertAndKey("websocket_client_cert.p12",
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         primary_db_.get(),
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         &certs);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  primary_db_->DeleteCertAndKey(certs[0].get());
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CertLoaderTest, UpdatedOnCACertTrustChange) {
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartCertLoaderWithPrimaryUser();
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CertificateList certs;
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ImportCACert("root_ca_cert.pem", primary_db_.get(), &certs);
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      IsCertInCertificateList(certs[0].get(), cert_loader_->cert_list()));
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The value that should have been set by |ImportCACert|.
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(net::NSSCertDatabase::TRUST_DEFAULT,
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            primary_db_->GetCertTrust(certs[0].get(), net::CA_CERT));
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(primary_db_->SetCertTrust(
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      certs[0].get(), net::CA_CERT, net::NSSCertDatabase::TRUSTED_SSL));
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Cert trust change should trigger certificate reload in cert_loader_.
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(0U, GetAndResetCertificatesLoadedEventsCount());
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1U, GetAndResetCertificatesLoadedEventsCount());
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace chromeos
318