// Copyright 2019 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 "tpm_softclear_utils/tpm2_impl.h"

#include <memory>
#include <string>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/optional.h>
#include <tpm_manager/proto_bindings/tpm_manager.pb.h>
#include <trunks/authorization_delegate.h>
#include <trunks/error_codes.h>
#include <trunks/tpm_generated.h>
#include <trunks/tpm_state.h>
#include <trunks/trunks_factory_impl.h>

namespace tpm_softclear_utils {

bool Tpm2Impl::Initialize() {
  if (!default_trunks_factory_.Initialize()) {
    LOG(ERROR) << __func__ << ": failed to initialize trunks factory.";
    return false;
  }

  trunks_factory_ = &default_trunks_factory_;
  return true;
}

base::Optional<std::string> Tpm2Impl::GetAuthForOwnerReset() {
  if (!trunks_factory_) {
    LOG(ERROR) << __func__ << ": trunks factory is uninitialized.";
    return {};
  }

  std::unique_ptr<trunks::TpmState> trunks_tpm_state =
      trunks_factory_->GetTpmState();
  trunks::TPM_RC result = trunks_tpm_state->Initialize();
  if (result) {
    LOG(ERROR) << __func__ << ": failed to initialize trunks tpm state: "
               << trunks::GetErrorString(result);
    return {};
  }

  if (!trunks_tpm_state->IsLockoutPasswordSet()) {
    // If the lockout password is not set in the TPM, we should not trust the
    // local data but use the default password instead.
    return std::string(kDefaultLockoutPassword);
  }

  std::string raw_data;
  if (!ReadFileToString(local_data_path_, &raw_data)) {
    // This covers both the cases of local data file not existing and failing to
    // read that file. The local data file should exist if the lockout password
    // is set.
    LOG(ERROR) << __func__
               << " : failed to read file " << local_data_path_.value();
    return {};
  }

  tpm_manager::LocalData local_data;
  if (!local_data.ParseFromString(raw_data)) {
    LOG(ERROR) << __func__
               << ": failed to parse local data file into protobuf.";
    return {};
  }

  return local_data.lockout_password();
}

bool Tpm2Impl::SoftClearOwner(const std::string& auth_for_owner_reset) {
  if (!trunks_factory_) {
    LOG(ERROR) << __func__ << ": trunks factory is uninitialized.";
    return {};
  }
  LOG(INFO) << "Start soft-clearing TPM 2.0";

  std::unique_ptr<trunks::AuthorizationDelegate> lockout_password_delegate(
      trunks_factory_->GetPasswordAuthorization(auth_for_owner_reset));

  std::string lockout_handle_name;
  trunks::TPM_RC result = trunks::Serialize_TPM_HANDLE(
      trunks::TPM_RH_LOCKOUT, &lockout_handle_name);
  if (result != trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": failed to serialize TPM lockout handle: "
               << trunks::GetErrorString(result);
    return false;
  }

  result = trunks_factory_->GetTpm()->ClearSync(
      trunks::TPM_RH_LOCKOUT,
      lockout_handle_name,
      lockout_password_delegate.get());
  if (result != trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << __func__ << ": failed to clear the TPM: "
               << trunks::GetErrorString(result);
    return false;
  }

  return true;
}

}  // namespace tpm_softclear_utils
