// Copyright (c) 2011 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 "chaps/chaps_proxy.h"

#include <base/logging.h>

#include "chaps/chaps.h"
#include "chaps/chaps_utility.h"
#include "chaps/isolate.h"
#include "pkcs11/cryptoki.h"

using base::AutoLock;
using std::string;
using std::vector;
using chromeos::SecureBlob;

namespace chaps {

ChapsProxyImpl::ChapsProxyImpl() {}

ChapsProxyImpl::~ChapsProxyImpl() {}

bool ChapsProxyImpl::Init() {
  try {
    if (!DBus::default_dispatcher)
      DBus::default_dispatcher = new DBus::BusDispatcher();
    if (!proxy_.get()) {
      // Establish a D-Bus connection.
      DBus::Connection connection = DBus::Connection::SystemBus();
      // Set the timeout to 5 minutes; some TPM operations can take long.  In
      // practice, calls have been noted to take more than 1 minute.
      connection.set_timeout(300000);
      proxy_.reset(new Proxy(connection, kChapsServicePath,
                             kChapsServiceName));
    }
    if (proxy_.get()) {
      if (!WaitForService())
        return false;
      VLOG(1) << "Chaps proxy initialized (" << kChapsServicePath << ").";
      return true;
    }
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return false;
}

bool ChapsProxyImpl::OpenIsolate(SecureBlob* isolate_credential,
                                 bool* new_isolate_created) {
  AutoLock lock(lock_);
  bool result = false;
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return false;
  }
  try {
    SecureBlob isolate_credential_in;
    SecureBlob isolate_credential_out;
    isolate_credential_in.swap(*isolate_credential);
    proxy_->OpenIsolate(isolate_credential_in, isolate_credential_out,
                        *new_isolate_created, result);
    isolate_credential->swap(isolate_credential_out);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
    result = false;
  }
  return result;
}

void ChapsProxyImpl::CloseIsolate(const SecureBlob& isolate_credential) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return;
  }
  try {
    proxy_->CloseIsolate(isolate_credential);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

bool ChapsProxyImpl::LoadToken(const SecureBlob& isolate_credential,
                               const string& path,
                               const vector<uint8_t>& auth_data,
                               const string& label,
                               uint64_t* slot_id) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return false;
  }
  bool result = false;;
  try {
    proxy_->LoadToken(isolate_credential,
                      path,
                      auth_data,
                      label,
                      *slot_id,
                      result);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
    result = false;
  }
  return result;
}

void ChapsProxyImpl::UnloadToken(const SecureBlob& isolate_credential,
                                 const string& path) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return;
  }
  try {
    proxy_->UnloadToken(isolate_credential, path);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

void ChapsProxyImpl::ChangeTokenAuthData(const string& path,
                                         const vector<uint8_t>& old_auth_data,
                                         const vector<uint8_t>& new_auth_data) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return;
  }
  try {
    proxy_->ChangeTokenAuthData(path, old_auth_data, new_auth_data);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

bool ChapsProxyImpl::GetTokenPath(const SecureBlob& isolate_credential,
                                  uint64_t slot_id,
                                  string* path) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << __func__ << ": Proxy not initialized.";
    return false;
  }
  bool result = false;;
  try {
    proxy_->GetTokenPath(isolate_credential, slot_id, *path, result);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
    result = false;
  }
  return result;
}

void ChapsProxyImpl::SetLogLevel(const int32_t& level) {
  AutoLock lock(lock_);
  if (!proxy_.get()) {
    LOG(ERROR) << "Failed to set logging level: proxy not initialized.";
    return;
  }
  try {
    proxy_->SetLogLevel(level);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::GetSlotList(const SecureBlob& isolate_credential,
                                     bool token_present,
                                     vector<uint64_t>* slot_list) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!slot_list, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetSlotList(isolate_credential, token_present, *slot_list, result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetSlotInfo(const SecureBlob& isolate_credential,
                                     uint64_t slot_id,
                                     vector<uint8_t>* slot_description,
                                     vector<uint8_t>* manufacturer_id,
                                     uint64_t* flags,
                                     uint8_t* hardware_version_major,
                                     uint8_t* hardware_version_minor,
                                     uint8_t* firmware_version_major,
                                     uint8_t* firmware_version_minor) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  if (!slot_description || !manufacturer_id || !flags ||
      !hardware_version_major || !hardware_version_minor ||
      !firmware_version_major || !firmware_version_minor)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetSlotInfo(isolate_credential,
                        slot_id,
                        *slot_description,
                        *manufacturer_id,
                        *flags,
                        *hardware_version_major,
                        *hardware_version_minor,
                        *firmware_version_major,
                        *firmware_version_minor,
                        result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetTokenInfo(const SecureBlob& isolate_credential,
                                      uint64_t slot_id,
                                      vector<uint8_t>* label,
                                      vector<uint8_t>* manufacturer_id,
                                      vector<uint8_t>* model,
                                      vector<uint8_t>* serial_number,
                                      uint64_t* flags,
                                      uint64_t* max_session_count,
                                      uint64_t* session_count,
                                      uint64_t* max_session_count_rw,
                                      uint64_t* session_count_rw,
                                      uint64_t* max_pin_len,
                                      uint64_t* min_pin_len,
                                      uint64_t* total_public_memory,
                                      uint64_t* free_public_memory,
                                      uint64_t* total_private_memory,
                                      uint64_t* free_private_memory,
                                      uint8_t* hardware_version_major,
                                      uint8_t* hardware_version_minor,
                                      uint8_t* firmware_version_major,
                                      uint8_t* firmware_version_minor) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  if (!label || !manufacturer_id || !model || !serial_number || !flags ||
      !max_session_count || !session_count || !max_session_count_rw ||
      !session_count_rw || !max_pin_len || !min_pin_len ||
      !total_public_memory || !free_public_memory || !total_private_memory ||
      !total_public_memory ||
      !hardware_version_major || !hardware_version_minor ||
      !firmware_version_major || !firmware_version_minor)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetTokenInfo(isolate_credential,
                         slot_id,
                         *label,
                         *manufacturer_id,
                         *model,
                         *serial_number,
                         *flags,
                         *max_session_count,
                         *session_count,
                         *max_session_count_rw,
                         *session_count_rw,
                         *max_pin_len,
                         *min_pin_len,
                         *total_public_memory,
                         *free_public_memory,
                         *total_private_memory,
                         *free_private_memory,
                         *hardware_version_major,
                         *hardware_version_minor,
                         *firmware_version_major,
                         *firmware_version_minor,
                         result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetMechanismList(
    const SecureBlob& isolate_credential,
    uint64_t slot_id,
    vector<uint64_t>* mechanism_list) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!mechanism_list, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetMechanismList(isolate_credential, slot_id, *mechanism_list,
                             result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetMechanismInfo(const SecureBlob& isolate_credential,
                                          uint64_t slot_id,
                                          uint64_t mechanism_type,
                                          uint64_t* min_key_size,
                                          uint64_t* max_key_size,
                                          uint64_t* flags) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  if (!min_key_size || !max_key_size || !flags)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetMechanismInfo(isolate_credential,
                             slot_id,
                             mechanism_type,
                             *min_key_size,
                             *max_key_size,
                             *flags,
                             result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::InitToken(const SecureBlob& isolate_credential,
                                   uint64_t slot_id,
                                   const string* so_pin,
                                   const vector<uint8_t>& label) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    string tmp_pin;
    if (so_pin)
      tmp_pin = *so_pin;
    result = proxy_->InitToken(isolate_credential, slot_id, (so_pin == NULL),
                               tmp_pin, label);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::InitPIN(const SecureBlob& isolate_credential,
                                 uint64_t session_id, const string* pin) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    string tmp_pin;
    if (pin)
      tmp_pin = *pin;
    result = proxy_->InitPIN(isolate_credential, session_id, (pin == NULL),
                             tmp_pin);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SetPIN(const SecureBlob& isolate_credential,
                                uint64_t session_id,
                                const string* old_pin,
                                const string* new_pin) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    string tmp_old_pin;
    if (old_pin)
      tmp_old_pin = *old_pin;
    string tmp_new_pin;
    if (new_pin)
      tmp_new_pin = *new_pin;
    result = proxy_->SetPIN(isolate_credential, session_id, (old_pin == NULL),
                            tmp_old_pin, (new_pin == NULL), tmp_new_pin);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::OpenSession(const SecureBlob& isolate_credential,
                                     uint64_t slot_id, uint64_t flags,
                                     uint64_t* session_id) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!session_id, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->OpenSession(isolate_credential, slot_id, flags, *session_id,
                        result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::CloseSession(const SecureBlob& isolate_credential,
                                      uint64_t session_id) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->CloseSession(isolate_credential, session_id);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::CloseAllSessions(const SecureBlob& isolate_credential,
                                          uint64_t slot_id) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->CloseAllSessions(isolate_credential, slot_id);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetSessionInfo(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        uint64_t* slot_id,
                                        uint64_t* state,
                                        uint64_t* flags,
                                        uint64_t* device_error) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  if (!slot_id || !state || !flags || !device_error)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetSessionInfo(isolate_credential, session_id, *slot_id, *state,
                           *flags, *device_error, result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetOperationState(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           vector<uint8_t>* operation_state) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!operation_state, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetOperationState(isolate_credential, session_id, *operation_state,
                              result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SetOperationState(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& operation_state,
    uint64_t encryption_key_handle,
    uint64_t authentication_key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SetOperationState(isolate_credential,
                                       session_id,
                                       operation_state,
                                       encryption_key_handle,
                                       authentication_key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Login(const SecureBlob& isolate_credential,
                               uint64_t session_id,
                               uint64_t user_type,
                               const string* pin) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    string tmp_pin;
    if (pin)
      tmp_pin = *pin;
    result = proxy_->Login(isolate_credential, session_id, user_type,
                           (pin == NULL), tmp_pin);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Logout(const SecureBlob& isolate_credential,
                                uint64_t session_id) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->Logout(isolate_credential, session_id);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::CreateObject(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& attributes,
                                      uint64_t* new_object_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->CreateObject(isolate_credential,
                         session_id,
                         attributes,
                         *new_object_handle,
                         result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::CopyObject(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    uint64_t object_handle,
                                    const vector<uint8_t>& attributes,
                                    uint64_t* new_object_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->CopyObject(isolate_credential,
                       session_id,
                       object_handle,
                       attributes,
                       *new_object_handle,
                       result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DestroyObject(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t object_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->DestroyObject(isolate_credential, session_id,
                                   object_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetObjectSize(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t object_handle,
                                       uint64_t* object_size) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!object_size, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetObjectSize(isolate_credential, session_id, object_handle,
                          *object_size, result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GetAttributeValue(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           uint64_t object_handle,
                                           const vector<uint8_t>& attributes_in,
                                           vector<uint8_t>* attributes_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!attributes_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GetAttributeValue(isolate_credential,
                              session_id,
                              object_handle,
                              attributes_in,
                              *attributes_out,
                              result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SetAttributeValue(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           uint64_t object_handle,
                                           const vector<uint8_t>& attributes) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SetAttributeValue(isolate_credential,
                                       session_id,
                                       object_handle,
                                       attributes);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::FindObjectsInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& attributes) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->FindObjectsInit(isolate_credential, session_id,
                                     attributes);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::FindObjects(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t max_object_count,
                                     vector<uint64_t>* object_list) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  if (!object_list || object_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->FindObjects(isolate_credential, session_id, max_object_count,
                        *object_list, result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::FindObjectsFinal(const SecureBlob& isolate_credential,
                                          uint64_t session_id) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->FindObjectsFinal(isolate_credential, session_id);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::EncryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->EncryptInit(isolate_credential,
                                 session_id,
                                 mechanism_type,
                                 mechanism_parameter,
                                 key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Encrypt(const SecureBlob& isolate_credential,
                                 uint64_t session_id,
                                 const vector<uint8_t>& data_in,
                                 uint64_t max_out_length,
                                 uint64_t* actual_out_length,
                                 vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->Encrypt(isolate_credential,
                    session_id,
                    data_in,
                    max_out_length,
                    *actual_out_length,
                    *data_out,
                    result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::EncryptUpdate(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       const vector<uint8_t>& data_in,
                                       uint64_t max_out_length,
                                       uint64_t* actual_out_length,
                                       vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->EncryptUpdate(isolate_credential,
                          session_id,
                          data_in,
                          max_out_length,
                          *actual_out_length,
                          *data_out,
                          result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::EncryptFinal(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      uint64_t max_out_length,
                                      uint64_t* actual_out_length,
                                      vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->EncryptFinal(isolate_credential,
                         session_id,
                         max_out_length,
                         *actual_out_length,
                         *data_out,
                         result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

void ChapsProxyImpl::EncryptCancel(const SecureBlob& isolate_credential,
                                   uint64_t session_id) {
  AutoLock lock(lock_);
  if (!proxy_.get())
    return;
  try {
    proxy_->EncryptCancel(isolate_credential, session_id);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::DecryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->DecryptInit(isolate_credential,
                                 session_id,
                                 mechanism_type,
                                 mechanism_parameter,
                                 key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Decrypt(const SecureBlob& isolate_credential,
                                 uint64_t session_id,
                                 const vector<uint8_t>& data_in,
                                 uint64_t max_out_length,
                                 uint64_t* actual_out_length,
                                 vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->Decrypt(isolate_credential,
                    session_id,
                    data_in,
                    max_out_length,
                    *actual_out_length,
                    *data_out,
                    result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DecryptUpdate(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       const vector<uint8_t>& data_in,
                                       uint64_t max_out_length,
                                       uint64_t* actual_out_length,
                                       vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DecryptUpdate(isolate_credential,
                          session_id,
                          data_in,
                          max_out_length,
                          *actual_out_length,
                          *data_out,
                          result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DecryptFinal(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      uint64_t max_out_length,
                                      uint64_t* actual_out_length,
                                      vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DecryptFinal(isolate_credential,
                         session_id,
                         max_out_length,
                         *actual_out_length,
                         *data_out,
                         result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

void ChapsProxyImpl::DecryptCancel(const SecureBlob& isolate_credential,
                                   uint64_t session_id) {
  AutoLock lock(lock_);
  if (!proxy_.get())
    return;
  try {
    proxy_->DecryptCancel(isolate_credential, session_id);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::DigestInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->DigestInit(isolate_credential,
                                session_id,
                                mechanism_type,
                                mechanism_parameter);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Digest(const SecureBlob& isolate_credential,
                                uint64_t session_id,
                                const vector<uint8_t>& data_in,
                                uint64_t max_out_length,
                                uint64_t* actual_out_length,
                                vector<uint8_t>* digest) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->Digest(isolate_credential,
                   session_id,
                   data_in,
                   max_out_length,
                   *actual_out_length,
                   *digest,
                   result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DigestUpdate(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data_in) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->DigestUpdate(isolate_credential, session_id, data_in);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DigestKey(const SecureBlob& isolate_credential,
                                   uint64_t session_id,
                                   uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->DigestKey(isolate_credential, session_id, key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DigestFinal(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t max_out_length,
                                     uint64_t* actual_out_length,
                                     vector<uint8_t>* digest) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DigestFinal(isolate_credential,
                        session_id,
                        max_out_length,
                        *actual_out_length,
                        *digest,
                        result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

void ChapsProxyImpl::DigestCancel(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  AutoLock lock(lock_);
  if (!proxy_.get())
    return;
  try {
    proxy_->DigestCancel(isolate_credential, session_id);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::SignInit(const SecureBlob& isolate_credential,
                                  uint64_t session_id,
                                  uint64_t mechanism_type,
                                  const vector<uint8_t>& mechanism_parameter,
                                  uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SignInit(isolate_credential,
                              session_id,
                              mechanism_type,
                              mechanism_parameter,
                              key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Sign(const SecureBlob& isolate_credential,
                              uint64_t session_id,
                              const vector<uint8_t>& data,
                              uint64_t max_out_length,
                              uint64_t* actual_out_length,
                              vector<uint8_t>* signature) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->Sign(isolate_credential,
                 session_id,
                 data,
                 max_out_length,
                 *actual_out_length,
                 *signature,
                 result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SignUpdate(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    const vector<uint8_t>& data_part) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SignUpdate(isolate_credential, session_id, data_part);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SignFinal(const SecureBlob& isolate_credential,
                                   uint64_t session_id,
                                   uint64_t max_out_length,
                                   uint64_t* actual_out_length,
                                   vector<uint8_t>* signature) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->SignFinal(isolate_credential,
                      session_id,
                      max_out_length,
                      *actual_out_length,
                      *signature,
                      result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

void ChapsProxyImpl::SignCancel(const SecureBlob& isolate_credential,
                                uint64_t session_id) {
  AutoLock lock(lock_);
  if (!proxy_.get())
    return;
  try {
    proxy_->SignCancel(isolate_credential, session_id);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::SignRecoverInit(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SignRecoverInit(isolate_credential,
                                     session_id,
                                     mechanism_type,
                                     mechanism_parameter,
                                     key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SignRecover(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     const vector<uint8_t>& data,
                                     uint64_t max_out_length,
                                     uint64_t* actual_out_length,
                                     vector<uint8_t>* signature) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->SignRecover(isolate_credential,
                        session_id,
                        data,
                        max_out_length,
                        *actual_out_length,
                        *signature,
                        result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::VerifyInit(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    uint64_t mechanism_type,
                                    const vector<uint8_t>& mechanism_parameter,
                                    uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->VerifyInit(isolate_credential,
                                session_id,
                                mechanism_type,
                                mechanism_parameter,
                                key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::Verify(const SecureBlob& isolate_credential,
                                uint64_t session_id,
                                const vector<uint8_t>& data,
                                const vector<uint8_t>& signature) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->Verify(isolate_credential, session_id, data, signature);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::VerifyUpdate(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data_part) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->VerifyUpdate(isolate_credential, session_id, data_part);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::VerifyFinal(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     const vector<uint8_t>& signature) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->VerifyFinal(isolate_credential, session_id, signature);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

void ChapsProxyImpl::VerifyCancel(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  AutoLock lock(lock_);
  if (!proxy_.get())
    return;
  try {
    proxy_->VerifyCancel(isolate_credential, session_id);
  } catch (DBus::Error err) {
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
}

uint32_t ChapsProxyImpl::VerifyRecoverInit(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      uint64_t key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->VerifyRecoverInit(isolate_credential,
                                       session_id,
                                       mechanism_type,
                                       mechanism_parameter,
                                       key_handle);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::VerifyRecover(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       const vector<uint8_t>& signature,
                                       uint64_t max_out_length,
                                       uint64_t* actual_out_length,
                                       vector<uint8_t>* data) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->VerifyRecover(isolate_credential,
                          session_id,
                          signature,
                          max_out_length,
                          *actual_out_length,
                          *data,
                          result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DigestEncryptUpdate(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DigestEncryptUpdate(isolate_credential,
                                session_id,
                                data_in,
                                max_out_length,
                                *actual_out_length,
                                *data_out,
                                result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DecryptDigestUpdate(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DecryptDigestUpdate(isolate_credential,
                                session_id,
                                data_in,
                                max_out_length,
                                *actual_out_length,
                                *data_out,
                                result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SignEncryptUpdate(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           const vector<uint8_t>& data_in,
                                           uint64_t max_out_length,
                                           uint64_t* actual_out_length,
                                           vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->SignEncryptUpdate(isolate_credential,
                              session_id,
                              data_in,
                              max_out_length,
                              *actual_out_length,
                              *data_out,
                              result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DecryptVerifyUpdate(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& data_in,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* data_out) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DecryptVerifyUpdate(isolate_credential,
                                session_id,
                                data_in,
                                max_out_length,
                                *actual_out_length,
                                *data_out,
                                result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GenerateKey(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& attributes,
    uint64_t* key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GenerateKey(isolate_credential,
                        session_id,
                        mechanism_type,
                        mechanism_parameter,
                        attributes,
                        *key_handle,
                        result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GenerateKeyPair(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    const vector<uint8_t>& public_attributes,
    const vector<uint8_t>& private_attributes,
    uint64_t* public_key_handle,
    uint64_t* private_key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!public_key_handle || !private_key_handle,
                          CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GenerateKeyPair(isolate_credential,
                            session_id,
                            mechanism_type,
                            mechanism_parameter,
                            public_attributes,
                            private_attributes,
                            *public_key_handle,
                            *private_key_handle,
                            result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::WrapKey(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t wrapping_key_handle,
    uint64_t key_handle,
    uint64_t max_out_length,
    uint64_t* actual_out_length,
    vector<uint8_t>* wrapped_key) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !wrapped_key,
                          CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->WrapKey(isolate_credential,
                    session_id,
                    mechanism_type,
                    mechanism_parameter,
                    wrapping_key_handle,
                    key_handle,
                    max_out_length,
                    *actual_out_length,
                    *wrapped_key,
                    result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::UnwrapKey(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t wrapping_key_handle,
    const vector<uint8_t>& wrapped_key,
    const vector<uint8_t>& attributes,
    uint64_t* key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->UnwrapKey(isolate_credential,
                      session_id,
                      mechanism_type,
                      mechanism_parameter,
                      wrapping_key_handle,
                      wrapped_key,
                      attributes,
                      *key_handle,
                      result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::DeriveKey(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t base_key_handle,
    const vector<uint8_t>& attributes,
    uint64_t* key_handle) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->DeriveKey(isolate_credential,
                      session_id,
                      mechanism_type,
                      mechanism_parameter,
                      base_key_handle,
                      attributes,
                      *key_handle,
                      result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::SeedRandom(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    const vector<uint8_t>& seed) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(seed.size() == 0, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    result = proxy_->SeedRandom(isolate_credential, session_id, seed);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

uint32_t ChapsProxyImpl::GenerateRandom(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        uint64_t num_bytes,
                                        vector<uint8_t>* random_data) {
  AutoLock lock(lock_);
  LOG_CK_RV_AND_RETURN_IF(!proxy_.get(), CKR_CRYPTOKI_NOT_INITIALIZED);
  LOG_CK_RV_AND_RETURN_IF(!random_data || num_bytes == 0, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  try {
    proxy_->GenerateRandom(isolate_credential, session_id, num_bytes,
                           *random_data, result);
  } catch (DBus::Error err) {
    result = CKR_GENERAL_ERROR;
    LOG(ERROR) << "DBus::Error - " << err.what();
  }
  return result;
}

bool ChapsProxyImpl::WaitForService() {
  const useconds_t kDelayOnFailureUs = 10000;  // 10ms.
  const int kMaxAttempts = 500;  // 5 seconds.
  vector<uint64_t> slot_list;
  uint32_t result;
  string last_error_message;
  for (int i = 0; i < kMaxAttempts; ++i) {
    try {
      proxy_->GetSlotList(
          IsolateCredentialManager::GetDefaultIsolateCredential(),
          false, slot_list, result);
      return true;
    } catch (DBus::Error err) {
      last_error_message = err.what();
    }
    usleep(kDelayOnFailureUs);
  }
  LOG(ERROR) << "Chaps service is not available: " << last_error_message;
  return false;
}

}  // namespace chaps
