// 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/key_challenge_service_impl.h"

#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <base/logging.h>
#include <base/time/time.h>
#include <brillo/errors/error.h>
#include <dbus/bus.h>
#include <google/protobuf/message_lite.h>

#include "cryptohome/error/location_utils.h"

using cryptohome::error::CryptohomeTPMError;
using cryptohome::error::ErrorAction;
using cryptohome::error::ErrorActionSet;
using hwsec::TPMRetryAction;
using hwsec_foundation::status::MakeStatus;
using hwsec_foundation::status::OkStatus;
using hwsec_foundation::status::StatusChain;

namespace cryptohome {

namespace {

// This is currently equal to the timeout used by the Chrome when making
// MountEx/CheckKeyEx calls to cryptohomed. (These timeouts are not technically
// required to be equal, but it's good from the UX perspective).
constexpr base::TimeDelta kDbusCallTimeout = base::Minutes(2);

// Used for holding OnceCallback when multiple callback function needs it, but
// only one of them will run. Note: This is not thread safe.
template <typename T>
class OnceCallbackHolder {
 public:
  explicit OnceCallbackHolder(T obj) : obj_(std::move(obj)) {}

  T get() {
    DCHECK(obj_.has_value());
    std::optional<T> res;
    std::swap(res, obj_);
    return std::move(res.value());
  }

 private:
  // The object that we are holding
  std::optional<T> obj_;
};

std::vector<uint8_t> SerializeProto(
    const google::protobuf::MessageLite& proto) {
  std::vector<uint8_t> serialized_proto(proto.ByteSizeLong());
  CHECK(
      proto.SerializeToArray(serialized_proto.data(), serialized_proto.size()));
  return serialized_proto;
}

bool DeserializeProto(const std::vector<uint8_t>& raw_buf,
                      google::protobuf::MessageLite* proto) {
  return proto->ParseFromArray(raw_buf.data(), raw_buf.size());
}

void OnDBusChallengeKeySuccess(
    std::shared_ptr<OnceCallbackHolder<KeyChallengeService::ResponseCallback>>
        callback_holder,
    const std::vector<uint8_t>& challenge_response) {
  KeyChallengeService::ResponseCallback original_callback =
      callback_holder->get();
  if (challenge_response.empty()) {
    // TODO(crbug.com/1046860): Remove the logging after stabilizing the
    // feature.
    LOG(INFO) << "Signature key challenge failed: empty response";
    std::move(original_callback)
        .Run(MakeStatus<CryptohomeTPMError>(
            CRYPTOHOME_ERR_LOC(
                kLocKeyChallengeServiceEmptyResponseInChallengeKey),
            ErrorActionSet(
                {ErrorAction::kDevCheckUnexpectedState, ErrorAction::kReboot}),
            TPMRetryAction::kNoRetry));
    return;
  }
  auto response_proto = std::make_unique<KeyChallengeResponse>();
  if (!DeserializeProto(challenge_response, response_proto.get())) {
    LOG(ERROR)
        << "Failed to parse KeyChallengeResponse from ChallengeKey D-Bus call";
    std::move(original_callback)
        .Run(MakeStatus<CryptohomeTPMError>(
            CRYPTOHOME_ERR_LOC(
                kLocKeyChallengeServiceParseFailedInChallengeKey),
            ErrorActionSet({ErrorAction::kDevCheckUnexpectedState}),
            TPMRetryAction::kNoRetry));
    return;
  }
  // TODO(crbug.com/1046860): Remove the logging after stabilizing the feature.
  if (response_proto->has_signature_response_data()) {
    LOG(INFO) << "Signature key challenge succeeded: signature size "
              << response_proto->signature_response_data().signature().size();
  } else {
    LOG(INFO) << "Key challenge completed with no signature";
  }
  std::move(original_callback).Run(std::move(response_proto));
}

void OnDBusChallengeKeyFailure(
    std::shared_ptr<OnceCallbackHolder<KeyChallengeService::ResponseCallback>>
        callback_holder,
    brillo::Error* error) {
  // TODO(crbug.com/1046860): Remove the logging after stabilizing the feature.
  TPMStatus status;
  if (error) {
    LOG(INFO) << "Signature key challenge failed: dbus error code "
              << error->GetCode() << ", message " << error->GetMessage();
    // TODO(b/230326115): Distinguish between user cancellation and actual
    // error.
    status = MakeStatus<CryptohomeTPMError>(
        CRYPTOHOME_ERR_LOC(kLocKeyChallengeServiceKnownDBusErrorInChallengeKey),
        ErrorActionSet({ErrorAction::kIncorrectAuth}),
        TPMRetryAction::kUserAuth);
  } else {
    LOG(INFO) << "Key challenge failed: unknown dbus error";
    status = MakeStatus<CryptohomeTPMError>(
        CRYPTOHOME_ERR_LOC(
            kLocKeyChallengeServiceUnknownDBusErrorInChallengeKey),
        ErrorActionSet(
            {ErrorAction::kDevCheckUnexpectedState, ErrorAction::kReboot}),
        TPMRetryAction::kNoRetry);
  }
  KeyChallengeService::ResponseCallback original_callback =
      callback_holder->get();
  std::move(original_callback).Run(std::move(status));
}

void OnDBusFidoMakeCredentialSuccess(
    std::shared_ptr<OnceCallbackHolder<
        KeyChallengeService::MakeCredentialCallback>> callback_holder,
    const std::vector<uint8_t>& make_credential_response) {
  KeyChallengeService::MakeCredentialCallback original_callback =
      callback_holder->get();

  if (make_credential_response.empty()) {
    std::move(original_callback).Run(nullptr /* response */);
    return;
  }
  auto response =
      std::make_unique<cryptohome::fido::MakeCredentialAuthenticatorResponse>();
  if (!DeserializeProto(make_credential_response, response.get())) {
    LOG(ERROR) << "Failed to parse MakeCredentialAuthenticatorResponse from "
               << "FidoMakeCredential D-Bus call";
    return;
  }
  std::move(original_callback).Run(std::move(response));
}

void OnDBusFidoMakeCredentialFailure(
    std::shared_ptr<OnceCallbackHolder<
        KeyChallengeService::MakeCredentialCallback>> callback_holder,
    brillo::Error* error) {
  LOG(ERROR) << error->GetMessage();
  KeyChallengeService::MakeCredentialCallback original_callback =
      callback_holder->get();
  std::move(original_callback).Run(nullptr /* response */);
}

void OnDBusFidoGetAssertionSuccess(
    std::shared_ptr<OnceCallbackHolder<
        KeyChallengeService::GetAssertionCallback>> callback_holder,
    const std::vector<uint8_t>& get_assertion_response) {
  KeyChallengeService::GetAssertionCallback original_callback =
      callback_holder->get();

  if (get_assertion_response.empty()) {
    std::move(original_callback).Run(nullptr /* response */);
    return;
  }

  auto response =
      std::make_unique<cryptohome::fido::GetAssertionAuthenticatorResponse>();
  if (!DeserializeProto(get_assertion_response, response.get())) {
    LOG(ERROR) << "Failed to parse GetAssertionAuthenticatorResponse from "
               << "FidoGetAssertion D-Bus call";
    return;
  }
  std::move(original_callback).Run(std::move(response));
}

void OnDBusFidoGetAssertionFailure(
    std::shared_ptr<OnceCallbackHolder<
        KeyChallengeService::GetAssertionCallback>> callback_holder,
    brillo::Error* error) {
  LOG(ERROR) << error->GetMessage();
  KeyChallengeService::GetAssertionCallback original_callback =
      callback_holder->get();
  std::move(original_callback).Run(nullptr /* response */);
}

}  // namespace

KeyChallengeServiceImpl::KeyChallengeServiceImpl(
    scoped_refptr<dbus::Bus> dbus_bus,
    const std::string& key_delegate_dbus_service_name)
    : key_delegate_dbus_service_name_(key_delegate_dbus_service_name),
      dbus_proxy_(dbus_bus, key_delegate_dbus_service_name_) {
  DCHECK(dbus_bus);
  DCHECK(!key_delegate_dbus_service_name_.empty());
}

KeyChallengeServiceImpl::~KeyChallengeServiceImpl() = default;

void KeyChallengeServiceImpl::ChallengeKey(
    const AccountIdentifier& account_id,
    const KeyChallengeRequest& key_challenge_request,
    ResponseCallback response_callback) {
  if (!dbus_validate_bus_name(key_delegate_dbus_service_name_.c_str(),
                              nullptr /* error */)) {
    // Bail out to avoid crashing inside the D-Bus library.
    // TODO(emaxx): Remove this special handling once libchrome is uprev'ed to
    // include the fix from crbug.com/927196.
    LOG(ERROR) << "Invalid key challenge service name "
               << key_delegate_dbus_service_name_;
    std::move(response_callback)
        .Run(MakeStatus<CryptohomeTPMError>(
            CRYPTOHOME_ERR_LOC(
                kLocKeyChallengeServiceInvalidDBusNameInChallengeKey),
            ErrorActionSet({ErrorAction::kDevCheckUnexpectedState}),
            TPMRetryAction::kNoRetry));
    return;
  }
  std::shared_ptr<OnceCallbackHolder<ResponseCallback>> callback_holder(
      new OnceCallbackHolder<ResponseCallback>(std::move(response_callback)));
  // TODO(crbug.com/1046860): Remove the logging after stabilizing the feature.
  if (key_challenge_request.has_signature_request_data()) {
    LOG(INFO)
        << "Starting signature key challenge request, size "
        << key_challenge_request.signature_request_data().data_to_sign().size()
        << ", spki size "
        << key_challenge_request.signature_request_data()
               .public_key_spki_der()
               .size()
        << ", algorithm "
        << key_challenge_request.signature_request_data().signature_algorithm();
  }
  dbus_proxy_.ChallengeKeyAsync(
      SerializeProto(account_id), SerializeProto(key_challenge_request),
      base::BindOnce(&OnDBusChallengeKeySuccess, callback_holder),
      base::BindOnce(&OnDBusChallengeKeyFailure, callback_holder),
      /*timeout_ms=*/kDbusCallTimeout.InMilliseconds());
}

void KeyChallengeServiceImpl::FidoMakeCredential(
    const std::string& client_data_json,
    const cryptohome::fido::PublicKeyCredentialCreationOptions& request,
    MakeCredentialCallback response_callback) {
  if (!dbus_validate_bus_name(key_delegate_dbus_service_name_.c_str(),
                              nullptr /* error */)) {
    LOG(ERROR) << "Invalid key challenge service name "
               << key_delegate_dbus_service_name_;
    std::move(response_callback).Run(nullptr /* response */);
    return;
  }

  std::shared_ptr<OnceCallbackHolder<MakeCredentialCallback>> callback_holder(
      new OnceCallbackHolder<MakeCredentialCallback>(
          std::move(response_callback)));
  dbus_proxy_.FidoMakeCredentialAsync(
      client_data_json, SerializeProto(request),
      base::BindOnce(&OnDBusFidoMakeCredentialSuccess, callback_holder),
      base::BindOnce(&OnDBusFidoMakeCredentialFailure, callback_holder));
}

void KeyChallengeServiceImpl::FidoGetAssertion(
    const std::string& client_data_json,
    const cryptohome::fido::PublicKeyCredentialRequestOptions& request,
    GetAssertionCallback response_callback) {
  if (!dbus_validate_bus_name(key_delegate_dbus_service_name_.c_str(),
                              nullptr)) {
    LOG(ERROR) << "Invalid key challenge service name "
               << key_delegate_dbus_service_name_;
    std::move(response_callback).Run(nullptr /* response */);
    return;
  }

  std::shared_ptr<OnceCallbackHolder<GetAssertionCallback>> callback_holder(
      new OnceCallbackHolder<GetAssertionCallback>(
          std::move(response_callback)));
  dbus_proxy_.FidoGetAssertionAsync(
      client_data_json, SerializeProto(request),
      base::BindOnce(&OnDBusFidoGetAssertionSuccess, callback_holder),
      base::BindOnce(&OnDBusFidoGetAssertionFailure, callback_holder));
}

}  // namespace cryptohome
