// 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_service_redirect.h"

#include <dlfcn.h>
#include <errno.h>

#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <chromeos/secure_blob.h>

#include "chaps/attributes.h"
#include "chaps/chaps.h"
#include "chaps/chaps_utility.h"
#include "chaps/platform_globals.h"

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

typedef CK_RV (*GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR);

namespace chaps {

ChapsServiceRedirect::ChapsServiceRedirect(const char* library_path)
    : library_path_(library_path),
      library_(NULL),
      functions_(NULL),
      is_initialized_(false) {}

ChapsServiceRedirect::~ChapsServiceRedirect() {
  TearDown();
}

bool ChapsServiceRedirect::Init() {
  library_ = dlopen(library_path_.c_str(), RTLD_NOW | RTLD_LOCAL);
  if (!library_) {
    LOG(ERROR) << "Failed to load " << library_path_ << " - " << dlerror();
    return false;
  }
  GetFunctionList get_func_list =
      reinterpret_cast<GetFunctionList>(dlsym(library_, "C_GetFunctionList"));
  if (!get_func_list) {
    LOG(ERROR) << "Failed to find C_GetFunctionList - " << dlerror();
    TearDown();
    return false;
  }
  if (get_func_list(&functions_) != CKR_OK) {
    LOG(ERROR) << "C_GetFunctionList failed.";
    TearDown();
    return false;
  }
  CHECK(functions_) << "Library successfully returned NULL function list.";
  return true;
}

bool ChapsServiceRedirect::Init2() {
  CHECK(functions_);
  if (is_initialized_)
    return true;
  if (!SetProcessUserAndGroup(kServiceRedirectProcessUser,
                              kServiceRedirectProcessGroup,
                              false))
    return false;
  CK_RV result = functions_->C_Initialize(NULL);
  if (result != CKR_OK && result != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
    LOG(ERROR) << "C_Initialize : " << CK_RVToString(result);
    return false;
  }
  LOG(INFO) << library_path_ << " initialized.";
  is_initialized_ = true;
  return true;
}

void ChapsServiceRedirect::TearDown() {
  if (functions_) {
    functions_->C_Finalize(NULL);
    functions_ = NULL;
  }
  if (library_) {
    dlclose(library_);
    library_ = NULL;
  }
}

uint32_t ChapsServiceRedirect::GetSlotList(const SecureBlob& isolate_credential,
                                           bool token_present,
                                           vector<uint64_t>* slot_list) {
  if (!slot_list || slot_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  if (!Init2()) {
    // If we can't initialize the target library, we will successfully report
    // zero slots.
    return CKR_OK;
  }
  CK_ULONG count = 0;
  // First, call with NULL to retrieve the slot count.
  CK_RV result = functions_->C_GetSlotList(token_present, NULL, &count);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  scoped_ptr<CK_SLOT_ID[]> slot_array(new CK_SLOT_ID[count]);
  CHECK(slot_array.get()) << "GetSlotList out of memory.";
  // Now, query the actual list.
  result = functions_->C_GetSlotList(token_present, slot_array.get(), &count);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  for (CK_ULONG i = 0; i < count; ++i) {
    slot_list->push_back(static_cast<uint64_t>(slot_array[i]));
  }
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  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);
  }
  CK_SLOT_INFO slot_info;
  CK_RV result = functions_->C_GetSlotInfo(slot_id, &slot_info);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *slot_description =
      ConvertByteBufferToVector(slot_info.slotDescription,
                                arraysize(slot_info.slotDescription));
  *manufacturer_id =
      ConvertByteBufferToVector(slot_info.manufacturerID,
                                arraysize(slot_info.manufacturerID));
  *flags = static_cast<uint64_t>(slot_info.flags);
  *hardware_version_major = slot_info.hardwareVersion.major;
  *hardware_version_minor = slot_info.hardwareVersion.minor;
  *firmware_version_major = slot_info.firmwareVersion.major;
  *firmware_version_minor = slot_info.firmwareVersion.minor;
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  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);
  }
  CK_TOKEN_INFO token_info;
  CK_RV result = functions_->C_GetTokenInfo(slot_id, &token_info);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *label =
      ConvertByteBufferToVector(token_info.label, arraysize(token_info.label));
  *manufacturer_id =
      ConvertByteBufferToVector(token_info.manufacturerID,
                                arraysize(token_info.manufacturerID));
  *model = ConvertByteBufferToVector(token_info.model,
                                     arraysize(token_info.model));
  *serial_number =
      ConvertByteBufferToVector(token_info.serialNumber,
                                arraysize(token_info.serialNumber));
  *flags = token_info.flags;
  *max_session_count = token_info.ulMaxSessionCount;
  *session_count = token_info.ulSessionCount;
  *max_session_count_rw = token_info.ulMaxRwSessionCount;
  *session_count_rw = token_info.ulRwSessionCount;
  *max_pin_len = token_info.ulMaxPinLen;
  *min_pin_len = token_info.ulMinPinLen;
  *total_public_memory = token_info.ulTotalPublicMemory;
  *free_public_memory = token_info.ulFreePublicMemory;
  *total_private_memory = token_info.ulTotalPrivateMemory;
  *free_private_memory = token_info.ulFreePrivateMemory;
  *hardware_version_major = token_info.hardwareVersion.major;
  *hardware_version_minor = token_info.hardwareVersion.minor;
  *firmware_version_major = token_info.firmwareVersion.major;
  *firmware_version_minor = token_info.firmwareVersion.minor;
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::GetMechanismList(
    const SecureBlob& isolate_credential,
    uint64_t slot_id,
    vector<uint64_t>* mechanism_list) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!mechanism_list || mechanism_list->size() > 0,
                          CKR_ARGUMENTS_BAD);
  CK_ULONG count = 0;
  // First, call with NULL to retrieve the mechanism count.
  CK_RV result = functions_->C_GetMechanismList(slot_id, NULL, &count);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  scoped_ptr<CK_MECHANISM_TYPE[]> mech_array(new CK_MECHANISM_TYPE[count]);
  LOG_CK_RV_AND_RETURN_IF(!mech_array.get(), CKR_HOST_MEMORY);
  // Now, query the actual list.
  result = functions_->C_GetMechanismList(slot_id, mech_array.get(), &count);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  for (CK_ULONG i = 0; i < count; ++i) {
    mechanism_list->push_back(static_cast<uint64_t>(mech_array[i]));
  }
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  if (!min_key_size || !max_key_size || !flags)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  CK_MECHANISM_INFO mech_info;
  CK_RV result = functions_->C_GetMechanismInfo(slot_id,
                                                mechanism_type,
                                                &mech_info);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *min_key_size = static_cast<uint64_t>(mech_info.ulMinKeySize);
  *max_key_size = static_cast<uint64_t>(mech_info.ulMaxKeySize);
  *flags = static_cast<uint64_t>(mech_info.flags);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::InitToken(const SecureBlob& isolate_credential,
                                         uint64_t slot_id,
                                         const string* so_pin,
                                         const vector<uint8_t>& label) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(label.size() != chaps::kTokenLabelSize,
                          CKR_ARGUMENTS_BAD);
  CK_UTF8CHAR_PTR pin_buffer =
      so_pin ? ConvertStringToCharBuffer(so_pin->data()) : NULL;
  CK_ULONG pin_length = so_pin ? static_cast<CK_ULONG>(so_pin->length()) : 0;
  CK_UTF8CHAR label_buffer[chaps::kTokenLabelSize];
  memcpy(label_buffer, label.data(), chaps::kTokenLabelSize);
  CK_RV result = functions_->C_InitToken(slot_id,
                                         pin_buffer,
                                         pin_length,
                                         label_buffer);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::InitPIN(const SecureBlob& isolate_credential,
                                       uint64_t session_id, const string* pin) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_UTF8CHAR_PTR pin_buffer =
      pin ? ConvertStringToCharBuffer(pin->data()) : NULL;
  CK_ULONG pin_length = pin ? static_cast<CK_ULONG>(pin->length()) : 0;
  CK_RV result = functions_->C_InitPIN(session_id, pin_buffer, pin_length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::SetPIN(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const string* old_pin,
                                      const string* new_pin) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_UTF8CHAR_PTR old_pin_buffer =
      old_pin ? ConvertStringToCharBuffer(old_pin->data()) : NULL;
  CK_ULONG old_pin_length =
      old_pin ? static_cast<CK_ULONG>(old_pin->length()) : 0;
  CK_UTF8CHAR_PTR new_pin_buffer =
      new_pin ? ConvertStringToCharBuffer(new_pin->data()) : NULL;
  CK_ULONG new_pin_length =
      new_pin ? static_cast<CK_ULONG>(new_pin->length()) : 0;
  CK_RV result = functions_->C_SetPIN(session_id,
                                      old_pin_buffer, old_pin_length,
                                      new_pin_buffer, new_pin_length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::OpenSession(const SecureBlob& isolate_credential,
                                           uint64_t slot_id, uint64_t flags,
                                           uint64_t* session_id) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!session_id, CKR_ARGUMENTS_BAD);
  CK_SESSION_HANDLE handle;
  uint32_t result = functions_->C_OpenSession(slot_id, flags, NULL, NULL,
                                              &handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *session_id = handle;
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::CloseSession(
     const SecureBlob& isolate_credential,
     uint64_t session_id) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_CloseSession(session_id);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::CloseAllSessions(
      const SecureBlob& isolate_credential,
      uint64_t slot_id) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_CloseAllSessions(slot_id);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::GetSessionInfo(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t* slot_id,
      uint64_t* state,
      uint64_t* flags,
      uint64_t* device_error) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  if (!slot_id || !state || !flags || !device_error)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  CK_SESSION_INFO info;
  uint32_t result = functions_->C_GetSessionInfo(session_id, &info);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *slot_id = static_cast<uint64_t>(info.slotID);
  *state = static_cast<uint64_t>(info.state);
  *flags = static_cast<uint64_t>(info.flags);
  *device_error = static_cast<uint64_t>(info.ulDeviceError);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::GetOperationState(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    vector<uint8_t>* operation_state) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!operation_state, CKR_ARGUMENTS_BAD);
  CK_ULONG size = 0;
  // First, call with NULL to retrieve the state size.
  CK_RV result = functions_->C_GetOperationState(session_id, NULL, &size);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  scoped_ptr<CK_BYTE[]> buffer(new CK_BYTE[size]);
  LOG_CK_RV_AND_RETURN_IF(!buffer.get(), CKR_HOST_MEMORY);
  // Now, get the actual state data.
  result = functions_->C_GetOperationState(session_id, buffer.get(), &size);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *operation_state = ConvertByteBufferToVector(buffer.get(), size);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_SetOperationState(
      session_id,
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(operation_state.data())),
      static_cast<CK_ULONG>(operation_state.size()),
      static_cast<CK_OBJECT_HANDLE>(encryption_key_handle),
      static_cast<CK_OBJECT_HANDLE>(authentication_key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::Login(const SecureBlob& isolate_credential,
                                     uint64_t session_id,
                                     uint64_t user_type,
                                     const string* pin) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_UTF8CHAR_PTR pin_buffer =
      pin ? ConvertStringToCharBuffer(pin->data()) : NULL;
  CK_ULONG pin_length = pin ? static_cast<CK_ULONG>(pin->length()) : 0;
  uint32_t result = functions_->C_Login(session_id,
                                        user_type,
                                        pin_buffer,
                                        pin_length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::Logout(const SecureBlob& isolate_credential,
                                      uint64_t session_id) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_Logout(session_id);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  Attributes tmp;
  if (!tmp.Parse(attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_CreateObject(
      session_id,
      tmp.attributes(),
      tmp.num_attributes(),
      PreservedUint64_t(new_object_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!new_object_handle, CKR_ARGUMENTS_BAD);
  Attributes tmp;
  if (!tmp.Parse(attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_CopyObject(
      session_id,
      object_handle,
      tmp.attributes(),
      tmp.num_attributes(),
      PreservedUint64_t(new_object_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::DestroyObject(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t object_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_DestroyObject(session_id, object_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::GetObjectSize(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t object_handle,
      uint64_t* object_size) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!object_size, CKR_ARGUMENTS_BAD);
  uint32_t result = functions_->C_GetObjectSize(session_id,
                                                object_handle,
                                                PreservedUint64_t(object_size));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!attributes_out, CKR_ARGUMENTS_BAD);
  Attributes tmp;
  if (!tmp.Parse(attributes_in))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_GetAttributeValue(session_id,
                                                    object_handle,
                                                    tmp.attributes(),
                                                    tmp.num_attributes());
  if (result != CKR_OK)
    LOG_CK_RV(result);
  if (!tmp.Serialize(attributes_out))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  return result;
}

uint32_t ChapsServiceRedirect::SetAttributeValue(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t object_handle,
    const vector<uint8_t>& attributes) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes), CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_SetAttributeValue(session_id,
                                                    object_handle,
                                                    tmp.attributes(),
                                                    tmp.num_attributes());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::FindObjectsInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    const vector<uint8_t>& attributes) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  Attributes tmp;
  LOG_CK_RV_AND_RETURN_IF(!tmp.Parse(attributes), CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_FindObjectsInit(session_id,
                                                  tmp.attributes(),
                                                  tmp.num_attributes());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::FindObjects(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           uint64_t max_object_count,
                                           vector<uint64_t>* object_list) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  if (!object_list || object_list->size() > 0)
    LOG_CK_RV_AND_RETURN(CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_OBJECT_HANDLE[]> object_handles(
      new CK_OBJECT_HANDLE[max_object_count]);
  CHECK(object_handles.get());
  CK_ULONG object_count = 0;
  uint32_t result = functions_->C_FindObjects(session_id,
                                              object_handles.get(),
                                              max_object_count,
                                              &object_count);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  for (CK_ULONG i = 0; i < object_count; i++) {
    object_list->push_back(static_cast<uint64_t>(object_handles[i]));
  }
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::FindObjectsFinal(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_FindObjectsFinal(session_id);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::EncryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_EncryptInit(
      session_id,
      &mechanism,
      static_cast<CK_OBJECT_HANDLE>(key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_Encrypt(session_id,
                                          in_bytes,
                                          data_in.size(),
                                          out_bytes.get(),
                                          &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_EncryptUpdate(session_id,
                                                in_bytes,
                                                data_in.size(),
                                                out_bytes.get(),
                                                &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_EncryptFinal(session_id,
                                               out_bytes.get(),
                                               &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

void ChapsServiceRedirect::EncryptCancel(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG(ERROR) << "Unexpected cancel operation";
}

uint32_t ChapsServiceRedirect::DecryptInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_DecryptInit(
      session_id,
      &mechanism,
      static_cast<CK_OBJECT_HANDLE>(key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_Decrypt(session_id,
                                          in_bytes,
                                          data_in.size(),
                                          out_bytes.get(),
                                          &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  if (out_bytes.get())
    *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DecryptUpdate(session_id,
                                                in_bytes,
                                                data_in.size(),
                                                out_bytes.get(),
                                                &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DecryptFinal(session_id,
                                               out_bytes.get(),
                                               &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

void ChapsServiceRedirect::DecryptCancel(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG(ERROR) << "Unexpected cancel operation";
}

uint32_t ChapsServiceRedirect::DigestInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_DigestInit(session_id, &mechanism);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !digest, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_Digest(session_id,
                                         in_bytes,
                                         data_in.size(),
                                         out_bytes.get(),
                                         &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *digest = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::DigestUpdate(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      const vector<uint8_t>& data_in) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  uint32_t result = functions_->C_DigestUpdate(session_id,
                                               in_bytes,
                                               data_in.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::DigestKey(const SecureBlob& isolate_credential,
                                         uint64_t session_id,
                                         uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  uint32_t result = functions_->C_DigestKey(session_id, key_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::DigestFinal(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           uint64_t max_out_length,
                                           uint64_t* actual_out_length,
                                           vector<uint8_t>* digest) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !digest, CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DigestFinal(session_id,
                                              out_bytes.get(),
                                              &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *digest = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

void ChapsServiceRedirect::DigestCancel(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG(ERROR) << "Unexpected cancel operation";
}

uint32_t ChapsServiceRedirect::SignInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_SignInit(session_id, &mechanism, key_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !signature, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_Sign(session_id,
                                       in_bytes,
                                       data.size(),
                                       out_bytes.get(),
                                       &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *signature = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::SignUpdate(const SecureBlob& isolate_credential,
                                          uint64_t session_id,
                                          const vector<uint8_t>& data_part) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_part.data()));
  uint32_t result = functions_->C_SignUpdate(session_id,
                                             in_bytes,
                                             data_part.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::SignFinal(const SecureBlob& isolate_credential,
                                         uint64_t session_id,
                                         uint64_t max_out_length,
                                         uint64_t* actual_out_length,
                                         vector<uint8_t>* signature) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !signature, CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_SignFinal(session_id,
                                            out_bytes.get(),
                                            &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *signature = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

void ChapsServiceRedirect::SignCancel(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG(ERROR) << "Unexpected cancel operation";
}

uint32_t ChapsServiceRedirect::SignRecoverInit(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_SignRecoverInit(session_id,
                                                  &mechanism,
                                                  key_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !signature, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_SignRecover(session_id,
                                              in_bytes,
                                              data.size(),
                                              out_bytes.get(),
                                              &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *signature = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::VerifyInit(
    const SecureBlob& isolate_credential,
    uint64_t session_id,
    uint64_t mechanism_type,
    const vector<uint8_t>& mechanism_parameter,
    uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_VerifyInit(session_id,
                                             &mechanism,
                                             key_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::Verify(const SecureBlob& isolate_credential,
                                      uint64_t session_id,
                                      const vector<uint8_t>& data,
                                      const vector<uint8_t>& signature) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_BYTE_PTR data_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data.data()));
  CK_BYTE_PTR sig_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(signature.data()));
  uint32_t result = functions_->C_Verify(session_id,
                                         data_bytes,
                                         data.size(),
                                         sig_bytes,
                                         signature.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::VerifyUpdate(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      const vector<uint8_t>& data_part) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_part.data()));
  uint32_t result = functions_->C_VerifyUpdate(session_id,
                                               in_bytes,
                                               data_part.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::VerifyFinal(const SecureBlob& isolate_credential,
                                           uint64_t session_id,
                                           const vector<uint8_t>& signature) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(signature.data()));
  uint32_t result = functions_->C_VerifyFinal(session_id,
                                              in_bytes,
                                              signature.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

void ChapsServiceRedirect::VerifyCancel(
      const SecureBlob& isolate_credential,
      uint64_t session_id) {
  LOG(ERROR) << "Unexpected cancel operation";
}

uint32_t ChapsServiceRedirect::VerifyRecoverInit(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t mechanism_type,
      const vector<uint8_t>& mechanism_parameter,
      uint64_t key_handle) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  uint32_t result = functions_->C_VerifyRecoverInit(session_id,
                                                    &mechanism,
                                                    key_handle);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(signature.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_VerifyRecover(session_id,
                                                in_bytes,
                                                signature.size(),
                                                out_bytes.get(),
                                                &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DigestEncryptUpdate(session_id,
                                                      in_bytes,
                                                      data_in.size(),
                                                      out_bytes.get(),
                                                      &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DecryptDigestUpdate(session_id,
                                                      in_bytes,
                                                      data_in.size(),
                                                      out_bytes.get(),
                                                      &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_SignEncryptUpdate(session_id,
                                                    in_bytes,
                                                    data_in.size(),
                                                    out_bytes.get(),
                                                    &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !data_out, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(data_in.data()));
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_DecryptVerifyUpdate(session_id,
                                                      in_bytes,
                                                      data_in.size(),
                                                      out_bytes.get(),
                                                      &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *data_out = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  Attributes parsed_attributes;
  if (!parsed_attributes.Parse(attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_GenerateKey(
      session_id,
      &mechanism,
      parsed_attributes.attributes(),
      parsed_attributes.num_attributes(),
      PreservedUint64_t(key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!public_key_handle || !private_key_handle,
                          CKR_ARGUMENTS_BAD);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  Attributes public_parsed_attributes;
  if (!public_parsed_attributes.Parse(public_attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  Attributes private_parsed_attributes;
  if (!private_parsed_attributes.Parse(private_attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_GenerateKeyPair(
      session_id,
      &mechanism,
      public_parsed_attributes.attributes(),
      public_parsed_attributes.num_attributes(),
      private_parsed_attributes.attributes(),
      private_parsed_attributes.num_attributes(),
      PreservedUint64_t(public_key_handle),
      PreservedUint64_t(private_key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!actual_out_length || !wrapped_key,
                          CKR_ARGUMENTS_BAD);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  scoped_ptr<CK_BYTE[]> out_bytes;
  if (max_out_length) {
    out_bytes.reset(new CK_BYTE[max_out_length]);
    CHECK(out_bytes.get());
  }
  CK_ULONG length = max_out_length;
  uint32_t result = functions_->C_WrapKey(session_id,
                                          &mechanism,
                                          wrapping_key_handle,
                                          key_handle,
                                          out_bytes.get(),
                                          &length);
  // Provide the length before checking the result. This handles cases like
  // CKR_BUFFER_TOO_SMALL.
  *actual_out_length = static_cast<uint64_t>(length);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *wrapped_key = ConvertByteBufferToVector(out_bytes.get(), length);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  Attributes parsed_attributes;
  if (!parsed_attributes.Parse(attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(wrapped_key.data()));
  uint32_t result = functions_->C_UnwrapKey(session_id,
                                            &mechanism,
                                            wrapping_key_handle,
                                            in_bytes,
                                            wrapped_key.size(),
                                            parsed_attributes.attributes(),
                                            parsed_attributes.num_attributes(),
                                            PreservedUint64_t(key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::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(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!key_handle, CKR_ARGUMENTS_BAD);
  CK_MECHANISM mechanism;
  mechanism.mechanism = static_cast<CK_MECHANISM_TYPE>(mechanism_type);
  mechanism.pParameter = const_cast<uint8_t*>(mechanism_parameter.data());
  mechanism.ulParameterLen = mechanism_parameter.size();
  Attributes parsed_attributes;
  if (!parsed_attributes.Parse(attributes))
    LOG_CK_RV_AND_RETURN(CKR_TEMPLATE_INCONSISTENT);
  uint32_t result = functions_->C_DeriveKey(session_id,
                                            &mechanism,
                                            base_key_handle,
                                            parsed_attributes.attributes(),
                                            parsed_attributes.num_attributes(),
                                            PreservedUint64_t(key_handle));
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::SeedRandom(const SecureBlob& isolate_credential,
                                          uint64_t session_id,
                                          const vector<uint8_t>& seed) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(seed.size() == 0, CKR_ARGUMENTS_BAD);
  CK_BYTE_PTR in_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(seed.data()));
  uint32_t result = functions_->C_SeedRandom(session_id, in_bytes, seed.size());
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  return CKR_OK;
}

uint32_t ChapsServiceRedirect::GenerateRandom(
      const SecureBlob& isolate_credential,
      uint64_t session_id,
      uint64_t num_bytes,
      vector<uint8_t>* random_data) {
  LOG_CK_RV_AND_RETURN_IF(!Init2(), CKR_GENERAL_ERROR);
  LOG_CK_RV_AND_RETURN_IF(!random_data || num_bytes == 0, CKR_ARGUMENTS_BAD);
  scoped_ptr<CK_BYTE[]> out_bytes(new CK_BYTE[num_bytes]);
  CHECK(out_bytes.get());
  uint32_t result = functions_->C_GenerateRandom(session_id,
                                                 out_bytes.get(),
                                                 num_bytes);
  LOG_CK_RV_AND_RETURN_IF_ERR(result);
  *random_data = ConvertByteBufferToVector(out_bytes.get(), num_bytes);
  return CKR_OK;
}

}  // namespace chaps
