// Copyright 2014 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 <stdint.h>

#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/fake_cryptohome_client.h"
#include "chromeos/tpm/tpm_token_info_getter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

using TpmTokenInfo = chromeos::CryptohomeClient::TpmTokenInfo;

// On invocation, set |called| to true, and store the result |token_info|
// to the |result|.
void OnTpmTokenInfoGetterCompleted(bool* called,
                                   base::Optional<TpmTokenInfo>* result,
                                   base::Optional<TpmTokenInfo> token_info) {
  DCHECK(called);
  DCHECK(result);
  *called = true;
  *result = std::move(token_info);
}

// Task runner for handling delayed tasks posted by TPMTokenInfoGetter when
// retrying failed cryptohome method calls. It just records the requested
// delay and immediately runs the task. The task is run asynchronously to be
// closer to what's actually happening in production.
// The delays used by TPMTokenGetter should be monotonically increasing, so
// the fake task runner does not handle task reordering based on the delays.
class FakeTaskRunner : public base::TaskRunner {
 public:
  // |delays|: Vector to which the dalays seen by the task runner are saved.
  explicit FakeTaskRunner(std::vector<int64_t>* delays) : delays_(delays) {}

  // base::TaskRunner overrides:
  bool PostDelayedTask(const base::Location& from_here,
                       base::OnceClosure task,
                       base::TimeDelta delay) override {
    delays_->push_back(delay.InMilliseconds());
    base::ThreadTaskRunnerHandle::Get()->PostTask(from_here, std::move(task));
    return true;
  }
  bool RunsTasksInCurrentSequence() const override { return true; }

 protected:
  ~FakeTaskRunner() override = default;

 private:
  // The vector of delays.
  std::vector<int64_t>* delays_;

  DISALLOW_COPY_AND_ASSIGN(FakeTaskRunner);
};

// Implementation of CryptohomeClient used in these tests. Note that
// TestCryptohomeClient implements FakeCryptohomeClient purely for convenience
// of not having to implement whole CryptohomeClient interface.
// TestCryptohomeClient overrides all CryptohomeClient methods used in
// TPMTokenInfoGetter tests.
class TestCryptohomeClient : public chromeos::FakeCryptohomeClient {
 public:
  // |account_id|: The user associated with the TPMTokenInfoGetter that will be
  // using the TestCryptohomeClient. Should be empty for system token.
  explicit TestCryptohomeClient(const AccountId& account_id)
      : account_id_(account_id),
        tpm_is_enabled_(true),
        tpm_is_enabled_failure_count_(0),
        tpm_is_enabled_succeeded_(false),
        get_tpm_token_info_failure_count_(0),
        get_tpm_token_info_not_set_count_(0),
        get_tpm_token_info_succeeded_(false) {}

  ~TestCryptohomeClient() override = default;

  void set_tpm_is_enabled(bool value) {
    tpm_is_enabled_ = value;
  }

  void set_tpm_is_enabled_failure_count(int value) {
    ASSERT_GT(value, 0);
    tpm_is_enabled_failure_count_ = value;
  }

  void set_get_tpm_token_info_failure_count(int value) {
    ASSERT_GT(value, 0);
    get_tpm_token_info_failure_count_ = value;
  }

  void set_get_tpm_token_info_not_set_count(int value) {
    ASSERT_GT(value, 0);
    get_tpm_token_info_not_set_count_ = value;
  }

  // Sets the tpm tpken info to be reported by the test CryptohomeClient.
  // If there is |Pkcs11GetTpmTokenInfo| in progress, runs the pending
  // callback with the set tpm token info.
  void SetTpmTokenInfo(const TpmTokenInfo& token_info) {
    tpm_token_info_ = token_info;
    ASSERT_NE(-1, tpm_token_info_->slot);

    InvokeGetTpmTokenInfoCallbackIfReady();
  }

 private:
  // FakeCryptohomeClient override.
  void TpmIsEnabled(chromeos::DBusMethodCallback<bool> callback) override {
    ASSERT_FALSE(tpm_is_enabled_succeeded_);
    base::Optional<bool> result;
    if (tpm_is_enabled_failure_count_ > 0) {
      --tpm_is_enabled_failure_count_;
    } else {
      tpm_is_enabled_succeeded_ = true;
      result.emplace(tpm_is_enabled_);
    }
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(std::move(callback), result));
  }

  void Pkcs11GetTpmTokenInfo(
      chromeos::DBusMethodCallback<TpmTokenInfo> callback) override {
    ASSERT_TRUE(account_id_.empty());

    HandleGetTpmTokenInfo(std::move(callback));
  }

  void Pkcs11GetTpmTokenInfoForUser(
      const cryptohome::AccountIdentifier& cryptohome_id,
      chromeos::DBusMethodCallback<TpmTokenInfo> callback) override {
    ASSERT_FALSE(cryptohome_id.account_id().empty());
    ASSERT_EQ(cryptohome::CreateAccountIdentifierFromAccountId(account_id_)
                  .account_id(),
              cryptohome_id.account_id());

    HandleGetTpmTokenInfo(std::move(callback));
  }

  // Handles Pkcs11GetTpmTokenInfo calls (both for system and user token). The
  // CryptohomeClient method overrides should make sure that |account_id_| is
  // properly set before calling this.
  void HandleGetTpmTokenInfo(
      chromeos::DBusMethodCallback<TpmTokenInfo> callback) {
    ASSERT_TRUE(tpm_is_enabled_succeeded_);
    ASSERT_FALSE(get_tpm_token_info_succeeded_);
    ASSERT_TRUE(pending_get_tpm_token_info_callback_.is_null());

    if (get_tpm_token_info_failure_count_ > 0) {
      --get_tpm_token_info_failure_count_;
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
      return;
    }

    if (get_tpm_token_info_not_set_count_ > 0) {
      --get_tpm_token_info_not_set_count_;
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback),
                                    TpmTokenInfo{std::string() /* label */,
                                                 std::string() /* user_pin */,
                                                 -1 /* slot */}));
      return;
    }

    pending_get_tpm_token_info_callback_ = std::move(callback);
    InvokeGetTpmTokenInfoCallbackIfReady();
  }

  void InvokeGetTpmTokenInfoCallbackIfReady() {
    if (!tpm_token_info_.has_value() || tpm_token_info_->slot == -1 ||
        pending_get_tpm_token_info_callback_.is_null())
      return;

    get_tpm_token_info_succeeded_ = true;
    // Called synchronously for convenience (to avoid using extra RunLoop in
    // tests). Unlike with other Cryptohome callbacks, TPMTokenInfoGetter does
    // not rely on this callback being called asynchronously.
    base::ResetAndReturn(&pending_get_tpm_token_info_callback_)
        .Run(tpm_token_info_);
  }

  AccountId account_id_;
  bool tpm_is_enabled_;
  int tpm_is_enabled_failure_count_;
  bool tpm_is_enabled_succeeded_;
  int get_tpm_token_info_failure_count_;
  int get_tpm_token_info_not_set_count_;
  bool get_tpm_token_info_succeeded_;
  chromeos::DBusMethodCallback<TpmTokenInfo>
      pending_get_tpm_token_info_callback_;
  base::Optional<TpmTokenInfo> tpm_token_info_;

  DISALLOW_COPY_AND_ASSIGN(TestCryptohomeClient);
};

class SystemTPMTokenInfoGetterTest : public testing::Test {
 public:
  SystemTPMTokenInfoGetterTest() = default;
  ~SystemTPMTokenInfoGetterTest() override = default;

  void SetUp() override {
    cryptohome_client_.reset(new TestCryptohomeClient(EmptyAccountId()));
    tpm_token_info_getter_ =
        chromeos::TPMTokenInfoGetter::CreateForSystemToken(
            cryptohome_client_.get(),
            scoped_refptr<base::TaskRunner>(new FakeTaskRunner(&delays_)));
  }

 protected:
  std::unique_ptr<TestCryptohomeClient> cryptohome_client_;
  std::unique_ptr<chromeos::TPMTokenInfoGetter> tpm_token_info_getter_;
  std::vector<int64_t> delays_;

 private:
  base::MessageLoop message_loop_;

  DISALLOW_COPY_AND_ASSIGN(SystemTPMTokenInfoGetterTest);
};

class UserTPMTokenInfoGetterTest : public testing::Test {
 public:
  UserTPMTokenInfoGetterTest()
      : account_id_(AccountId::FromUserEmail("user@gmail.com")) {}
  ~UserTPMTokenInfoGetterTest() override = default;

  void SetUp() override {
    cryptohome_client_.reset(new TestCryptohomeClient(account_id_));
    tpm_token_info_getter_ = chromeos::TPMTokenInfoGetter::CreateForUserToken(
        account_id_, cryptohome_client_.get(),
        scoped_refptr<base::TaskRunner>(new FakeTaskRunner(&delays_)));
  }

 protected:
  std::unique_ptr<TestCryptohomeClient> cryptohome_client_;
  std::unique_ptr<chromeos::TPMTokenInfoGetter> tpm_token_info_getter_;

  const AccountId account_id_;
  std::vector<int64_t> delays_;

 private:
  base::MessageLoop message_loop_;

  DISALLOW_COPY_AND_ASSIGN(UserTPMTokenInfoGetterTest);
};

TEST_F(SystemTPMTokenInfoGetterTest, BasicFlow) {
  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  EXPECT_EQ(std::vector<int64_t>(), delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, TokenSlotIdEqualsZero) {
  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_0", "2222", 0};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_0", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(0, result->slot);

  EXPECT_EQ(std::vector<int64_t>(), delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, TPMNotEnabled) {
  cryptohome_client_->set_tpm_is_enabled(false);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(completed);

  EXPECT_EQ(std::vector<int64_t>(), delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, TpmEnabledCallFails) {
  cryptohome_client_->set_tpm_is_enabled_failure_count(1);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  const int64_t kExpectedDelays[] = {100};
  EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyNotReady) {
  cryptohome_client_->set_get_tpm_token_info_not_set_count(1);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  const int64_t kExpectedDelays[] = {100};
  EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyFails) {
  cryptohome_client_->set_get_tpm_token_info_failure_count(1);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  const int64_t kExpectedDelays[] = {100};
  EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, RetryDelaysIncreaseExponentially) {
  cryptohome_client_->set_tpm_is_enabled_failure_count(2);
  cryptohome_client_->set_get_tpm_token_info_failure_count(1);
  cryptohome_client_->set_get_tpm_token_info_not_set_count(3);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  int64_t kExpectedDelays[] = {100, 200, 400, 800, 1600, 3200};
  ASSERT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(SystemTPMTokenInfoGetterTest, RetryDelayBounded) {
  cryptohome_client_->set_tpm_is_enabled_failure_count(4);
  cryptohome_client_->set_get_tpm_token_info_failure_count(5);
  cryptohome_client_->set_get_tpm_token_info_not_set_count(6);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  int64_t kExpectedDelays[] = {100,    200,    400,    800,    1600,
                               3200,   6400,   12800,  25600,  51200,
                               102400, 204800, 300000, 300000, 300000};
  ASSERT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(UserTPMTokenInfoGetterTest, BasicFlow) {
  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  EXPECT_EQ(std::vector<int64_t>(), delays_);
}

TEST_F(UserTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyFails) {
  cryptohome_client_->set_get_tpm_token_info_failure_count(1);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  const int64_t kExpectedDelays[] = {100};
  EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

TEST_F(UserTPMTokenInfoGetterTest, GetTpmTokenInfoInitiallyNotReady) {
  cryptohome_client_->set_get_tpm_token_info_not_set_count(1);

  bool completed = false;
  base::Optional<TpmTokenInfo> result;
  tpm_token_info_getter_->Start(
      base::BindOnce(&OnTpmTokenInfoGetterCompleted, &completed, &result));
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(completed);

  const TpmTokenInfo fake_token_info = {"TOKEN_1", "2222", 1};
  cryptohome_client_->SetTpmTokenInfo(fake_token_info);

  EXPECT_TRUE(completed);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ("TOKEN_1", result->label);
  EXPECT_EQ("2222", result->user_pin);
  EXPECT_EQ(1, result->slot);

  const int64_t kExpectedDelays[] = {100};
  EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
                                 kExpectedDelays + base::size(kExpectedDelays)),
            delays_);
}

}  // namespace
