// 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 <string>
#include <vector>

#include <base/command_line.h>
#include <chromeos/secure_blob.h>
#include <gtest/gtest.h>

#include "chaps/attributes.h"
#include "chaps/chaps_interface.h"
#include "chaps/chaps_proxy.h"
#include "chaps/chaps_service_redirect.h"
#include "chaps/chaps_utility.h"
#include "chaps/isolate.h"

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

namespace chaps {

static chaps::ChapsInterface* CreateChapsInstance() {
  bool use_dbus = false;
  if (base::CommandLine::InitializedForCurrentProcess()) {
    use_dbus = base::CommandLine::ForCurrentProcess()->HasSwitch("use_dbus");
  }

  if (use_dbus) {
    scoped_ptr<chaps::ChapsProxyImpl> proxy(new chaps::ChapsProxyImpl());
    if (proxy->Init())
      return proxy.release();
  } else {
    scoped_ptr<chaps::ChapsServiceRedirect> service(
        new chaps::ChapsServiceRedirect("libchaps.so"));
    if (service->Init())
      return service.release();
  }
  return NULL;
}

static bool SerializeAttributes(CK_ATTRIBUTE_PTR attributes,
                                CK_ULONG num_attributes,
                                vector<uint8_t>* serialized) {
  Attributes tmp(attributes, num_attributes);
  return tmp.Serialize(serialized);
}

static bool ParseAndFillAttributes(const vector<uint8_t>& serialized,
                                   CK_ATTRIBUTE_PTR attributes,
                                   CK_ULONG num_attributes) {
  Attributes tmp(attributes, num_attributes);
  return tmp.ParseAndFill(serialized);
}

static vector<uint8_t> SubVector(const vector<uint8_t>& v,
                                 int offset,
                                 int size) {
  const uint8_t* front = v.data() + offset;
  return vector<uint8_t>(front, front + size);
}

// Default test fixture for PKCS #11 calls.
class TestP11 : public ::testing::Test {
 protected:
  virtual void SetUp() {
    // The current user's token will be used so the token will already be
    // initialized and changes to token objects will persist.  The user pin can
    // be assumed to be "111111" and the so pin can be assumed to be "000000".
    // This approach will be used as long as we redirect to openCryptoki.
    chaps_.reset(CreateChapsInstance());
    ASSERT_TRUE(chaps_ != NULL);
    so_pin_ = "000000";
    user_pin_ = "111111";
    credential_ = IsolateCredentialManager::GetDefaultIsolateCredential();
  }
  scoped_ptr<chaps::ChapsInterface> chaps_;
  string so_pin_;
  string user_pin_;
  SecureBlob credential_;
};

// Test fixture for testing with a valid open session.
class TestP11PublicSession : public TestP11 {
 protected:
  virtual void SetUp() {
    TestP11::SetUp();
    ASSERT_EQ(CKR_OK, chaps_->OpenSession(credential_, 0,
                                          CKF_SERIAL_SESSION|CKF_RW_SESSION,
                                          &session_id_));
    uint32_t result = chaps_->Logout(credential_, session_id_);
    ASSERT_TRUE(result == CKR_OK || result == CKR_USER_NOT_LOGGED_IN);
  }
  virtual void TearDown() {
    SecureBlob isolate_credential;
    uint32_t result = chaps_->Logout(credential_, session_id_);
    ASSERT_TRUE(result == CKR_OK || result == CKR_USER_NOT_LOGGED_IN);
    EXPECT_EQ(CKR_OK, chaps_->CloseSession(credential_, session_id_));
    TestP11::TearDown();
  }
  uint64_t session_id_;
};

class TestP11UserSession : public TestP11PublicSession {
 protected:
  virtual void SetUp() {
    TestP11PublicSession::SetUp();
    uint32_t result = chaps_->Login(credential_, session_id_,
                                    CKU_USER, &user_pin_);
    ASSERT_TRUE(result == CKR_OK || result == CKR_USER_ALREADY_LOGGED_IN);
  }
  virtual void TearDown() {
    TestP11PublicSession::TearDown();
  }
};

class TestP11SOSession : public TestP11PublicSession {
 protected:
  virtual void SetUp() {
    TestP11PublicSession::SetUp();
    uint32_t result = chaps_->Login(credential_, session_id_,
                                    CKU_SO, &so_pin_);
    ASSERT_TRUE(result == CKR_OK || result == CKR_USER_ALREADY_LOGGED_IN);
  }
  virtual void TearDown() {
    TestP11PublicSession::TearDown();
  }
};

class TestP11Object : public TestP11PublicSession {
 protected:
  virtual void SetUp() {
    TestP11PublicSession::SetUp();
    CK_OBJECT_CLASS class_value = CKO_DATA;
    CK_UTF8CHAR label[] = "A data object";
    CK_UTF8CHAR application[] = "An application";
    CK_BYTE data[] = "Sample data";
    CK_BBOOL false_value = CK_FALSE;
    CK_ATTRIBUTE attributes[] = {
      {CKA_CLASS, &class_value, sizeof(class_value)},
      {CKA_TOKEN, &false_value, sizeof(false_value)},
      {CKA_LABEL, label, sizeof(label)-1},
      {CKA_APPLICATION, application, sizeof(application)-1},
      {CKA_VALUE, data, sizeof(data)}
    };
    vector<uint8_t> serialized;
    ASSERT_TRUE(SerializeAttributes(attributes, 5, &serialized));
    ASSERT_EQ(CKR_OK, chaps_->CreateObject(credential_,
                                           session_id_,
                                           serialized,
                                           &object_handle_));
  }
  virtual void TearDown() {
    ASSERT_EQ(CKR_OK, chaps_->DestroyObject(credential_,
                                            session_id_,
                                            object_handle_));
    TestP11PublicSession::TearDown();
  }
  uint64_t object_handle_;
};

TEST_F(TestP11, SlotList) {
  vector<uint64_t> slot_list;
  uint32_t result = chaps_->GetSlotList(credential_, false, &slot_list);
  EXPECT_EQ(CKR_OK, result);
  EXPECT_LT(0, slot_list.size());
  printf("Slots: ");
  for (size_t i = 0; i < slot_list.size(); ++i) {
    printf("%d ", static_cast<int>(slot_list[i]));
  }
  printf("\n");
  result = chaps_->GetSlotList(credential_, false, NULL);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
}

TEST_F(TestP11, SlotInfo) {
  vector<uint8_t> description;
  vector<uint8_t> manufacturer;
  uint64_t flags;
  uint8_t version[4];
  uint32_t result = chaps_->GetSlotInfo(credential_, 0, &description,
                                        &manufacturer, &flags,
                                        &version[0], &version[1],
                                        &version[2], &version[3]);
  EXPECT_EQ(CKR_OK, result);
  result = chaps_->GetSlotInfo(credential_, 0, NULL, &manufacturer, &flags,
                               &version[0], &version[1],
                               &version[2], &version[3]);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
  result = chaps_->GetSlotInfo(credential_, 17, &description,
                               &manufacturer, &flags,
                               &version[0], &version[1],
                               &version[2], &version[3]);
  EXPECT_NE(CKR_OK, result);
}

TEST_F(TestP11, TokenInfo) {
  vector<uint8_t> label;
  vector<uint8_t> manufacturer;
  vector<uint8_t> model;
  vector<uint8_t> serial_number;
  uint64_t flags;
  uint8_t version[4];
  uint64_t not_used[10];
  uint32_t result = chaps_->GetTokenInfo(credential_, 0, &label, &manufacturer,
                                         &model, &serial_number, &flags,
                                         &not_used[0], &not_used[1],
                                         &not_used[2], &not_used[3],
                                         &not_used[4], &not_used[5],
                                         &not_used[6], &not_used[7],
                                         &not_used[8], &not_used[9],
                                         &version[0], &version[1],
                                         &version[2], &version[3]);
  EXPECT_EQ(CKR_OK, result);
  result = chaps_->GetTokenInfo(credential_, 0, NULL, &manufacturer,
                                &model, &serial_number, &flags,
                                &not_used[0], &not_used[1],
                                &not_used[2], &not_used[3],
                                &not_used[4], &not_used[5],
                                &not_used[6], &not_used[7],
                                &not_used[8], &not_used[9],
                                &version[0], &version[1],
                                &version[2], &version[3]);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
  result = chaps_->GetTokenInfo(credential_, 17, &label, &manufacturer,
                                &model, &serial_number, &flags,
                                &not_used[0], &not_used[1],
                                &not_used[2], &not_used[3],
                                &not_used[4], &not_used[5],
                                &not_used[6], &not_used[7],
                                &not_used[8], &not_used[9],
                                &version[0], &version[1],
                                &version[2], &version[3]);
  EXPECT_NE(CKR_OK, result);
}

TEST_F(TestP11, MechList) {
  vector<uint64_t> mech_list;
  uint32_t result = chaps_->GetMechanismList(credential_, 0, &mech_list);
  EXPECT_EQ(CKR_OK, result);
  EXPECT_LT(0, mech_list.size());
  printf("Mech List [0]: %d\n", static_cast<int>(mech_list[0]));
  result = chaps_->GetMechanismList(credential_, 0, NULL);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
  result = chaps_->GetMechanismList(credential_, 17, &mech_list);
  EXPECT_NE(CKR_OK, result);
}

TEST_F(TestP11, MechInfo) {
  uint64_t flags;
  uint64_t min_key_size;
  uint64_t max_key_size;
  uint32_t result = chaps_->GetMechanismInfo(credential_, 0, CKM_RSA_PKCS,
                                             &min_key_size,
                                             &max_key_size, &flags);
  EXPECT_EQ(CKR_OK, result);
  printf("RSA Key Sizes: %d - %d\n", static_cast<int>(min_key_size),
         static_cast<int>(max_key_size));
  result = chaps_->GetMechanismInfo(credential_, 0,
                                    0xFFFF,
                                    &min_key_size, &max_key_size,
                                    &flags);
  EXPECT_EQ(CKR_MECHANISM_INVALID, result);
  result = chaps_->GetMechanismInfo(credential_, 17,
                                    CKM_RSA_PKCS,
                                    &min_key_size,
                                    &max_key_size,
                                    &flags);
  EXPECT_NE(CKR_OK, result);
  result = chaps_->GetMechanismInfo(credential_, 0,
                                    CKM_RSA_PKCS,
                                    NULL,
                                    &max_key_size,
                                    &flags);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
  result = chaps_->GetMechanismInfo(credential_, 0,
                                    CKM_RSA_PKCS,
                                    &min_key_size,
                                    NULL,
                                    &flags);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
  result = chaps_->GetMechanismInfo(credential_, 0,
                                    CKM_RSA_PKCS,
                                    &min_key_size,
                                    &max_key_size,
                                    NULL);
  EXPECT_EQ(CKR_ARGUMENTS_BAD, result);
}

TEST_F(TestP11, OpenCloseSession) {
  uint64_t session = 0;
  // Test successful RO and RW sessions.
  EXPECT_EQ(CKR_OK, chaps_->OpenSession(credential_, 0,
                                        CKF_SERIAL_SESSION,
                                        &session));
  EXPECT_EQ(CKR_OK, chaps_->CloseSession(credential_, session));
  EXPECT_EQ(CKR_OK, chaps_->OpenSession(credential_, 0,
                                        CKF_SERIAL_SESSION|CKF_RW_SESSION,
                                        &session));
  EXPECT_EQ(CKR_OK, chaps_->CloseSession(credential_, session));
  // Test double close.
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID, chaps_->CloseSession(credential_,
                                                             session));
  // Test error cases.
  EXPECT_EQ(CKR_ARGUMENTS_BAD,
            chaps_->OpenSession(credential_, 0, CKF_SERIAL_SESSION, NULL));
  EXPECT_EQ(CKR_SESSION_PARALLEL_NOT_SUPPORTED,
            chaps_->OpenSession(credential_, 0, 0, &session));
  // Test CloseAllSessions.
  EXPECT_EQ(CKR_OK, chaps_->OpenSession(credential_, 0,
                                        CKF_SERIAL_SESSION,
                                        &session));
  EXPECT_EQ(CKR_OK, chaps_->CloseAllSessions(credential_, 0));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID, chaps_->CloseSession(credential_,
                                                             session));
}

TEST_F(TestP11PublicSession, GetSessionInfo) {
  uint64_t slot_id, state, flags, device_error;
  EXPECT_EQ(CKR_OK, chaps_->GetSessionInfo(credential_, session_id_, &slot_id,
                                           &state, &flags, &device_error));
  EXPECT_EQ(0, slot_id);
  EXPECT_TRUE(state == CKS_RW_PUBLIC_SESSION || state == CKS_RW_USER_FUNCTIONS);
  EXPECT_EQ(CKF_SERIAL_SESSION|CKF_RW_SESSION, flags);
  uint64_t readonly_session_id;
  ASSERT_EQ(CKR_OK, chaps_->OpenSession(credential_, 0, CKF_SERIAL_SESSION,
                                        &readonly_session_id));
  EXPECT_EQ(CKR_OK, chaps_->GetSessionInfo(credential_, readonly_session_id,
                                           &slot_id, &state, &flags,
                                           &device_error));
  EXPECT_EQ(CKR_OK, chaps_->CloseSession(credential_, readonly_session_id));
  EXPECT_EQ(0, slot_id);
  EXPECT_TRUE(state == CKS_RO_PUBLIC_SESSION || state == CKS_RO_USER_FUNCTIONS);
  EXPECT_EQ(CKF_SERIAL_SESSION, flags);
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->GetSessionInfo(credential_, 17, &slot_id, &state, &flags,
                                   &device_error));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->GetSessionInfo(credential_,
                                                      session_id_,
                                                      NULL,
                                                      &state,
                                                      &flags,
                                                      &device_error));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->GetSessionInfo(credential_,
                                                      session_id_,
                                                      &slot_id,
                                                      NULL,
                                                      &flags,
                                                      &device_error));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->GetSessionInfo(credential_,
                                                      session_id_,
                                                      &slot_id,
                                                      &state,
                                                      NULL,
                                                      &device_error));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->GetSessionInfo(credential_,
                                                      session_id_,
                                                      &slot_id,
                                                      &state,
                                                      &flags,
                                                      NULL));
}

TEST_F(TestP11PublicSession, GetOperationState) {
  vector<uint8_t> state;
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->GetOperationState(credential_, 17, &state));
  EXPECT_EQ(CKR_ARGUMENTS_BAD,
            chaps_->GetOperationState(credential_, session_id_, NULL));
}

TEST_F(TestP11PublicSession, SetOperationState) {
  vector<uint8_t> state(10, 0);
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->SetOperationState(credential_, 17, state, 0, 0));
}

TEST_F(TestP11PublicSession, Login) {
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->Login(credential_, 17, CKU_USER, &user_pin_));
  EXPECT_EQ(CKR_USER_TYPE_INVALID, chaps_->Login(credential_, session_id_,
                                                 17, &user_pin_));
  EXPECT_EQ(CKR_OK, chaps_->Login(credential_, session_id_, CKU_USER, NULL));
  EXPECT_EQ(CKR_OK, chaps_->Login(credential_, session_id_,
                                  CKU_USER, &user_pin_));
}

TEST_F(TestP11PublicSession, Logout) {
  CK_RV result = chaps_->Logout(credential_, session_id_);
  EXPECT_TRUE(result == CKR_USER_NOT_LOGGED_IN || result == CKR_OK);
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID, chaps_->Logout(credential_, 17));
  ASSERT_EQ(CKR_OK,
            chaps_->Login(credential_, session_id_, CKU_USER, &user_pin_));
  EXPECT_EQ(CKR_OK, chaps_->Logout(credential_, session_id_));
}

TEST_F(TestP11PublicSession, CreateObject) {
  CK_OBJECT_CLASS class_value = CKO_DATA;
  CK_UTF8CHAR label[] = "A data object";
  CK_UTF8CHAR application[] = "An application";
  CK_BYTE data[] = "Sample data";
  CK_BYTE data2[] = "Sample data 2";
  CK_BBOOL false_value = CK_FALSE;
  CK_ATTRIBUTE attributes[] = {
    {CKA_CLASS, &class_value, sizeof(class_value)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_LABEL, label, sizeof(label)-1},
    {CKA_APPLICATION, application, sizeof(application)-1},
    {CKA_VALUE, data, sizeof(data)}
  };
  CK_ATTRIBUTE attributes2[] = {
    {CKA_VALUE, data2, sizeof(data2)}
  };
  vector<uint8_t> attribute_serial;
  ASSERT_TRUE(SerializeAttributes(attributes, 5, &attribute_serial));
  uint64_t handle = 0;
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->CreateObject(credential_, session_id_,
                                                    attribute_serial, NULL));
  EXPECT_EQ(CKR_OK, chaps_->CreateObject(credential_, session_id_,
                                         attribute_serial, &handle));
  vector<uint8_t> attribute_serial2;
  ASSERT_TRUE(SerializeAttributes(attributes2, 1, &attribute_serial2));
  uint64_t handle2 = 0;
  EXPECT_EQ(CKR_OK, chaps_->CopyObject(credential_,
                                       session_id_,
                                       handle,
                                       attribute_serial2,
                                       &handle2));
  EXPECT_EQ(CKR_OK, chaps_->DestroyObject(credential_, session_id_, handle));
  EXPECT_EQ(CKR_OK, chaps_->DestroyObject(credential_, session_id_, handle2));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->CreateObject(credential_, 17, attribute_serial, &handle));
  EXPECT_EQ(CKR_TEMPLATE_INCOMPLETE, chaps_->CreateObject(credential_,
                                                          session_id_,
                                                          attribute_serial2,
                                                          &handle));
}

TEST_F(TestP11Object, GetObjectSize) {
  uint64_t size;
  EXPECT_EQ(CKR_OK, chaps_->GetObjectSize(credential_, session_id_,
                                          object_handle_, &size));
  EXPECT_EQ(CKR_ARGUMENTS_BAD,
      chaps_->GetObjectSize(credential_, session_id_, object_handle_, NULL));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
      chaps_->GetObjectSize(credential_, 17, object_handle_, &size));
  EXPECT_EQ(CKR_OBJECT_HANDLE_INVALID,
      chaps_->GetObjectSize(credential_, session_id_, 17, &size));
}

TEST_F(TestP11Object, GetAttributeValue) {
  CK_BYTE buffer[100];
  CK_ATTRIBUTE query[1] = {{CKA_VALUE, buffer, sizeof(buffer)}};
  vector<uint8_t> serial_query;
  ASSERT_TRUE(SerializeAttributes(query, 1, &serial_query));
  vector<uint8_t> response;
  EXPECT_EQ(CKR_OK, chaps_->GetAttributeValue(credential_,
                                              session_id_,
                                              object_handle_,
                                              serial_query,
                                              &response));
  EXPECT_TRUE(ParseAndFillAttributes(response, query, 1));
  CK_BYTE data[] = "Sample data";
  EXPECT_EQ(sizeof(data), query[0].ulValueLen);
  EXPECT_EQ(0, memcmp(data, query[0].pValue, query[0].ulValueLen));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->GetAttributeValue(credential_,
                                                         session_id_,
                                                         object_handle_,
                                                         serial_query,
                                                         NULL));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
      chaps_->GetAttributeValue(credential_, 17, object_handle_,
                                serial_query, &response));
  EXPECT_EQ(CKR_OBJECT_HANDLE_INVALID,
      chaps_->GetAttributeValue(credential_, session_id_, 17,
                                serial_query, &response));
}

TEST_F(TestP11Object, SetAttributeValue) {
  CK_BYTE buffer[100];
  memset(buffer, 0xAA, sizeof(buffer));
  CK_ATTRIBUTE attributes[1] = {{CKA_LABEL, buffer, sizeof(buffer)}};
  vector<uint8_t> serial;
  ASSERT_TRUE(SerializeAttributes(attributes, 1, &serial));
  EXPECT_EQ(CKR_OK, chaps_->SetAttributeValue(credential_, session_id_,
                                              object_handle_, serial));
  CK_BYTE buffer2[100];
  memset(buffer2, 0xBB, sizeof(buffer2));
  attributes[0].pValue = buffer2;
  ASSERT_TRUE(SerializeAttributes(attributes, 1, &serial));
  vector<uint8_t> response;
  EXPECT_EQ(CKR_OK, chaps_->GetAttributeValue(credential_, session_id_,
                                              object_handle_, serial,
                                              &response));
  EXPECT_TRUE(ParseAndFillAttributes(response, attributes, 1));
  EXPECT_EQ(0, memcmp(buffer, buffer2, 100));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
      chaps_->SetAttributeValue(credential_, 17, object_handle_, serial));
  EXPECT_EQ(CKR_OBJECT_HANDLE_INVALID,
      chaps_->SetAttributeValue(credential_, session_id_, 17, serial));
}

TEST_F(TestP11Object, FindObjects) {
  vector<uint64_t> objects;
  vector<uint8_t> empty;
  EXPECT_EQ(CKR_OK, chaps_->FindObjectsInit(credential_, session_id_, empty));
  EXPECT_EQ(CKR_OK, chaps_->FindObjects(credential_, session_id_,
                                        10, &objects));
  EXPECT_EQ(CKR_OK, chaps_->FindObjectsFinal(credential_, session_id_));
  EXPECT_GT(objects.size(), 0);
  EXPECT_LT(objects.size(), 11);

  CK_OBJECT_CLASS class_value = CKO_DATA;
  CK_BBOOL false_value = CK_FALSE;
  CK_ATTRIBUTE attributes[2] = {
    {CKA_CLASS, &class_value, sizeof(class_value)},
    {CKA_TOKEN, &false_value, sizeof(false_value)}
  };
  vector<uint8_t> serial;
  ASSERT_TRUE(SerializeAttributes(attributes, 2, &serial));
  EXPECT_EQ(CKR_TEMPLATE_INCONSISTENT,
            chaps_->FindObjectsInit(credential_, session_id_,
                                    vector<uint8_t>(20, 0)));
  EXPECT_EQ(CKR_OK, chaps_->FindObjectsInit(credential_, session_id_, serial));
  EXPECT_EQ(CKR_ARGUMENTS_BAD,
            chaps_->FindObjects(credential_, session_id_, 10, NULL));
  EXPECT_EQ(CKR_ARGUMENTS_BAD,
            chaps_->FindObjects(credential_, session_id_, 10, &objects));
  objects.clear();
  EXPECT_EQ(CKR_OK,
            chaps_->FindObjects(credential_, session_id_, 10, &objects));
  EXPECT_EQ(CKR_OK, chaps_->FindObjectsFinal(credential_, session_id_));
  EXPECT_EQ(objects.size(), 1);
  // Operation state management tests.
  objects.clear();
  EXPECT_EQ(CKR_OPERATION_NOT_INITIALIZED,
            chaps_->FindObjects(credential_, session_id_, 10, &objects));
  EXPECT_EQ(CKR_OPERATION_NOT_INITIALIZED,
            chaps_->FindObjectsFinal(credential_, session_id_));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->FindObjectsInit(credential_, 17, empty));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->FindObjects(credential_, 17, 10, &objects));
  EXPECT_EQ(CKR_SESSION_HANDLE_INVALID,
            chaps_->FindObjectsFinal(credential_, 17));
}

TEST_F(TestP11PublicSession, Encrypt) {
  // Create a session key.
  CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
  CK_KEY_TYPE key_type = CKK_AES;
  CK_BYTE key_value[32] = {0};
  CK_BBOOL false_value = CK_FALSE;
  CK_BBOOL true_value = CK_TRUE;
  CK_ATTRIBUTE key_desc[] = {
    {CKA_CLASS, &key_class, sizeof(key_class)},
    {CKA_KEY_TYPE, &key_type, sizeof(key_type)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_ENCRYPT, &true_value, sizeof(true_value)},
    {CKA_DECRYPT, &true_value, sizeof(true_value)},
    {CKA_VALUE, key_value, sizeof(key_value)}
  };
  vector<uint8_t> key;
  ASSERT_TRUE(SerializeAttributes(key_desc, 6, &key));
  uint64_t key_handle = 0;
  ASSERT_EQ(CKR_OK, chaps_->CreateObject(credential_, session_id_,
                                         key, &key_handle));
  // Test encrypt.
  vector<uint8_t> parameter;
  EXPECT_EQ(CKR_OK, chaps_->EncryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  vector<uint8_t> data(48, 2), encrypted;
  uint64_t not_used = 0;
  const uint64_t max_out_length = 100;
  EXPECT_EQ(CKR_OK, chaps_->Encrypt(credential_,
                                    session_id_,
                                    data,
                                    max_out_length,
                                    &not_used,
                                    &encrypted));
  EXPECT_EQ(CKR_OK, chaps_->EncryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  vector<uint8_t> encrypted2, tmp;
  EXPECT_EQ(CKR_OK, chaps_->EncryptUpdate(credential_,
                                          session_id_,
                                          SubVector(data, 0, 3),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  encrypted2.insert(encrypted2.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->EncryptUpdate(credential_,
                                          session_id_,
                                          SubVector(data, 3, 27),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  encrypted2.insert(encrypted2.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->EncryptUpdate(credential_,
                                          session_id_,
                                          SubVector(data, 30, 18),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  encrypted2.insert(encrypted2.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->EncryptFinal(credential_,
                                         session_id_,
                                         max_out_length,
                                         &not_used,
                                         &tmp));
  encrypted2.insert(encrypted2.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_TRUE(std::equal(encrypted.begin(),
                         encrypted.end(),
                         encrypted2.begin()));
  // Test decrypt.
  EXPECT_EQ(CKR_OK, chaps_->DecryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  vector<uint8_t> decrypted;
  EXPECT_EQ(CKR_OK, chaps_->Decrypt(credential_,
                                    session_id_,
                                    encrypted,
                                    max_out_length,
                                    &not_used,
                                    &decrypted));
  EXPECT_TRUE(std::equal(data.begin(), data.end(), decrypted.begin()));
  decrypted.clear();
  EXPECT_EQ(CKR_OK, chaps_->DecryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  EXPECT_EQ(CKR_OK, chaps_->DecryptUpdate(credential_,
                                          session_id_,
                                          SubVector(encrypted, 0, 16),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  decrypted.insert(decrypted.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->DecryptUpdate(credential_,
                                          session_id_,
                                          SubVector(encrypted, 16, 17),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  decrypted.insert(decrypted.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->DecryptUpdate(credential_,
                                          session_id_,
                                          SubVector(encrypted, 33, 15),
                                          max_out_length,
                                          &not_used,
                                          &tmp));
  decrypted.insert(decrypted.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_EQ(CKR_OK, chaps_->DecryptFinal(credential_,
                                         session_id_,
                                         max_out_length,
                                         &not_used,
                                         &tmp));
  decrypted.insert(decrypted.end(), tmp.begin(), tmp.end());
  tmp.clear();
  EXPECT_TRUE(std::equal(data.begin(), data.end(), decrypted.begin()));
  // Bad arg cases.
  EXPECT_EQ(CKR_OK, chaps_->EncryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->Encrypt(credential_, session_id_, data,
                                               max_out_length, NULL, NULL));
  EXPECT_EQ(CKR_OK, chaps_->DecryptInit(credential_,
                                        session_id_,
                                        CKM_AES_ECB,
                                        parameter,
                                        key_handle));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->Decrypt(credential_, session_id_, data,
                                               max_out_length, NULL, NULL));
}

TEST_F(TestP11PublicSession, Digest) {
  vector<uint8_t> parameter;
  vector<uint8_t> data(100, 2), digest;
  uint64_t not_used = 0;
  const uint64_t max_out_length = 100;
  EXPECT_EQ(CKR_OK, chaps_->DigestInit(credential_, session_id_,
                                       CKM_SHA_1, parameter));
  EXPECT_EQ(CKR_OK, chaps_->Digest(credential_, session_id_, data,
                                   max_out_length, &not_used, &digest));
  EXPECT_EQ(CKR_OK, chaps_->DigestInit(credential_, session_id_,
                                       CKM_SHA_1, parameter));
  EXPECT_EQ(CKR_OK, chaps_->DigestUpdate(credential_, session_id_,
                                         SubVector(data, 0, 10)));
  EXPECT_EQ(CKR_OK, chaps_->DigestUpdate(credential_, session_id_,
                                         SubVector(data, 10, 90)));
  vector<uint8_t> digest2;
  EXPECT_EQ(CKR_OK, chaps_->DigestFinal(credential_, session_id_,
                                        max_out_length, &not_used, &digest2));
  EXPECT_TRUE(std::equal(digest.begin(), digest.end(), digest2.begin()));

  // Create a session key.
  CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
  CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
  CK_BYTE key_value[100] = {0};
  memcpy(key_value, data.data(), 100);
  CK_BBOOL false_value = CK_FALSE;
  CK_BBOOL true_value = CK_TRUE;
  CK_ATTRIBUTE key_desc[] = {
    {CKA_CLASS, &key_class, sizeof(key_class)},
    {CKA_KEY_TYPE, &key_type, sizeof(key_type)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_SIGN, &true_value, sizeof(true_value)},
    {CKA_VERIFY, &true_value, sizeof(true_value)},
    {CKA_VALUE, key_value, sizeof(key_value)}
  };
  vector<uint8_t> key;
  ASSERT_TRUE(SerializeAttributes(key_desc, 6, &key));
  uint64_t key_handle = 0;
  ASSERT_EQ(CKR_OK,
            chaps_->CreateObject(credential_, session_id_, key, &key_handle));
  EXPECT_EQ(CKR_OK,
            chaps_->DigestInit(credential_, session_id_, CKM_SHA_1, parameter));
  EXPECT_EQ(CKR_KEY_INDIGESTIBLE,
            chaps_->DigestKey(credential_, session_id_, key_handle));
}

TEST_F(TestP11PublicSession, Sign) {
  // Create a session key.
  CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
  CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
  CK_BYTE key_value[32] = {0};
  CK_BBOOL false_value = CK_FALSE;
  CK_BBOOL true_value = CK_TRUE;
  CK_ATTRIBUTE key_desc[] = {
    {CKA_CLASS, &key_class, sizeof(key_class)},
    {CKA_KEY_TYPE, &key_type, sizeof(key_type)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_SIGN, &true_value, sizeof(true_value)},
    {CKA_VERIFY, &true_value, sizeof(true_value)},
    {CKA_VALUE, key_value, sizeof(key_value)}
  };
  vector<uint8_t> key;
  ASSERT_TRUE(SerializeAttributes(key_desc, 6, &key));
  uint64_t key_handle = 0;
  ASSERT_EQ(CKR_OK, chaps_->CreateObject(credential_, session_id_,
                                         key, &key_handle));
  // Sign / Verify using SHA-1 HMAC.
  vector<uint8_t> parameter;
  EXPECT_EQ(CKR_OK, chaps_->SignInit(credential_,
                                     session_id_,
                                     CKM_SHA_1_HMAC,
                                     parameter,
                                     key_handle));
  vector<uint8_t> data(100, 2), signature;
  uint64_t not_used = 0;
  const uint64_t max_out_length = 100;
  EXPECT_EQ(CKR_OK, chaps_->Sign(credential_,
                                 session_id_,
                                 data,
                                 max_out_length,
                                 &not_used,
                                 &signature));
  EXPECT_EQ(signature.size(), 20);
  EXPECT_EQ(CKR_OK, chaps_->VerifyInit(credential_,
                                       session_id_,
                                       CKM_SHA_1_HMAC,
                                       parameter,
                                       key_handle));
  EXPECT_EQ(CKR_OK, chaps_->Verify(credential_, session_id_, data, signature));
}

TEST_F(TestP11UserSession, GenerateKey) {
  vector<uint8_t> empty;
  uint64_t key_handle;
  CK_BBOOL false_value = CK_FALSE;
  CK_BBOOL true_value = CK_TRUE;
  CK_ULONG key_length = 32;
  CK_ATTRIBUTE attributes[] = {
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_PRIVATE, &true_value, sizeof(true_value)},
    {CKA_ENCRYPT, &true_value, sizeof(true_value)},
    {CKA_DECRYPT, &true_value, sizeof(true_value)},
    {CKA_VALUE_LEN, &key_length, sizeof(key_length)}
  };
  vector<uint8_t> serialized;
  ASSERT_TRUE(SerializeAttributes(attributes, 5, &serialized));
  ASSERT_EQ(CKR_OK, chaps_->GenerateKey(credential_,
                                        session_id_,
                                        CKM_AES_KEY_GEN,
                                        empty,
                                        serialized,
                                        &key_handle));
  EXPECT_EQ(CKR_OK,
            chaps_->DestroyObject(credential_, session_id_, key_handle));
}

TEST_F(TestP11UserSession, GenerateKeyPair) {
  vector<uint8_t> empty;
  uint64_t public_key, private_key;
  CK_ULONG bits = 1024;
  CK_BYTE e[] = {1, 0, 1};
  CK_BBOOL false_value = CK_FALSE;
  CK_BBOOL true_value = CK_TRUE;
  CK_ATTRIBUTE public_attributes[] = {
    {CKA_ENCRYPT, &true_value, sizeof(true_value)},
    {CKA_VERIFY, &true_value, sizeof(true_value)},
    {CKA_WRAP, &false_value, sizeof(false_value)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_PRIVATE, &false_value, sizeof(false_value)},
    {CKA_MODULUS_BITS, &bits, sizeof(bits)},
    {CKA_PUBLIC_EXPONENT, e, sizeof(e)}
  };
  CK_BYTE id[] = {'A'};
  CK_ATTRIBUTE private_attributes[] = {
    {CKA_DECRYPT, &true_value, sizeof(true_value)},
    {CKA_SIGN, &true_value, sizeof(true_value)},
    {CKA_UNWRAP, &false_value, sizeof(false_value)},
    {CKA_SENSITIVE, &true_value, sizeof(true_value)},
    {CKA_TOKEN, &false_value, sizeof(false_value)},
    {CKA_PRIVATE, &true_value, sizeof(true_value)},
    {CKA_ID, &id, sizeof(id)},
  };
  vector<uint8_t> public_serialized, private_serialized;
  ASSERT_TRUE(SerializeAttributes(public_attributes, 7, &public_serialized));
  ASSERT_TRUE(SerializeAttributes(private_attributes, 7, &private_serialized));
  ASSERT_EQ(CKR_OK, chaps_->GenerateKeyPair(credential_,
                                            session_id_,
                                            CKM_RSA_PKCS_KEY_PAIR_GEN,
                                            empty,
                                            public_serialized,
                                            private_serialized,
                                            &public_key,
                                            &private_key));
  EXPECT_EQ(CKR_OK,
            chaps_->DestroyObject(credential_, session_id_, public_key));
  EXPECT_EQ(CKR_OK,
            chaps_->DestroyObject(credential_, session_id_, private_key));
}

TEST_F(TestP11PublicSession, WrapKey) {
  uint64_t not_used;
  vector<uint8_t> empty;
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->WrapKey(credential_,
                                               session_id_,
                                               CKM_RSA_PKCS, empty,
                                               0, 1,
                                               1000, &not_used,
                                               NULL));
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->UnwrapKey(credential_, session_id_,
                                                 CKM_RSA_PKCS, empty, 0,
                                                 empty, empty, NULL));
}

TEST_F(TestP11PublicSession, DeriveKey) {
  vector<uint8_t> empty;
  EXPECT_EQ(CKR_ARGUMENTS_BAD, chaps_->DeriveKey(credential_,
                                                 session_id_,
                                                 CKM_SHA1_KEY_DERIVATION,
                                                 empty,
                                                 1,
                                                 empty,
                                                 NULL));
}

TEST_F(TestP11PublicSession, Random) {
  vector<uint8_t> data(8, 0xAA);
  EXPECT_EQ(CKR_OK, chaps_->SeedRandom(credential_, session_id_, data));
  EXPECT_EQ(CKR_OK,
            chaps_->GenerateRandom(credential_, session_id_, 32, &data));
}

}  // namespace chaps

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
