// 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 <utility>

#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ptr_util.h>
#include <base/memory/ref_counted.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <dbus/message.h>
#include <dbus/object_path.h>

#include "chaps/chaps.h"
#include "chaps/chaps_utility.h"
#include "chaps/dbus/dbus_proxy_wrapper.h"
#include "chaps/dbus/scoped_bus.h"
#include "chaps/dbus_bindings/constants.h"
#include "chaps/isolate.h"
#include "pkcs11/cryptoki.h"

using base::AutoLock;
using std::string;
using std::vector;
using brillo::dbus_utils::ExtractMethodCallResults;
using brillo::SecureBlob;

namespace {

const char kDBusThreadName[] = "chaps_dbus_client_thread";

// These methods are equivalent to static_casting the blob to
// a regular std::vector since this is just an upcast. The reason why
// we use them is that the libbrillo D-Bus bindings rely on template
// argument type deduction to figure out which MessageReader and
// MessageWriter methods need to be called to marshal and unmarshal
// data into D-Bus messages, and SecureBlob has no specializations
// there.
inline const std::vector<uint8_t>& AsVector(const SecureBlob& blob) {
  return blob;
}

inline std::vector<uint8_t>* AsVector(SecureBlob* blob) {
  return blob;
}

// We need to be able to shadow AtExitManagers because we don't know if the
// caller has an AtExitManager already or not (on Chrome it might, but on Linux
// it probably won't).
class ProxyAtExitManager : public base::AtExitManager {
 public:
  ProxyAtExitManager() : AtExitManager(true) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ProxyAtExitManager);
};

}  // namespace

namespace chaps {

// Below is the real implementation.

ChapsProxyImpl::ChapsProxyImpl(std::unique_ptr<base::AtExitManager> at_exit,
                               std::unique_ptr<base::Thread> dbus_thread,
                               scoped_refptr<DBusProxyWrapper> proxy)
    : at_exit_(std::move(at_exit)),
      dbus_thread_(std::move(dbus_thread)),
      proxy_(proxy) {}

ChapsProxyImpl::~ChapsProxyImpl() {}

// static
std::unique_ptr<ChapsProxyImpl> ChapsProxyImpl::Create() {
  auto at_exit = std::make_unique<ProxyAtExitManager>();

  base::Thread::Options options;
  options.message_loop_type = base::MessageLoop::TYPE_IO;
  auto dbus_thread = std::make_unique<base::Thread>(kDBusThreadName);
  dbus_thread->StartWithOptions(options);

  scoped_refptr<ProxyWrapperConstructionTask> task(
      new ProxyWrapperConstructionTask);
  scoped_refptr<DBusProxyWrapper> proxy =
      task->ConstructProxyWrapper(dbus_thread->task_runner());
  if (!proxy)
    return nullptr;

  VLOG(1) << "Chaps proxy initialized (" << kChapsServicePath << ").";
  return base::WrapUnique(
      new ChapsProxyImpl(std::move(at_exit), std::move(dbus_thread), proxy));
}

bool ChapsProxyImpl::OpenIsolate(SecureBlob* isolate_credential,
                                 bool* new_isolate_created) {
  bool result = false;
  SecureBlob isolate_credential_in;
  SecureBlob isolate_credential_out;
  isolate_credential_in.swap(*isolate_credential);
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kOpenIsolateMethod, AsVector(isolate_credential_in));
  if (resp && ExtractMethodCallResults(resp.get(), nullptr,
                                       AsVector(&isolate_credential_out),
                                       new_isolate_created, &result))
    isolate_credential->swap(isolate_credential_out);
  return result;
}

void ChapsProxyImpl::CloseIsolate(const SecureBlob& isolate_credential) {
  proxy_->CallMethod(kCloseIsolateMethod, AsVector(isolate_credential));
}

bool ChapsProxyImpl::LoadToken(const SecureBlob& isolate_credential,
                               const string& path,
                               const vector<uint8_t>& auth_data,
                               const string& label,
                               uint64_t* slot_id) {
  bool result = false;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kLoadTokenMethod, AsVector(isolate_credential), path, auth_data, label);
  return resp &&
         ExtractMethodCallResults(resp.get(), nullptr, slot_id, &result) &&
         result;
}

void ChapsProxyImpl::UnloadToken(const SecureBlob& isolate_credential,
                                 const string& path) {
  proxy_->CallMethod(kUnloadTokenMethod, AsVector(isolate_credential), path);
}

void ChapsProxyImpl::ChangeTokenAuthData(const string& path,
                                         const vector<uint8_t>& old_auth_data,
                                         const vector<uint8_t>& new_auth_data) {
  proxy_->CallMethod(kChangeTokenAuthDataMethod, path, old_auth_data,
                     new_auth_data);
}

bool ChapsProxyImpl::GetTokenPath(const SecureBlob& isolate_credential,
                                  uint64_t slot_id,
                                  string* path) {
  bool result = false;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetTokenPathMethod, AsVector(isolate_credential), slot_id);
  return resp && ExtractMethodCallResults(resp.get(), nullptr, path, &result) &&
         result;
}

void ChapsProxyImpl::SetLogLevel(const int32_t& level) {
  proxy_->CallMethod(kSetLogLevelMethod, level);
}

uint32_t ChapsProxyImpl::GetSlotList(const SecureBlob& isolate_credential,
                                     bool token_present,
                                     vector<uint64_t>* slot_list) {
  LOG_CK_RV_AND_RETURN_IF(!slot_list, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetSlotListMethod, AsVector(isolate_credential), token_present);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, slot_list, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetSlotInfo(const SecureBlob& isolate_credential,
                                     uint64_t slot_id,
                                     SlotInfo* slot_info) {
  LOG_CK_RV_AND_RETURN_IF(!slot_info, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetSlotInfoMethod, AsVector(isolate_credential), slot_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, slot_info, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetTokenInfo(const SecureBlob& isolate_credential,
                                      uint64_t slot_id,
                                      TokenInfo* token_info) {
  LOG_CK_RV_AND_RETURN_IF(!token_info, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetTokenInfoMethod, AsVector(isolate_credential), slot_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, token_info, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetMechanismList(const SecureBlob& isolate_credential,
                                          uint64_t slot_id,
                                          vector<uint64_t>* mechanism_list) {
  LOG_CK_RV_AND_RETURN_IF(!mechanism_list, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetMechanismListMethod, AsVector(isolate_credential), slot_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, mechanism_list, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetMechanismInfo(const SecureBlob& isolate_credential,
                                          uint64_t slot_id,
                                          uint64_t mechanism_type,
                                          MechanismInfo* mechanism_info) {
  LOG_CK_RV_AND_RETURN_IF(!mechanism_info, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kGetMechanismInfoMethod, AsVector(isolate_credential),
                         slot_id, mechanism_type);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, mechanism_info, &result);
  return result;
}

uint32_t ChapsProxyImpl::InitToken(const SecureBlob& isolate_credential,
                                   uint64_t slot_id,
                                   const string* so_pin,
                                   const vector<uint8_t>& label) {
  uint32_t result = CKR_GENERAL_ERROR;
  string tmp_pin;
  if (so_pin)
    tmp_pin = *so_pin;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kInitTokenMethod, AsVector(isolate_credential),
                         slot_id, (so_pin == nullptr), tmp_pin, label);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::InitPIN(const SecureBlob& isolate_credential,
                                 uint64_t session_id,
                                 const string* pin) {
  uint32_t result = CKR_GENERAL_ERROR;
  string tmp_pin;
  if (pin)
    tmp_pin = *pin;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kInitPINMethod, AsVector(isolate_credential),
                         session_id, (pin == nullptr), tmp_pin);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::SetPIN(const SecureBlob& isolate_credential,
                                uint64_t session_id,
                                const string* old_pin,
                                const string* new_pin) {
  uint32_t result = CKR_GENERAL_ERROR;
  string tmp_old_pin;
  if (old_pin)
    tmp_old_pin = *old_pin;
  string tmp_new_pin;
  if (new_pin)
    tmp_new_pin = *new_pin;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSetPINMethod, AsVector(isolate_credential), session_id,
      (old_pin == nullptr), tmp_old_pin, (new_pin == nullptr), tmp_new_pin);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::OpenSession(const SecureBlob& isolate_credential,
                                     uint64_t slot_id,
                                     uint64_t flags,
                                     uint64_t* session_id) {
  LOG_CK_RV_AND_RETURN_IF(!session_id, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kOpenSessionMethod, AsVector(isolate_credential), slot_id, flags);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, session_id, &result);
  return result;
}

uint32_t ChapsProxyImpl::CloseSession(const SecureBlob& isolate_credential,
                                      uint64_t session_id) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kCloseSessionMethod, AsVector(isolate_credential), session_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::CloseAllSessions(const SecureBlob& isolate_credential,
                                          uint64_t slot_id) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kCloseAllSessionsMethod, AsVector(isolate_credential), slot_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetSessionInfo(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        SessionInfo* session_info) {
  LOG_CK_RV_AND_RETURN_IF(!session_info, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetSessionInfoMethod, AsVector(isolate_credential), session_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, session_info, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetOperationState(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           vector<uint8_t>* operation_state) {
  LOG_CK_RV_AND_RETURN_IF(!operation_state, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGetOperationStateMethod, AsVector(isolate_credential), session_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, operation_state, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSetOperationStateMethod, AsVector(isolate_credential), session_id,
      operation_state, encryption_key_handle, authentication_key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::Login(const SecureBlob& isolate_credential,
                               uint64_t session_id,
                               uint64_t user_type,
                               const string* pin) {
  uint32_t result = CKR_GENERAL_ERROR;
  string tmp_pin;
  if (pin)
    tmp_pin = *pin;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kLoginMethod, AsVector(isolate_credential), session_id,
                         user_type, (pin == nullptr), tmp_pin);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::Logout(const SecureBlob& isolate_credential,
                                uint64_t session_id) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kLogoutMethod, AsVector(isolate_credential), session_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::CreateObject(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& attributes,
                                      uint64_t* new_object_handle) {
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kCreateObjectMethod, AsVector(isolate_credential),
                         session_id, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, new_object_handle, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kCopyObjectMethod, AsVector(isolate_credential),
                         session_id, object_handle, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, new_object_handle, &result);
  return result;
}

uint32_t ChapsProxyImpl::DestroyObject(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t object_handle) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDestroyObjectMethod, AsVector(isolate_credential),
                         session_id, object_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::GetObjectSize(const SecureBlob& isolate_credential,
                                       uint64_t session_id,
                                       uint64_t object_handle,
                                       uint64_t* object_size) {
  LOG_CK_RV_AND_RETURN_IF(!object_size, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kGetObjectSizeMethod, AsVector(isolate_credential),
                         session_id, object_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, object_size, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!attributes_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kGetAttributeValueMethod, AsVector(isolate_credential),
                         session_id, object_handle, attributes_in);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, attributes_out, &result);
  return result;
}

uint32_t ChapsProxyImpl::SetAttributeValue(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           uint64_t object_handle,
                                           const vector<uint8_t>& attributes) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kSetAttributeValueMethod, AsVector(isolate_credential),
                         session_id, object_handle, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::FindObjectsInit(const SecureBlob& isolate_credential,
                                         uint64_t session_id,
                                         const vector<uint8_t>& attributes) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kFindObjectsInitMethod, AsVector(isolate_credential),
                         session_id, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::FindObjects(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t max_object_count,
                                     vector<uint64_t>* object_list) {
  if (!object_list || object_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kFindObjectsMethod, AsVector(isolate_credential),
                         session_id, max_object_count);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, object_list, &result);
  return result;
}

uint32_t ChapsProxyImpl::FindObjectsFinal(const SecureBlob& isolate_credential,
                                          uint64_t session_id) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kFindObjectsFinalMethod, AsVector(isolate_credential), session_id);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kEncryptInitMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kEncryptMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp) {
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  }
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kEncryptUpdateMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp) {
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  }
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kEncryptFinalMethod, AsVector(isolate_credential),
                         session_id, max_out_length);
  if (resp) {
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  }
  return result;
}

void ChapsProxyImpl::EncryptCancel(const SecureBlob& isolate_credential,
                                   uint64_t session_id) {
  proxy_->CallMethod(kEncryptCancelMethod, AsVector(isolate_credential),
                     session_id);
}

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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDecryptInitMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDecryptMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp) {
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  }
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDecryptUpdateMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDecryptFinalMethod, AsVector(isolate_credential),
                         session_id, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  return result;
}

void ChapsProxyImpl::DecryptCancel(const SecureBlob& isolate_credential,
                                   uint64_t session_id) {
  proxy_->CallMethod(kDecryptCancelMethod, AsVector(isolate_credential),
                     session_id);
}

uint32_t ChapsProxyImpl::DigestInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDigestInitMethod, AsVector(isolate_credential),
                         session_id, mechanism_type, mechanism_parameter);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDigestMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, digest,
                             &result);
  return result;
}

uint32_t ChapsProxyImpl::DigestUpdate(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data_in) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDigestUpdateMethod, AsVector(isolate_credential), session_id, data_in);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::DigestKey(const SecureBlob& isolate_credential,
                                   uint64_t session_id,
                                   uint64_t key_handle) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDigestKeyMethod, AsVector(isolate_credential), session_id, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kDigestFinalMethod, AsVector(isolate_credential),
                         session_id, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, digest,
                             &result);
  return result;
}

void ChapsProxyImpl::DigestCancel(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  proxy_->CallMethod(kDigestCancelMethod, AsVector(isolate_credential),
                     session_id);
}

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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSignInitMethod, AsVector(isolate_credential), session_id, mechanism_type,
      mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kSignMethod, AsVector(isolate_credential), session_id,
                         data, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, signature,
                             &result);
  return result;
}

uint32_t ChapsProxyImpl::SignUpdate(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    const vector<uint8_t>& data_part) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSignUpdateMethod, AsVector(isolate_credential), session_id, data_part);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kSignFinalMethod, AsVector(isolate_credential),
                         session_id, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, signature,
                             &result);
  return result;
}

void ChapsProxyImpl::SignCancel(const SecureBlob& isolate_credential,
                                uint64_t session_id) {
  proxy_->CallMethod(kSignCancelMethod, AsVector(isolate_credential),
                     session_id);
}

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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSignRecoverInitMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kSignRecoverMethod, AsVector(isolate_credential),
                         session_id, data, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, signature,
                             &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kVerifyInitMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::Verify(const SecureBlob& isolate_credential,
                                uint64_t session_id,
                                const vector<uint8_t>& data,
                                const vector<uint8_t>& signature) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kVerifyMethod, AsVector(isolate_credential), session_id, data, signature);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::VerifyUpdate(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data_part) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kVerifyUpdateMethod, AsVector(isolate_credential), session_id, data_part);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::VerifyFinal(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     const vector<uint8_t>& signature) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kVerifyUpdateMethod, AsVector(isolate_credential), session_id, signature);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

void ChapsProxyImpl::VerifyCancel(const SecureBlob& isolate_credential,
                                  uint64_t session_id) {
  proxy_->CallMethod(kVerifyCancelMethod, AsVector(isolate_credential),
                     session_id);
}

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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kVerifyRecoverInitMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, key_handle);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  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) {
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kVerifyRecoverMethod, AsVector(isolate_credential),
                         session_id, signature, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDigestEncryptUpdateMethod, AsVector(isolate_credential), session_id,
      data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDecryptDigestUpdateMethod, AsVector(isolate_credential), session_id,
      data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kSignEncryptUpdateMethod, AsVector(isolate_credential),
                         session_id, data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDecryptVerifyUpdateMethod, AsVector(isolate_credential), session_id,
      data_in, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length, data_out,
                             &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kGenerateKeyMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, key_handle, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!public_key_handle || !private_key_handle,
                          CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kGenerateKeyPairMethod, AsVector(isolate_credential),
                         session_id, mechanism_type, mechanism_parameter,
                         public_attributes, private_attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, public_key_handle,
                             private_key_handle, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !wrapped_key,
                          CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kWrapKeyMethod, AsVector(isolate_credential), session_id, mechanism_type,
      mechanism_parameter, wrapping_key_handle, key_handle, max_out_length);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, actual_out_length,
                             wrapped_key, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kUnwrapKeyMethod, AsVector(isolate_credential),
                         session_id, mechanism_type, mechanism_parameter,
                         wrapping_key_handle, wrapped_key, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, key_handle, &result);
  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) {
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kDeriveKeyMethod, AsVector(isolate_credential), session_id,
      mechanism_type, mechanism_parameter, base_key_handle, attributes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, key_handle, &result);
  return result;
}

uint32_t ChapsProxyImpl::SeedRandom(const SecureBlob& isolate_credential,
                                    uint64_t session_id,
                                    const vector<uint8_t>& seed) {
  LOG_CK_RV_AND_RETURN_IF(seed.size() == 0, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp = proxy_->CallMethod(
      kSeedRandomMethod, AsVector(isolate_credential), session_id, seed);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, &result);
  return result;
}

uint32_t ChapsProxyImpl::GenerateRandom(const SecureBlob& isolate_credential,
                                        uint64_t session_id,
                                        uint64_t num_bytes,
                                        vector<uint8_t>* random_data) {
  LOG_CK_RV_AND_RETURN_IF(!random_data || num_bytes == 0, CKR_ARGUMENTS_BAD);
  uint32_t result = CKR_GENERAL_ERROR;
  std::unique_ptr<dbus::Response> resp =
      proxy_->CallMethod(kGenerateRandomMethod, AsVector(isolate_credential),
                         session_id, num_bytes);
  if (resp)
    ExtractMethodCallResults(resp.get(), nullptr, random_data, &result);
  return result;
}

}  // namespace chaps
