// 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 <brillo/glib/object.h>
#include <cryptohome-client/cryptohome/dbus-proxies.h>
#include <cryptohome/proto_bindings/rpc.pb.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>  // NOLINT - sort not stable

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
