// Copyright 2017 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 "arc/setup/boot_lockbox_client.h"

#include <utility>
#include <vector>

#include <base/timer/elapsed_timer.h>
#include <cryptohome-client/cryptohome/dbus-proxies.h>
#include <cryptohome/proto_bindings/rpc.pb.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <dbus/dbus.h>

namespace arc {

std::unique_ptr<BootLockboxClient>
BootLockboxClient::CreateBootLockboxClient() {
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
  if (!bus->Connect()) {
    LOG(ERROR) << "D-Bus system bus is not ready";
    return nullptr;
  }

  auto cryptohome_proxy =
      std::make_unique<org::chromium::CryptohomeInterfaceProxy>(bus);

  return std::unique_ptr<BootLockboxClient>(
      new BootLockboxClient(std::move(cryptohome_proxy), bus));
}

BootLockboxClient::BootLockboxClient(
    std::unique_ptr<org::chromium::CryptohomeInterfaceProxyInterface>
        cryptohome,
    scoped_refptr<dbus::Bus> bus)
    : cryptohome_(std::move(cryptohome)), bus_(bus) {}

BootLockboxClient::~BootLockboxClient() {
  bus_->ShutdownAndBlock();
}

bool BootLockboxClient::IsServiceReady() {
  std::string owner = bus_->GetServiceOwnerAndBlock(
      cryptohome::kCryptohomeServiceName, dbus::Bus::SUPPRESS_ERRORS);
  return !owner.empty();
}

bool BootLockboxClient::IsTpmReady() {
  bool is_tpm_ready = false;
  brillo::ErrorPtr error;
  // Return false if call fails.
  if (!cryptohome_->TpmIsReady(&is_tpm_ready, &error)) {
    LOG(ERROR) << "Failed to call TpmIsReady, error: " << error->GetMessage();
    return false;
  }
  LOG(INFO) << "Is TPM ready: " << is_tpm_ready;
  return is_tpm_ready;
}

bool BootLockboxClient::Sign(const std::string& digest,
                             std::string* signature_out) {
  base::ElapsedTimer timer;
  cryptohome::SignBootLockboxRequest request;
  request.set_data(digest);
  std::vector<uint8_t> request_array(request.ByteSize());
  request.SerializeToArray(request_array.data(), request_array.size());

  std::vector<uint8_t> reply_array;
  brillo::ErrorPtr error;
  if (!cryptohome_->SignBootLockbox(request_array, &reply_array, &error)) {
    LOG(ERROR) << "Failed to call SignBootLockbox, error: "
               << error->GetMessage();
    return false;
  }

  cryptohome::BaseReply base_reply;
  if (!base_reply.ParseFromArray(reply_array.data(), reply_array.size())) {
    LOG(ERROR) << "Failed to parse SignBootLockboxReply";
    return false;
  }

  if (base_reply.has_error()) {
    LOG(ERROR) << "Failed to call Sign, error code: " << base_reply.error();
    return false;
  }

  if (!base_reply.HasExtension(cryptohome::SignBootLockboxReply::reply)) {
    LOG(ERROR) << "Missing reply field in SignBootLockboxReply";
    return false;
  }

  cryptohome::SignBootLockboxReply signature_reply =
      base_reply.GetExtension(cryptohome::SignBootLockboxReply::reply);
  if (!signature_reply.has_signature()) {
    LOG(ERROR) << "Missing signature in SignBootLockboxReply";
    return false;
  }
  *signature_out = signature_reply.signature();
  LOG(INFO) << "BootLockboxClient::Sign took "
            << timer.Elapsed().InMillisecondsRoundedUp() << "ms";
  return true;
}

bool BootLockboxClient::Verify(const std::string& digest,
                               const std::string& signature) {
  base::ElapsedTimer timer;
  cryptohome::VerifyBootLockboxRequest request;
  request.set_data(digest);
  request.set_signature(signature);
  std::vector<uint8_t> request_array(request.ByteSize());
  request.SerializeToArray(request_array.data(), request_array.size());

  std::vector<uint8_t> reply_array;
  brillo::ErrorPtr error;
  if (!cryptohome_->VerifyBootLockbox(request_array, &reply_array, &error)) {
    LOG(ERROR) << "Failed to call VerifyBootLockbox, " << error->GetMessage();
    return false;
  }

  cryptohome::BaseReply base_reply;
  if (!base_reply.ParseFromArray(reply_array.data(), reply_array.size())) {
    LOG(ERROR) << "Failed to parse VerifyBootLockbox reply message";
    return false;
  }

  if (base_reply.has_error()) {
    LOG(ERROR) << "Error calling VerifyBootLockbox, error code:"
               << base_reply.error();
    return false;
  }
  LOG(INFO) << "Verifing took " << timer.Elapsed().InMillisecondsRoundedUp()
            << "ms";
  return true;
}

bool BootLockboxClient::Finalize() {
  base::ElapsedTimer timer;
  cryptohome::FinalizeBootLockboxRequest request;
  std::vector<uint8_t> request_array(request.ByteSize());
  request.SerializeToArray(request_array.data(), request_array.size());

  std::vector<uint8_t> reply_array;
  brillo::ErrorPtr error;
  if (!cryptohome_->FinalizeBootLockbox(request_array, &reply_array, &error)) {
    LOG(ERROR) << "Failed to call FinalizeBootLockbox";
    return false;
  }

  cryptohome::BaseReply base_reply;
  if (!base_reply.ParseFromArray(reply_array.data(), reply_array.size())) {
    LOG(ERROR) << "Failed to parse FinalizeBootLockbox reply";
    return false;
  }

  if (base_reply.has_error()) {
    LOG(ERROR) << "Error calling FinalizeBootLockbox, error code: "
               << base_reply.error();
    return false;
  }
  LOG(INFO) << "Finalize took " << timer.Elapsed().InMillisecondsRoundedUp()
            << "ms";
  return true;
}

}  // namespace arc
