// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Unit tests for InstallAttributes.

#include "cryptohome/install_attributes.h"

#include <string>
#include <vector>

#include <algorithm>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.h>

#include "cryptohome/lockbox.h"
#include "cryptohome/mock_lockbox.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_tpm_init.h"

using base::FilePath;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;

namespace cryptohome {

namespace {
static constexpr char kTestName[] = "Shuffle";
static constexpr char kTestData[] = "Duffle";
}  // namespace

// Provides a test fixture for ensuring Lockbox-flows work as expected.
//
// Multiple helpers are included to ensure tests are starting from the same
// baseline for difference scenarios, such as first boot or all-other-normal
// boots.
class InstallAttributesTest : public ::testing::Test {
 public:
  InstallAttributesTest() : install_attrs_(nullptr) {}
  ~InstallAttributesTest() override = default;

  void SetUp() override {
    ON_CALL(tpm_init_, IsTpmReady()).WillByDefault(Return(true));
    ON_CALL(tpm_init_, IsTpmEnabled()).WillByDefault(Return(true));
    ON_CALL(tpm_init_, IsTpmOwned()).WillByDefault(Return(true));

    install_attrs_.set_lockbox(&lockbox_);
    install_attrs_.set_platform(&platform_);
    // No pre-existing data and no TPM auth.
    EXPECT_CALL(lockbox_, set_tpm(&tpm_)).Times(1);
    EXPECT_CALL(tpm_, IsEnabled()).WillOnce(Return(true));
    install_attrs_.SetTpm(&tpm_);
    Mock::VerifyAndClearExpectations(&lockbox_);
    Mock::VerifyAndClearExpectations(&tpm_);
  }

  void GetAndCheck() {
    EXPECT_EQ(1, install_attrs_.Count());
    brillo::Blob data;
    EXPECT_TRUE(install_attrs_.Get(kTestName, &data));
    std::string data_str(reinterpret_cast<const char*>(data.data()),
                         data.size());
    EXPECT_STREQ(data_str.c_str(), kTestData);
  }

  // Generate the data we'll need to load from.
  brillo::Blob GenerateTestDataFileContents() {
    brillo::Blob data;
    SerializedInstallAttributes proto;
    proto.set_version(proto.version());
    SerializedInstallAttributes::Attribute* attr = proto.add_attributes();
    attr->set_name(kTestName);
    attr->set_value(std::string(reinterpret_cast<const char*>(kTestData),
                                strlen(kTestData)));
    data.resize(proto.ByteSizeLong());
    CHECK(proto.SerializeWithCachedSizesToArray(data.data()));
    return data;
  }

  void ExpectRemovingOwnerDependency() {
    EXPECT_CALL(tpm_init_,
                RemoveTpmOwnerDependency(
                    TpmPersistentState::TpmOwnerDependency::kInstallAttributes))
        .Times(1);
  }

  void ExpectNotRemovingOwnerDependency() {
    EXPECT_CALL(tpm_init_, RemoveTpmOwnerDependency(_)).Times(0);
  }

  NiceMock<MockLockbox> lockbox_;
  brillo::Blob lockbox_data_;
  InstallAttributes install_attrs_;
  NiceMock<MockPlatform> platform_;
  NiceMock<MockTpm> tpm_;
  NiceMock<MockTpmInit> tpm_init_;

 private:
  DISALLOW_COPY_AND_ASSIGN(InstallAttributesTest);
};

TEST_F(InstallAttributesTest, OobeWithTpm) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  // The first Init() call finds no data file and an unowned TPM.
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(tpm_init_, IsTpmReady()).WillRepeatedly(Return(false));
  EXPECT_CALL(tpm_init_, IsTpmOwned()).WillRepeatedly(Return(false));
  EXPECT_FALSE(install_attrs_.Init(&tpm_init_));
  Mock::VerifyAndClearExpectations(&tpm_init_);
  Mock::VerifyAndClearExpectations(&platform_);
  EXPECT_EQ(InstallAttributes::Status::kTpmNotOwned, install_attrs_.status());

  // After taking ownership, TPM is ready and Init creates the lockbox.
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(lockbox_, Reset(_)).WillOnce(Return(true));
  ExpectRemovingOwnerDependency();
  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));
  Mock::VerifyAndClearExpectations(&lockbox_);
  Mock::VerifyAndClearExpectations(&platform_);
  EXPECT_EQ(InstallAttributes::Status::kFirstInstall, install_attrs_.status());

  // Set the test attribute.
  brillo::Blob data(kTestData, kTestData + sizeof(kTestData));
  data.assign(kTestData, kTestData + strlen(kTestData));
  EXPECT_TRUE(install_attrs_.Set(kTestName, data));

  // Finalize.
  EXPECT_CALL(lockbox_, Store(_, _)).WillOnce(Return(true));
  brillo::Blob serialized_data;
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(
                  FilePath(InstallAttributes::kDefaultDataFile), _, _))
      .WillOnce(DoAll(SaveArg<1>(&serialized_data), Return(true)));
  brillo::Blob cached_data;
  EXPECT_CALL(
      platform_,
      WriteFileAtomic(FilePath(InstallAttributes::kDefaultCacheFile), _, _))
      .WillOnce(DoAll(SaveArg<1>(&cached_data), Return(true)));

  EXPECT_TRUE(install_attrs_.Finalize());
  Mock::VerifyAndClearExpectations(&lockbox_);
  Mock::VerifyAndClearExpectations(&platform_);
  EXPECT_EQ(InstallAttributes::Status::kValid, install_attrs_.status());

  brillo::Blob expected_data = GenerateTestDataFileContents();
  EXPECT_EQ(expected_data, serialized_data);
  EXPECT_EQ(expected_data, cached_data);
}

TEST_F(InstallAttributesTest, OobeWithoutTpm) {
  EXPECT_CALL(lockbox_, set_tpm(nullptr)).Times(1);
  install_attrs_.SetTpm(nullptr);

  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_FALSE(install_attrs_.is_secure());

  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(Return(false));
  ExpectNotRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kFirstInstall, install_attrs_.status());
}

TEST_F(InstallAttributesTest, OobeWithTpmBadWrite) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  // Assume authorization and working tpm.
  EXPECT_CALL(lockbox_, tpm()).WillRepeatedly(Return(&tpm_));
  EXPECT_CALL(lockbox_, Reset(_)).WillOnce(Return(true));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));
  Mock::VerifyAndClearExpectations(&lockbox_);

  brillo::Blob data;
  data.assign(kTestData, kTestData + strlen(kTestData));
  EXPECT_TRUE(install_attrs_.Set(kTestName, data));

  EXPECT_CALL(lockbox_, Store(_, _)).WillOnce(Return(true));
  EXPECT_CALL(platform_, WriteFileAtomicDurable(_, _, _))
      .WillOnce(Return(false));

  EXPECT_FALSE(install_attrs_.Finalize());

  EXPECT_EQ(InstallAttributes::Status::kInvalid, install_attrs_.status());
}

TEST_F(InstallAttributesTest, NormalBootWithTpm) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  brillo::Blob serialized_data = GenerateTestDataFileContents();
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(DoAll(SetArgPointee<1>(serialized_data), Return(true)));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kValid, install_attrs_.status());

  // Make sure the data was parsed correctly.
  GetAndCheck();
}

TEST_F(InstallAttributesTest, NormalBootWithoutTpm) {
  EXPECT_CALL(lockbox_, set_tpm(nullptr)).Times(1);
  install_attrs_.SetTpm(nullptr);

  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_FALSE(install_attrs_.is_secure());

  brillo::Blob serialized_data = GenerateTestDataFileContents();
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(DoAll(SetArgPointee<1>(serialized_data), Return(true)));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kValid, install_attrs_.status());

  // Make sure the data was parsed correctly.
  GetAndCheck();
}

// Represents that the OOBE process was interrupted by a reboot or crash prior
// to Finalize() being called, but after the Lockbox was reset.
// Since InstallAttributes Set/Finalize is not atomic, there is always the risk
// of data loss due to failure of the device. It will fail-safe however (by
// failing empty).
TEST_F(InstallAttributesTest, NormalBootUnlocked) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(Return(false));
  EXPECT_CALL(lockbox_, Reset(_)).WillOnce(Return(true));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kFirstInstall, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

// Represents that the OOBE process was interrupted by a reboot or crash prior
// to Finalize() being called, and before the Lockbox was Created.
TEST_F(InstallAttributesTest, NormalBootNoSpace) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(lockbox_, Reset(_)).WillOnce(Return(true));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kFirstInstall, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

TEST_F(InstallAttributesTest, NormalBootReadFileError) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(Return(false));
  EXPECT_CALL(lockbox_, Reset(_))
      .WillOnce(
          DoAll(SetArgPointee<0>(LockboxError::kNvramInvalid), Return(false)));
  ExpectNotRemovingOwnerDependency();
  EXPECT_CALL(platform_, DeleteFile(_, _)).Times(0);

  EXPECT_FALSE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kInvalid, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

TEST_F(InstallAttributesTest, LegacyBoot) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(Return(false));
  EXPECT_CALL(lockbox_, Reset(_))
      .WillOnce(DoAll(SetArgPointee<0>(LockboxError::kNvramSpaceAbsent),
                      Return(false)));
  ExpectRemovingOwnerDependency();

  EXPECT_TRUE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kValid, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

// If the Lockbox Reset fails for reasons other than bad password, it should
// still be treated as if locked without any attributes set.
TEST_F(InstallAttributesTest, LegacyBootUnexpected) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillOnce(Return(false));
  EXPECT_CALL(lockbox_, Reset(_))
      .WillOnce(
          DoAll(SetArgPointee<0>(LockboxError::kTpmError), Return(false)));

  EXPECT_FALSE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kInvalid, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

// If initializing with an unowned TPM, the old data file should be deleted to
// make sure that we don't accidentally pick it up as valid after taking
// ownership.
TEST_F(InstallAttributesTest, ClearPreviousDataFile) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(tpm_init_, IsTpmReady()).WillRepeatedly(Return(false));
  EXPECT_CALL(tpm_init_, IsTpmOwned()).WillRepeatedly(Return(false));

  // The cache file isn't present because lockbox-cache won't receive a dump of
  // the lockbox space if the TPM isn't owned.
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              FileExists(FilePath(InstallAttributes::kDefaultDataFile)))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              DeleteFile(FilePath(InstallAttributes::kDefaultDataFile), _))
      .WillOnce(Return(true));

  EXPECT_FALSE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kTpmNotOwned, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

// Check that if the TPM is out for lunch and inoperable in this boot cycle, we
// do keep around the data file as to not irrevocably invalidate install
// attributes should the TPM start functioning again after reboot.
TEST_F(InstallAttributesTest, KeepDataFileOnTpmFailure) {
  EXPECT_EQ(InstallAttributes::Status::kUnknown, install_attrs_.status());
  EXPECT_TRUE(install_attrs_.is_secure());

  EXPECT_CALL(tpm_init_, IsTpmReady()).WillRepeatedly(Return(false));
  EXPECT_CALL(tpm_init_, IsTpmEnabled()).WillRepeatedly(Return(false));
  EXPECT_CALL(tpm_init_, IsTpmOwned()).WillRepeatedly(Return(false));

  // The cache file isn't present because lockbox-cache won't receive a dump of
  // the lockbox space if the TPM isn't owned.
  EXPECT_CALL(platform_,
              ReadFile(FilePath(InstallAttributes::kDefaultCacheFile), _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              FileExists(FilePath(InstallAttributes::kDefaultDataFile)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              DeleteFile(FilePath(InstallAttributes::kDefaultDataFile), _))
      .Times(0);

  EXPECT_FALSE(install_attrs_.Init(&tpm_init_));

  EXPECT_EQ(InstallAttributes::Status::kInvalid, install_attrs_.status());
  EXPECT_EQ(0, install_attrs_.Count());
}

}  // namespace cryptohome
