// 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
