
// Copyright 2022 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.

#include "cryptohome/auth_factor_vault_keyset_converter.h"

#include <stdint.h>

#include <map>
#include <memory>
#include <vector>

#include <base/check.h>
#include <brillo/cryptohome.h>
#include <cryptohome/proto_bindings/UserDataAuth.pb.h>
#include <cryptohome/proto_bindings/auth_factor.pb.h>
#include <cryptohome/proto_bindings/rpc.pb.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libhwsec-foundation/crypto/secure_blob_util.h>

#include "cryptohome/auth_factor/auth_factor.h"
#include "cryptohome/auth_factor/auth_factor_label.h"
#include "cryptohome/auth_factor/auth_factor_type.h"
#include "cryptohome/credentials.h"
#include "cryptohome/crypto.h"
#include "cryptohome/filesystem_layout.h"
#include "cryptohome/key_objects.h"
#include "cryptohome/keyset_management.h"
#include "cryptohome/mock_crypto.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/vault_keyset.h"
#include "cryptohome/vault_keyset.pb.h"

using ::testing::NiceMock;

namespace {
constexpr char kUsername[] = "user";
constexpr char kPinLabel[] = "pin";
constexpr char kLabel[] = "label0";
constexpr char kLabel1[] = "label1";
constexpr char kLabel2[] = "label2";
constexpr char kUserPassword[] = "user_pass";

constexpr char kFirstIndice[] = "0";
constexpr char kSecondIndice[] = "1";
constexpr char kThirdIndice[] = "2";

}  // namespace

namespace cryptohome {

class AuthFactorVaultKeysetConverterTest : public ::testing::Test {
 public:
  AuthFactorVaultKeysetConverterTest() : crypto_(&platform_) {}

  ~AuthFactorVaultKeysetConverterTest() override {}

  // Not copyable or movable
  AuthFactorVaultKeysetConverterTest(
      const AuthFactorVaultKeysetConverterTest&) = delete;
  AuthFactorVaultKeysetConverterTest& operator=(
      const AuthFactorVaultKeysetConverterTest&) = delete;
  AuthFactorVaultKeysetConverterTest(AuthFactorVaultKeysetConverterTest&&) =
      delete;
  AuthFactorVaultKeysetConverterTest& operator=(
      AuthFactorVaultKeysetConverterTest&&) = delete;

  void SetUp() override {
    // Setup salt for brillo functions.
    keyset_management_ = std::make_unique<KeysetManagement>(
        &platform_, &crypto_, std::make_unique<VaultKeysetFactory>());
    converter_ = std::make_unique<AuthFactorVaultKeysetConverter>(
        keyset_management_.get());
    file_system_keyset_ = FileSystemKeyset::CreateRandom();

    AddUser(kUserPassword);

    PrepareDirectoryStructure();
  }

 protected:
  NiceMock<MockPlatform> platform_;
  Crypto crypto_;
  FileSystemKeyset file_system_keyset_;
  std::unique_ptr<KeysetManagement> keyset_management_;
  std::unique_ptr<AuthFactorVaultKeysetConverter> converter_;
  struct UserInfo {
    std::string name;
    std::string obfuscated;
    brillo::SecureBlob passkey;
    Credentials credentials;
    base::FilePath homedir_path;
    base::FilePath user_path;
  };

  UserInfo user;

  void AddUser(const char* password) {
    std::string obfuscated =
        brillo::cryptohome::home::SanitizeUserName(kUsername);
    brillo::SecureBlob passkey(password);
    Credentials credentials(kUsername, passkey);

    user = {kUsername,
            obfuscated,
            passkey,
            credentials,
            UserPath(obfuscated),
            brillo::cryptohome::home::GetHashedUserPath(obfuscated)};
  }

  void PrepareDirectoryStructure() {
    ASSERT_TRUE(platform_.CreateDirectory(ShadowRoot()));
    ASSERT_TRUE(platform_.CreateDirectory(
        brillo::cryptohome::home::GetUserPathPrefix()));
    // We only need the homedir path, not the vault/mount paths.
    ASSERT_TRUE(platform_.CreateDirectory(user.homedir_path));
  }

  KeyData SetKeyData(const std::string& label) {
    KeyData key_data;
    key_data.set_label(label);
    return key_data;
  }

  void KeysetSetUpWithKeyData(const KeyData& key_data,
                              const std::string& indice) {
    VaultKeyset vk;
    vk.Initialize(&platform_, &crypto_);
    vk.CreateFromFileSystemKeyset(file_system_keyset_);
    vk.SetKeyData(key_data);
    user.credentials.set_key_data(key_data);
    ASSERT_TRUE(vk.Encrypt(user.passkey, user.obfuscated));
    ASSERT_TRUE(
        vk.Save(user.homedir_path.Append(kKeyFile).AddExtension(indice)));
  }
};

// Test that VaultKeysetsToAuthFactors return correct error when there is
// no VaultKeyset on the disk.
TEST_F(AuthFactorVaultKeysetConverterTest,
       ConvertToAuthFactorFailWhenListEmpty) {
  std::map<std::string, std::unique_ptr<AuthFactor>> label_to_auth_factor;
  EXPECT_EQ(
      user_data_auth::CRYPTOHOME_ERROR_KEY_NOT_FOUND,
      converter_->VaultKeysetsToAuthFactors(kUsername, label_to_auth_factor));
  EXPECT_TRUE(label_to_auth_factor.empty());
}

// Test that VaultKeysetsToAuthFactors lists the existing VaultKeyset on
// the disk.
TEST_F(AuthFactorVaultKeysetConverterTest, ConvertToAuthFactorListSuccess) {
  KeysetSetUpWithKeyData(SetKeyData(kLabel), kFirstIndice);
  std::map<std::string, std::unique_ptr<AuthFactor>> label_to_auth_factor;

  EXPECT_EQ(
      user_data_auth::CRYPTOHOME_ERROR_NOT_SET,
      converter_->VaultKeysetsToAuthFactors(kUsername, label_to_auth_factor));
  EXPECT_FALSE(label_to_auth_factor.empty());
  EXPECT_EQ(kLabel, label_to_auth_factor[kLabel]->label());
  EXPECT_EQ(AuthFactorType::kPassword, label_to_auth_factor[kLabel]->type());
}

// Test that VaultKeysetsToAuthFactors lists all the VaultKeysets in the
// disk.
TEST_F(AuthFactorVaultKeysetConverterTest,
       ConvertToAuthFactorListMultipleVaultKeysetsSuccess) {
  KeysetSetUpWithKeyData(SetKeyData(kLabel), kFirstIndice);
  KeysetSetUpWithKeyData(SetKeyData(kLabel1), kSecondIndice);
  KeysetSetUpWithKeyData(SetKeyData(kLabel2), kThirdIndice);

  std::map<std::string, std::unique_ptr<AuthFactor>> label_to_auth_factor;

  EXPECT_EQ(
      user_data_auth::CRYPTOHOME_ERROR_NOT_SET,
      converter_->VaultKeysetsToAuthFactors(kUsername, label_to_auth_factor));
  EXPECT_EQ(3, label_to_auth_factor.size());

  EXPECT_EQ(kLabel, label_to_auth_factor[kLabel]->label());
  EXPECT_EQ(AuthFactorType::kPassword, label_to_auth_factor[kLabel]->type());

  EXPECT_EQ(kLabel1, label_to_auth_factor[kLabel1]->label());
  EXPECT_EQ(AuthFactorType::kPassword, label_to_auth_factor[kLabel1]->type());

  EXPECT_EQ(kLabel2, label_to_auth_factor[kLabel2]->label());
  EXPECT_EQ(AuthFactorType::kPassword, label_to_auth_factor[kLabel2]->type());
}

// Test that PopulateKeyDataForVK returns correct KeyData for the given
// label.
TEST_F(AuthFactorVaultKeysetConverterTest, ConvertToVaultKeysetDataSuccess) {
  KeyData test_key_data = SetKeyData(kLabel);
  KeysetSetUpWithKeyData(test_key_data, kFirstIndice);

  KeyData key_data;
  std::string auth_factor_label = kLabel;
  EXPECT_EQ(
      user_data_auth::CRYPTOHOME_ERROR_NOT_SET,
      converter_->PopulateKeyDataForVK(kUsername, auth_factor_label, key_data));
  EXPECT_EQ(kLabel, key_data.label());
}

// Test that PopulateKeyDataForVK fails to return KeyData for a wrong given
// label.
TEST_F(AuthFactorVaultKeysetConverterTest, ConvertToVaultKeysetDataFail) {
  KeyData test_key_data = SetKeyData(kLabel);
  KeysetSetUpWithKeyData(test_key_data, kFirstIndice);

  KeyData key_data;
  std::string auth_factor_label = kLabel1;
  EXPECT_EQ(
      user_data_auth::CRYPTOHOME_ERROR_KEY_NOT_FOUND,
      converter_->PopulateKeyDataForVK(kUsername, auth_factor_label, key_data));
}

// Test that AuthFactorToKeyData generates correct KeyData for the given
// password label and type.
TEST_F(AuthFactorVaultKeysetConverterTest, GenerateKeyDataPassword) {
  KeyData key_data = SetKeyData(kLabel);
  key_data.set_type(KeyData::KEY_TYPE_PASSWORD);

  KeyData test_key_data;
  std::string auth_factor_label = kLabel;
  AuthFactorType auth_factor_type = AuthFactorType::kPassword;

  EXPECT_EQ(user_data_auth::CRYPTOHOME_ERROR_NOT_SET,
            converter_->AuthFactorToKeyData(auth_factor_label, auth_factor_type,
                                            test_key_data));
  EXPECT_EQ(key_data.label(), test_key_data.label());
  EXPECT_EQ(key_data.type(), test_key_data.type());
  EXPECT_FALSE(test_key_data.policy().low_entropy_credential());
}

// Test that AuthFactorToKeyData generates correct KeyData for the given
// password label and type.
TEST_F(AuthFactorVaultKeysetConverterTest, GenerateKeyDataPin) {
  KeyData key_data = SetKeyData(kPinLabel);
  key_data.set_type(KeyData::KEY_TYPE_PASSWORD);
  key_data.mutable_policy()->set_low_entropy_credential(true);

  KeyData test_key_data;
  std::string auth_factor_label = kPinLabel;
  AuthFactorType auth_factor_type = AuthFactorType::kPin;

  EXPECT_EQ(user_data_auth::CRYPTOHOME_ERROR_NOT_SET,
            converter_->AuthFactorToKeyData(auth_factor_label, auth_factor_type,
                                            test_key_data));
  EXPECT_EQ(key_data.label(), test_key_data.label());
  EXPECT_EQ(key_data.type(), test_key_data.type());
  EXPECT_TRUE(test_key_data.policy().low_entropy_credential());
}

// Test that VaultKeysetToAuthFactor returns correct AuthFactor for the given
// label.
TEST_F(AuthFactorVaultKeysetConverterTest, VaultKeysetToAuthFactorSuccess) {
  KeyData test_key_data = SetKeyData(kLabel);
  KeysetSetUpWithKeyData(test_key_data, kFirstIndice);

  KeyData key_data;
  std::string auth_factor_label = kLabel;
  std::unique_ptr<AuthFactor> auth_factor =
      converter_->VaultKeysetToAuthFactor(kUsername, auth_factor_label);
  EXPECT_NE(nullptr, auth_factor);
  EXPECT_EQ(kLabel, auth_factor->label());
  EXPECT_EQ(AuthFactorType::kPassword, auth_factor->type());
}

// Test that VaultKeysetToAuthFactor fails to return AuthFactor for a wrong
// given label.
TEST_F(AuthFactorVaultKeysetConverterTest, VaultKeysetToAuthFactorFail) {
  KeyData test_key_data = SetKeyData(kLabel);
  KeysetSetUpWithKeyData(test_key_data, kFirstIndice);

  KeyData key_data;
  std::string auth_factor_label = kLabel1;
  std::unique_ptr<AuthFactor> auth_factor =
      converter_->VaultKeysetToAuthFactor(kUsername, auth_factor_label);
  EXPECT_EQ(nullptr, auth_factor);
}

}  // namespace cryptohome
