// 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.front(), 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.front())),
      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.front());
  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.front()));
  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.front()));
  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.front());
  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.front()));
  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.front()));
  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.front());
  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.front()));
  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.front()));
  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.front());
  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.front()));
  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.front()));
  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.front());
  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.front()));
  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.front());
  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.front()));
  CK_BYTE_PTR sig_bytes =
      static_cast<CK_BYTE_PTR>(const_cast<uint8_t*>(&signature.front()));
  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.front()));
  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.front()));
  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.front());
  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.front()));
  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.front()));
  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.front()));
  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.front()));
  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.front()));
  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.front());
  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.front());
  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.front());
  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.front());
  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.front()));
  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.front());
  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.front()));
  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
