// Copyright 2021 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/cryptohome_key_loader.h"

#include <utility>

#include <base/logging.h>

using brillo::SecureBlob;
using hwsec::error::TPMError;
using hwsec::error::TPMErrorBase;
using hwsec::error::TPMRetryAction;
using hwsec_foundation::error::CreateError;
using hwsec_foundation::error::WrapError;
namespace cryptohome {

CryptohomeKeyLoader::CryptohomeKeyLoader(Tpm* tpm,
                                         Platform* platform,
                                         const base::FilePath& path)
    : tpm_(tpm), platform_(platform), cryptohome_key_path_(path) {}

bool CryptohomeKeyLoader::SaveCryptohomeKey(const SecureBlob& wrapped_key) {
  bool ok = platform_->WriteSecureBlobToFileAtomicDurable(cryptohome_key_path_,
                                                          wrapped_key, 0600);
  if (!ok)
    LOG(ERROR) << "Error writing key file of desired size: "
               << wrapped_key.size();
  return ok;
}

TPMErrorBase CryptohomeKeyLoader::LoadCryptohomeKey(
    ScopedKeyHandle* key_handle) {
  CHECK(key_handle);
  // First, try loading the key from the key file.
  SecureBlob raw_key;
  if (platform_->ReadFileToSecureBlob(cryptohome_key_path_, &raw_key)) {
    if (TPMErrorBase err = tpm_->LoadWrappedKey(raw_key, key_handle)) {
      if (err->ToTPMRetryAction() == TPMRetryAction::kNoRetry) {
        LOG(INFO) << "Using legacy upgrade path: " << *err;
        goto legacy_upgrade_path;
      }
      return WrapError<TPMError>(std::move(err), "Failed to load wrapped key");
    }
    return nullptr;
  }

legacy_upgrade_path:
  // Then try loading the key by the UUID (this is a legacy upgrade path).
  if (!tpm_->LegacyLoadCryptohomeKey(key_handle, &raw_key)) {
    return CreateError<TPMError>("Failed to load legacy cryptohome key",
                                 TPMRetryAction::kNoRetry);
  }

  // Save the legacy cryptohome key to the well-known location.
  if (!SaveCryptohomeKey(raw_key)) {
    return CreateError<TPMError>("Couldn't save legacy cryptohome key",
                                 TPMRetryAction::kNoRetry);
  }

  return nullptr;
}

bool CryptohomeKeyLoader::LoadOrCreateCryptohomeKey(
    ScopedKeyHandle* key_handle) {
  CHECK(key_handle);
  // Try to load the cryptohome key.
  if (TPMErrorBase err = LoadCryptohomeKey(key_handle)) {
    if (err->ToTPMRetryAction() == TPMRetryAction::kNoRetry) {
      // The key couldn't be loaded, and it wasn't due to a transient error,
      // so we must create the key.
      SecureBlob wrapped_key;
      if (CreateCryptohomeKey(&wrapped_key)) {
        if (!SaveCryptohomeKey(wrapped_key)) {
          LOG(ERROR) << "Couldn't save cryptohome key";
          return false;
        }
        LOG(INFO) << "Created new cryptohome key.";
        err = LoadCryptohomeKey(key_handle);
      }
    }
    if (err) {
      LOG(ERROR) << "Failed to load or create cryptohome key: " << *err;
      return false;
    }
  }
  return true;
}

bool CryptohomeKeyLoader::HasCryptohomeKey() {
  return cryptohome_key_.has_value();
}

TpmKeyHandle CryptohomeKeyLoader::GetCryptohomeKey() {
  return cryptohome_key_.value();
}

bool CryptohomeKeyLoader::ReloadCryptohomeKey() {
  CHECK(HasCryptohomeKey());
  // Release the handle first, we know this handle doesn't contain a loaded key
  // since ReloadCryptohomeKey only called after we failed to use it.
  // Otherwise we may flush the newly loaded key and fail to use it again,
  // if it is loaded to the same handle.
  // TODO(crbug.com/687330): change to closing the handle and ignoring errors
  // once checking for stale virtual handles is implemented in trunksd.
  cryptohome_key_.release();
  if (TPMErrorBase err = LoadCryptohomeKey(&cryptohome_key_)) {
    LOG(ERROR) << "Error reloading Cryptohome key: " << *err;
    return false;
  }
  return true;
}

void CryptohomeKeyLoader::Init() {
  if (!LoadOrCreateCryptohomeKey(&cryptohome_key_)) {
    LOG(ERROR) << __func__ << ": failed to load or create cryptohome key";
  }
}

}  // namespace cryptohome
