blob: 516482ceb32d1aa0c5f7a829a3f3e7560a2403d0 [file] [log] [blame]
// 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/bootlockbox/boot_lockbox_client.h"
#include <utility>
#include <vector>
#include <base/timer/elapsed_timer.h>
#include <brillo/glib/object.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>
// Note that boot_lockbox_rpc.pb.h have to be included before
// dbus_adaptors/org.chromium.BootLockboxInterface.h because it is used in
// there.
#include "bootlockbox/proto_bindings/boot_lockbox_rpc.pb.h"
#include "bootlockbox/dbus-proxies.h"
namespace cryptohome {
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 bootlockbox_proxy =
std::make_unique<org::chromium::BootLockboxInterfaceProxy>(bus);
return std::unique_ptr<BootLockboxClient>(
new BootLockboxClient(std::move(bootlockbox_proxy), bus));
}
BootLockboxClient::BootLockboxClient(
std::unique_ptr<org::chromium::BootLockboxInterfaceProxy> bootlockbox,
scoped_refptr<dbus::Bus> bus)
: bootlockbox_(std::move(bootlockbox)), bus_(bus) {}
BootLockboxClient::~BootLockboxClient() {
bus_->ShutdownAndBlock();
}
bool BootLockboxClient::Store(const std::string& key,
const std::string& digest) {
base::ElapsedTimer timer;
cryptohome::StoreBootLockboxRequest request;
request.set_key(key);
request.set_data(digest);
cryptohome::StoreBootLockboxReply reply;
brillo::ErrorPtr error;
if (!bootlockbox_->StoreBootLockbox(request, &reply, &error)) {
LOG(ERROR) << "Failed to call StoreBootLockbox, error: "
<< error->GetMessage();
return false;
}
if (reply.has_error()) {
LOG(ERROR) << "Failed to call Store, error code: " << reply.error();
return false;
}
VLOG(1) << "BootLockboxClient::Store took "
<< timer.Elapsed().InMillisecondsRoundedUp() << "ms";
return true;
}
bool BootLockboxClient::Read(const std::string& key, std::string* digest) {
base::ElapsedTimer timer;
cryptohome::ReadBootLockboxRequest request;
request.set_key(key);
cryptohome::ReadBootLockboxReply reply;
brillo::ErrorPtr error;
if (!bootlockbox_->ReadBootLockbox(request, &reply, &error)) {
LOG(ERROR) << "Failed to call ReadBootLockbox, error: "
<< error->GetMessage();
return false;
}
if (reply.has_error()) {
LOG(ERROR) << "Failed to call ReadBootLockbox, error code: "
<< reply.error();
return false;
}
if (!reply.has_data()) {
LOG(ERROR) << "Missing data field in ReadBootLockboxReply";
return false;
}
*digest = reply.data();
return true;
}
bool BootLockboxClient::Finalize() {
base::ElapsedTimer timer;
cryptohome::FinalizeNVRamBootLockboxRequest request;
cryptohome::FinalizeBootLockboxReply reply;
brillo::ErrorPtr error;
if (!bootlockbox_->FinalizeBootLockbox(request, &reply, &error)) {
LOG(ERROR) << "Failed to call FinalizeBootLockbox";
return false;
}
if (reply.has_error()) {
LOG(ERROR) << "Error calling FinalizeBootLockbox, error code: "
<< reply.error();
return false;
}
VLOG(1) << "BootLockboxClient::Finalize took "
<< timer.Elapsed().InMillisecondsRoundedUp() << "ms";
return true;
}
} // namespace cryptohome