// Copyright 2017 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 <tuple>
#include <vector>

#include <base/bind.h>
#include <chaps/attributes.h>
#include <chaps/chaps_proxy_mock.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

#include "cryptohome/cert/cert_provision_cryptohome.h"
#include "cryptohome/cert/cert_provision_keystore.h"
#include "cryptohome/cert/cert_provision_pca.h"
#include "cryptohome/cert/cert_provision_util.h"
#include "cryptohome/cert_provision.h"

#include "cryptohome/cert/mock_cert_provision_cryptohome.h"
#include "cryptohome/cert/mock_cert_provision_keystore.h"
#include "cryptohome/cert/mock_cert_provision_pca.h"

#include "cert/cert_provision.pb.h"  // NOLINT(build/include)

using ::brillo::SecureBlob;
using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SetArgPointee;

namespace {

// Some arbitrary certificate label used for testing.
const char kCertLabel[] = "test";

// Some non-zero handles for PKCS#11 session and object.
const CK_SESSION_HANDLE kSession = 17;
const CK_OBJECT_HANDLE kObject = 112;

}  // namespace

namespace cert_provision {

// Test class for testing KeyStoreImpl.
class CertProvisionKeyStoreTest : public testing::Test {
 public:
  using Pkcs11Mock = chaps::ChapsProxyMock;
  CertProvisionKeyStoreTest() = default;

  void SetUp() {
    ON_CALL(pkcs11_, OpenSession(_, _, _, _))
        .WillByDefault(DoAll(SetArgPointee<3>(kSession), Return(0)));
    ON_CALL(pkcs11_, FindObjects(_, _, _, _))
        .WillByDefault(Invoke(this, &CertProvisionKeyStoreTest::FindObjects));
    ON_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
        .WillByDefault(
            Invoke(this, &CertProvisionKeyStoreTest::GetAttributeValue));
    ON_CALL(pkcs11_, CreateObject(_, _, _, _))
        .WillByDefault(Invoke(this, &CertProvisionKeyStoreTest::CreateObject));
    ON_CALL(pkcs11_, Sign(_, _, _, _, _, _))
        .WillByDefault(Invoke(this, &CertProvisionKeyStoreTest::Sign));
  }

  // Mocks looking for objects.
  uint32_t FindObjects(const SecureBlob& /* isolate_credential */,
                       uint64_t /* session_id */,
                       uint64_t max_object_count,
                       std::vector<uint64_t>* objects) {
    while (!found_objects_.empty() && objects->size() < max_object_count) {
      objects->push_back(found_objects_.back());
      found_objects_.pop_back();
    }
    return CKR_OK;
  }

  // Mocks getting CKA_VALUE for an object.
  uint32_t GetAttributeValue(const SecureBlob& /* isolate_credential */,
                             uint64_t /* session_id */,
                             uint64_t /* object_handle */,
                             const std::vector<uint8_t>& attributes_in,
                             std::vector<uint8_t>* attributes_out) {
    chaps::Attributes chaps_attr;
    chaps_attr.Parse(attributes_in);
    CK_ATTRIBUTE* attr = chaps_attr.attributes();
    if (chaps_attr.num_attributes() != 1 || attr->type != CKA_VALUE) {
      return CKR_GENERAL_ERROR;
    }
    if (attr->pValue) {
      if (attr->ulValueLen == object_value_.size()) {
        memcpy(attr->pValue, object_value_.data(), object_value_.size());
      } else {
        return CKR_GENERAL_ERROR;
      }
    }
    attr->ulValueLen = object_value_.size();
    chaps_attr.Serialize(attributes_out);
    return CKR_OK;
  }

  // Mocks creating an object.
  uint32_t CreateObject(const SecureBlob& /* isolate_credential */,
                        uint64_t /* session_id */,
                        const std::vector<uint8_t>& attributes,
                        uint64_t* new_object_handle) {
    *new_object_handle = kObject;
    object_value_.clear();

    chaps::Attributes chaps_attr;
    chaps_attr.Parse(attributes);
    CK_ATTRIBUTE* attr = chaps_attr.attributes();
    for (CK_ULONG i = 0; i < chaps_attr.num_attributes(); ++i, ++attr) {
      if (attr->type == CKA_VALUE) {
        object_value_.assign(reinterpret_cast<char*>(attr->pValue),
                             attr->ulValueLen);
        break;
      }
    }
    return CKR_OK;
  }

  uint32_t Sign(const brillo::SecureBlob& /* isolate_credential */,
                uint64_t /* session_id */,
                const std::vector<uint8_t>& /* data */,
                uint64_t /* max_out_length */,
                uint64_t* actual_out_length,
                std::vector<uint8_t>* signature) {
    *actual_out_length = signature_.size();
    uint8_t* sig_data =
        reinterpret_cast<uint8_t*>(const_cast<char*>(signature_.data()));
    signature->assign(sig_data, sig_data + signature_.size());
    return CKR_OK;
  }

 protected:
  NiceMock<Pkcs11Mock> pkcs11_{false /* do not pre-initialize */};
  KeyStoreImpl key_store_;

  // Objects to return from C_FindObjects.
  std::vector<uint64_t> found_objects_;

  // CKA_VALUE attribute for getting/setting.
  std::string object_value_;

  // Signature returned by Sign().
  std::string signature_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CertProvisionKeyStoreTest);
};

// Checks that initialization succeeds under normal conditions
// and that the session is closed on deleting the KeyStoreImpl object.
TEST_F(CertProvisionKeyStoreTest, InitSuccess) {
  EXPECT_TRUE(key_store_.Init());
  EXPECT_CALL(pkcs11_, CloseSession(_, _)).WillOnce(Return(0));
}

// Checks that initialization fails, if session cannot be opened.
TEST_F(CertProvisionKeyStoreTest, InitFailureSession) {
  EXPECT_CALL(pkcs11_, OpenSession(_, _, _, _))
      .WillOnce(Return(CKR_GENERAL_ERROR));
  EXPECT_FALSE(key_store_.Init());
  EXPECT_CALL(pkcs11_, CloseSession(_, _)).Times(0);
  key_store_.TearDown();
}

// Checks that reading an existing ProvisionStatus returns the right data.
TEST_F(CertProvisionKeyStoreTest, ReadProvisionStatusSuccessExists) {
  EXPECT_TRUE(key_store_.Init());

  ProvisionStatus provision_status_stored;
  provision_status_stored.set_key_id("100");  // some random value
  provision_status_stored.SerializeToString(&object_value_);
  found_objects_.assign({kObject});

  // Expect to be called twice - once to get the size, then the value itself.
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, kSession, kObject, _, _)).Times(2);

  ProvisionStatus provision_status;
  EXPECT_TRUE(key_store_.ReadProvisionStatus(kCertLabel, &provision_status));
  EXPECT_EQ(provision_status_stored.key_id(), provision_status.key_id());
}

// Checks that if there is no ProvisionStatus object, an empty proto is
// returned.
TEST_F(CertProvisionKeyStoreTest, ReadProvisionStatusSuccessNew) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.clear();
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _)).Times(0);

  ProvisionStatus provision_status;
  EXPECT_TRUE(key_store_.ReadProvisionStatus(kCertLabel, &provision_status));
  EXPECT_FALSE(provision_status.provisioned());
}

// Checks ReadProvisionStatus behavior if not initialized.
TEST_F(CertProvisionKeyStoreTest, ReadProvisionStatusFailureNotInit) {
  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _)).Times(0);
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _)).Times(0);

  ProvisionStatus provision_status;
  EXPECT_FALSE(key_store_.ReadProvisionStatus(kCertLabel, &provision_status));
}

// Checks ReadProvisionStatus behavior in case of GetAttribute error.
TEST_F(CertProvisionKeyStoreTest, ReadProvisionStatusFailureGet) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject});
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, kSession, kObject, _, _))
      .WillOnce(Return(CKR_GENERAL_ERROR));

  ProvisionStatus provision_status;
  EXPECT_FALSE(key_store_.ReadProvisionStatus(kCertLabel, &provision_status));
}

// Checks ReadProvisionStatus behavior if there are multiple objects.
TEST_F(CertProvisionKeyStoreTest, ReadProvisionStatusFailureMultiple) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject, kObject+1});
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _)).Times(0);

  ProvisionStatus provision_status;
  EXPECT_FALSE(key_store_.ReadProvisionStatus(kCertLabel, &provision_status));
}

// Checks that KeyStoreImpl saves ProvisionStatus if there was no previous
// ProvisionStatus objects.
TEST_F(CertProvisionKeyStoreTest, WriteProvisionStatusSuccessNew) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.clear();

  EXPECT_CALL(pkcs11_, DestroyObject(_, _, _)).Times(0);
  EXPECT_CALL(pkcs11_, CreateObject(_, kSession, _, _));

  ProvisionStatus provision_status;
  provision_status.set_key_id("200");  // some random value
  EXPECT_TRUE(key_store_.WriteProvisionStatus(kCertLabel, provision_status));
  EXPECT_EQ(provision_status.SerializeAsString(), object_value_);
}

// Checks that KeyStoreImpl saves ProvisionStatus if there was already some
// ProvisionStatus object(s).
TEST_F(CertProvisionKeyStoreTest, WriteProvisionStatusSuccessExist) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject+1, kObject+2});

  EXPECT_CALL(pkcs11_, DestroyObject(_, kSession, kObject+1));
  EXPECT_CALL(pkcs11_, DestroyObject(_, kSession, kObject+2));
  EXPECT_CALL(pkcs11_, CreateObject(_, kSession, _, _));

  ProvisionStatus provision_status;
  provision_status.set_key_id("200");  // some random value
  EXPECT_TRUE(key_store_.WriteProvisionStatus(kCertLabel, provision_status));
  EXPECT_EQ(provision_status.SerializeAsString(), object_value_);
}

// Checks WriteProvisionStatus behavior if not initialized.
TEST_F(CertProvisionKeyStoreTest, WriteProvisionStatusFailureNotInit) {
  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _)).Times(0);
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _)).Times(0);

  ProvisionStatus provision_status;
  provision_status.set_key_id("200");  // some random value
  EXPECT_FALSE(key_store_.WriteProvisionStatus(kCertLabel, provision_status));
}

// Checks WriteProvisionStatus behavior in case of CreateObject error.
TEST_F(CertProvisionKeyStoreTest, WriteProvisionStatusFailureCreate) {
  EXPECT_TRUE(key_store_.Init());

  EXPECT_CALL(pkcs11_, CreateObject(_, kSession, _, _))
      .WillOnce(Return(CKR_GENERAL_ERROR));

  ProvisionStatus provision_status;
  EXPECT_FALSE(key_store_.WriteProvisionStatus(kCertLabel, provision_status));
}

// Checks that DeleteKeys succeeds if there are no objects to delete.
TEST_F(CertProvisionKeyStoreTest, DeleteKeysSuccessEmpty) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.clear();

  EXPECT_CALL(pkcs11_, DestroyObject(_, _, _)).Times(0);

  std::string key_id = "300";  // some random value
  EXPECT_TRUE(key_store_.DeleteKeys(key_id, kCertLabel));
}

// Checks that DeleteKeys delets all required objects.
TEST_F(CertProvisionKeyStoreTest, DeleteKeysSuccess) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject+1, kObject+2});

  EXPECT_CALL(pkcs11_, DestroyObject(_, kSession, kObject+1));
  EXPECT_CALL(pkcs11_, DestroyObject(_, kSession, kObject+2));

  std::string key_id = "300";  // some random value
  EXPECT_TRUE(key_store_.DeleteKeys(key_id, kCertLabel));
}

// Checks DeleteKeys behavior if not initialized.
TEST_F(CertProvisionKeyStoreTest, DeleteKeysFailureNotInit) {
  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _)).Times(0);

  std::string key_id = "300";  // some random value
  EXPECT_FALSE(key_store_.DeleteKeys(key_id, kCertLabel));
}

// Checks that DeleteKeys ignores DestroyObject errors.
TEST_F(CertProvisionKeyStoreTest, DeleteKeysSuccessDestroyError) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject});
  EXPECT_CALL(pkcs11_, DestroyObject(_, kSession, kObject))
      .WillOnce(Return(CKR_GENERAL_ERROR));

  std::string key_id = "300";  // some random value
  EXPECT_TRUE(key_store_.DeleteKeys(key_id, kCertLabel));
}

// Checks that Sign succeeds if there is a key.
TEST_F(CertProvisionKeyStoreTest, SignSuccess) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject});

  std::string key_id = "400";  // some arbitrary value
  std::string data = "data";  // arbitrary data to sign

  signature_ = "sig-sha1";
  EXPECT_CALL(pkcs11_, SignInit(_, kSession, CKM_SHA1_RSA_PKCS, _, kObject));
  EXPECT_CALL(pkcs11_, Sign(_, kSession, _, _, _, _));
  std::string sig;
  EXPECT_TRUE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA1_RSA_PKCS, data, &sig));
  EXPECT_EQ("sig-sha1", sig);

  found_objects_.assign({kObject});

  signature_ = "sig-sha256";
  EXPECT_CALL(pkcs11_, SignInit(_, kSession, CKM_SHA256_RSA_PKCS, _, kObject));
  EXPECT_CALL(pkcs11_, Sign(_, kSession, _, _, _, _));
  sig.clear();
  EXPECT_TRUE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA256_RSA_PKCS, data, &sig));
  EXPECT_EQ("sig-sha256", sig);

  found_objects_.assign({kObject});

  signature_ = "sig-sha256-pss";
  EXPECT_CALL(pkcs11_,
              SignInit(_, kSession, CKM_SHA256_RSA_PKCS_PSS, _, kObject));
  EXPECT_CALL(pkcs11_, Sign(_, kSession, _, _, _, _));
  sig.clear();
  EXPECT_TRUE(key_store_.Sign(key_id, kCertLabel, SignMechanism::SHA256_RSA_PSS,
                              data, &sig));
  EXPECT_EQ("sig-sha256-pss", sig);
}

// Checks that Sign fails if there's no key.
TEST_F(CertProvisionKeyStoreTest, SignFailureNoKey) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.clear();

  EXPECT_CALL(pkcs11_, SignInit(_, _, _, _, _)).Times(0);
  EXPECT_CALL(pkcs11_, Sign(_, _, _, _, _, _)).Times(0);

  std::string key_id = "400";  // some arbitrary value
  std::string data = "data";  // arbitrary data to sign
  std::string sig;
  EXPECT_FALSE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA1_RSA_PKCS, data, &sig));
}

// Checks Sign behavior if not initialized.
TEST_F(CertProvisionKeyStoreTest, SignFailureNotInit) {
  found_objects_.assign({kObject});

  EXPECT_CALL(pkcs11_, SignInit(_, _, _, _, _)).Times(0);
  EXPECT_CALL(pkcs11_, Sign(_, _, _, _, _, _)).Times(0);

  std::string key_id = "400";  // some arbitrary value
  std::string data = "data";  // arbitrary data to sign
  std::string sig;
  EXPECT_FALSE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA1_RSA_PKCS, data, &sig));
}

// Checks WriteProvisionStatus behavior in case of SignInit error.
TEST_F(CertProvisionKeyStoreTest, SignFailureSignInit) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject});

  EXPECT_CALL(pkcs11_, SignInit(_, kSession, CKM_SHA1_RSA_PKCS, _, kObject))
      .WillOnce(Return(CKR_GENERAL_ERROR));
  EXPECT_CALL(pkcs11_, Sign(_, _, _, _, _, _)).Times(0);
  std::string key_id = "400";  // some arbitrary value
  std::string data = "data";  // arbitrary data to sign
  std::string sig;
  EXPECT_FALSE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA1_RSA_PKCS, data, &sig));
}

// Checks WriteProvisionStatus behavior in case of SignInit error.
TEST_F(CertProvisionKeyStoreTest, SignFailureSign) {
  EXPECT_TRUE(key_store_.Init());

  found_objects_.assign({kObject});

  EXPECT_CALL(pkcs11_, SignInit(_, kSession, CKM_SHA1_RSA_PKCS, _, kObject));
  EXPECT_CALL(pkcs11_, Sign(_, kSession, _, _, _, _))
      .WillOnce(Return(CKR_GENERAL_ERROR));
  std::string key_id = "400";  // some arbitrary value
  std::string data = "data";  // arbitrary data to sign
  std::string sig;
  EXPECT_FALSE(key_store_.Sign(
      key_id, kCertLabel, SignMechanism::SHA1_RSA_PKCS, data, &sig));
}

}  // namespace cert_provision
