// Copyright 2018 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/challenge_credentials/challenge_credentials_helper_impl.h"

#include <utility>

#include <base/bind.h>
#include <base/check.h>
#include <base/check_op.h>
#include <base/logging.h>
#include <libhwsec/status.h>

#include "cryptohome/challenge_credentials/challenge_credentials_decrypt_operation.h"
#include "cryptohome/challenge_credentials/challenge_credentials_generate_new_operation.h"
#include "cryptohome/challenge_credentials/challenge_credentials_operation.h"
#include "cryptohome/challenge_credentials/challenge_credentials_verify_key_operation.h"
#include "cryptohome/key_challenge_service.h"
#include "cryptohome/signature_sealing_backend.h"

using brillo::Blob;
using cryptohome::error::CryptohomeTPMError;
using hwsec::TPMError;
using hwsec::TPMErrorBase;
using hwsec::TPMRetryAction;
using hwsec_foundation::error::CreateError;
using hwsec_foundation::error::WrapError;
using hwsec_foundation::status::StatusChain;

namespace cryptohome {

namespace {

bool IsOperationFailureTransient(
    const StatusChain<CryptohomeTPMError>& status) {
  TPMRetryAction action = status->ToTPMRetryAction();
  return action == TPMRetryAction::kCommunication ||
         action == TPMRetryAction::kLater;
}

}  // namespace

ChallengeCredentialsHelperImpl::ChallengeCredentialsHelperImpl(
    Tpm* tpm, const Blob& delegate_blob, const Blob& delegate_secret)
    : tpm_(tpm),
      delegate_blob_(delegate_blob),
      delegate_secret_(delegate_secret) {
  DCHECK(tpm_);
}

ChallengeCredentialsHelperImpl::~ChallengeCredentialsHelperImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

void ChallengeCredentialsHelperImpl::GenerateNew(
    const std::string& account_id,
    const structure::ChallengePublicKeyInfo& public_key_info,
    const std::string& obfuscated_username,
    std::unique_ptr<KeyChallengeService> key_challenge_service,
    GenerateNewCallback callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());
  CancelRunningOperation();
  key_challenge_service_ = std::move(key_challenge_service);
  operation_ = std::make_unique<ChallengeCredentialsGenerateNewOperation>(
      key_challenge_service_.get(), tpm_, delegate_blob_, delegate_secret_,
      account_id, public_key_info, obfuscated_username,
      base::BindOnce(&ChallengeCredentialsHelperImpl::OnGenerateNewCompleted,
                     base::Unretained(this), std::move(callback)));
  operation_->Start();
}

void ChallengeCredentialsHelperImpl::Decrypt(
    const std::string& account_id,
    const structure::ChallengePublicKeyInfo& public_key_info,
    const structure::SignatureChallengeInfo& keyset_challenge_info,
    bool locked_to_single_user,
    std::unique_ptr<KeyChallengeService> key_challenge_service,
    DecryptCallback callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());
  CancelRunningOperation();
  key_challenge_service_ = std::move(key_challenge_service);
  StartDecryptOperation(account_id, public_key_info, keyset_challenge_info,
                        locked_to_single_user, 1 /* attempt_number */,
                        std::move(callback));
}

void ChallengeCredentialsHelperImpl::VerifyKey(
    const std::string& account_id,
    const structure::ChallengePublicKeyInfo& public_key_info,
    std::unique_ptr<KeyChallengeService> key_challenge_service,
    VerifyKeyCallback callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(!callback.is_null());
  CancelRunningOperation();
  key_challenge_service_ = std::move(key_challenge_service);
  operation_ = std::make_unique<ChallengeCredentialsVerifyKeyOperation>(
      key_challenge_service_.get(), tpm_, account_id, public_key_info,
      base::BindOnce(&ChallengeCredentialsHelperImpl::OnVerifyKeyCompleted,
                     base::Unretained(this), std::move(callback)));
  operation_->Start();
}

void ChallengeCredentialsHelperImpl::StartDecryptOperation(
    const std::string& account_id,
    const structure::ChallengePublicKeyInfo& public_key_info,
    const structure::SignatureChallengeInfo& keyset_challenge_info,
    bool locked_to_single_user,
    int attempt_number,
    DecryptCallback callback) {
  DCHECK(!operation_);
  operation_ = std::make_unique<ChallengeCredentialsDecryptOperation>(
      key_challenge_service_.get(), tpm_, delegate_blob_, delegate_secret_,
      account_id, public_key_info, keyset_challenge_info, locked_to_single_user,
      base::BindOnce(&ChallengeCredentialsHelperImpl::OnDecryptCompleted,
                     base::Unretained(this), account_id, public_key_info,
                     keyset_challenge_info, locked_to_single_user,
                     attempt_number, std::move(callback)));
  operation_->Start();
}

void ChallengeCredentialsHelperImpl::CancelRunningOperation() {
  // Destroy the previous Operation before instantiating a new one, to keep the
  // resource usage constrained (for example, there must be only one instance of
  // SignatureSealingBackend::UnsealingSession at a time).
  if (operation_) {
    DLOG(INFO) << "Cancelling an old challenge-response credentials operation";
    operation_->Abort();
    operation_.reset();
    // It's illegal for the consumer code to request a new operation in
    // immediate response to completion of a previous one.
    DCHECK(!operation_);
  }
}

void ChallengeCredentialsHelperImpl::OnGenerateNewCompleted(
    GenerateNewCallback original_callback,
    std::unique_ptr<structure::SignatureChallengeInfo> signature_challenge_info,
    std::unique_ptr<brillo::SecureBlob> passkey) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CancelRunningOperation();
  std::move(original_callback)
      .Run(std::move(signature_challenge_info), std::move(passkey));
}

void ChallengeCredentialsHelperImpl::OnDecryptCompleted(
    const std::string& account_id,
    const structure::ChallengePublicKeyInfo& public_key_info,
    const structure::SignatureChallengeInfo& keyset_challenge_info,
    bool locked_to_single_user,
    int attempt_number,
    DecryptCallback original_callback,
    StatusChain<CryptohomeTPMError> status,
    std::unique_ptr<brillo::SecureBlob> passkey) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(passkey == nullptr, !status.ok());
  CancelRunningOperation();
  if (!status.ok() && IsOperationFailureTransient(status) &&
      attempt_number < kRetryAttemptCount) {
    LOG(WARNING) << "Retrying the decryption operation after transient error: "
                 << status;
    StartDecryptOperation(account_id, public_key_info, keyset_challenge_info,
                          locked_to_single_user, attempt_number + 1,
                          std::move(original_callback));
  } else {
    if (!status.ok()) {
      LOG(ERROR) << "Decryption completed with error: " << status;
    }
    std::move(original_callback).Run(std::move(passkey));
  }
}

void ChallengeCredentialsHelperImpl::OnVerifyKeyCompleted(
    VerifyKeyCallback original_callback, bool is_key_valid) {
  DCHECK(thread_checker_.CalledOnValidThread());
  CancelRunningOperation();
  std::move(original_callback).Run(is_key_valid);
}

}  // namespace cryptohome
