// Copyright 2021 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 "shill/pkcs11_data_store.h"

#include <map>
#include <string>
#include <vector>

#include <base/check.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/cryptohome.h>
#include <brillo/map_utils.h>
#include <chaps/attributes.h>
#include <chaps/chaps_proxy_mock.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

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

namespace {

const uint64_t kSession = 7;  // Arbitrary non-zero value.
const CK_SLOT_ID kDefaultSlot = 1;

class ScopedFakeSalt {
 public:
  ScopedFakeSalt() : salt_(128, 0) {
    brillo::cryptohome::home::SetSystemSalt(&salt_);
  }
  ~ScopedFakeSalt() { brillo::cryptohome::home::SetSystemSalt(nullptr); }

 private:
  std::string salt_;
};

class ScopedDisableVerboseLogging {
 public:
  ScopedDisableVerboseLogging()
      : original_severity_(logging::GetMinLogLevel()) {
    logging::SetMinLogLevel(logging::LOGGING_INFO);
  }
  ~ScopedDisableVerboseLogging() {
    logging::SetMinLogLevel(original_severity_);
  }

 private:
  logging::LogSeverity original_severity_;
};

}  // namespace

namespace shill {

typedef chaps::ChapsProxyMock Pkcs11Mock;

// Implements a fake PKCS #11 object store.  Labeled data blobs can be stored
// and later retrieved.  The mocked interface is ChapsInterface so these
// tests must be linked with the Chaps PKCS #11 library.  The mock class itself
// is part of the Chaps package; it is reused here to avoid duplication (see
// chaps_proxy_mock.h).
class PKCS11DataStoreTest : public testing::Test {
 public:
  PKCS11DataStoreTest()
      : pkcs11_(false),  // Do not pre-initialize the mock PKCS #11 library.
                         // This just controls whether the first call to
                         // C_Initialize returns 'already initialized'.
        next_handle_(1) {}
  PKCS11DataStoreTest(const PKCS11DataStoreTest&) = delete;
  PKCS11DataStoreTest& operator=(const PKCS11DataStoreTest&) = delete;

  ~PKCS11DataStoreTest() override = default;

  void SetUp() override {
    std::vector<uint64_t> slot_list = {0, 1};
    ON_CALL(pkcs11_, GetSlotList(_, _, _))
        .WillByDefault(DoAll(SetArgPointee<2>(slot_list), Return(0)));
    ON_CALL(pkcs11_, OpenSession(_, _, _, _))
        .WillByDefault(DoAll(SetArgPointee<3>(kSession), Return(0)));
    ON_CALL(pkcs11_, CloseSession(_, _)).WillByDefault(Return(0));
    ON_CALL(pkcs11_, CreateObject(_, _, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::CreateObject));
    ON_CALL(pkcs11_, DestroyObject(_, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::DestroyObject));
    ON_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::GetAttributeValue));
    ON_CALL(pkcs11_, SetAttributeValue(_, _, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::SetAttributeValue));
    ON_CALL(pkcs11_, FindObjectsInit(_, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::FindObjectsInit));
    ON_CALL(pkcs11_, FindObjects(_, _, _, _))
        .WillByDefault(Invoke(this, &PKCS11DataStoreTest::FindObjects));
    ON_CALL(pkcs11_, FindObjectsFinal(_, _)).WillByDefault(Return(0));
  }

  // Stores a new labeled object, only CKA_LABEL and CKA_VALUE are relevant.
  virtual uint32_t CreateObject(const brillo::SecureBlob& isolate,
                                uint64_t session_id,
                                const std::vector<uint8_t>& attributes,
                                uint64_t* new_object_handle) {
    *new_object_handle = next_handle_++;
    std::string label = GetValue(attributes, CKA_LABEL);
    handles_[*new_object_handle] = label;
    values_[label] = GetValue(attributes, CKA_VALUE);
    labels_[label] = *new_object_handle;
    return CKR_OK;
  }

  // Deletes a labeled object.
  virtual uint32_t DestroyObject(const brillo::SecureBlob& isolate,
                                 uint64_t session_id,
                                 uint64_t object_handle) {
    std::string label = handles_[object_handle];
    handles_.erase(object_handle);
    values_.erase(label);
    labels_.erase(label);
    return CKR_OK;
  }

  // Supports reading CKA_VALUE.
  virtual uint32_t GetAttributeValue(const brillo::SecureBlob& isolate,
                                     uint64_t session_id,
                                     uint64_t object_handle,
                                     const std::vector<uint8_t>& attributes_in,
                                     std::vector<uint8_t>* attributes_out) {
    std::string label = handles_[object_handle];
    std::string value = values_[label];
    chaps::Attributes parsed;
    parsed.Parse(attributes_in);
    if (parsed.num_attributes() == 1 &&
        parsed.attributes()[0].type == CKA_LABEL)
      value = label;
    if (parsed.num_attributes() != 1 ||
        (parsed.attributes()[0].type != CKA_VALUE &&
         parsed.attributes()[0].type != CKA_LABEL) ||
        (parsed.attributes()[0].pValue &&
         parsed.attributes()[0].ulValueLen != value.size()))
      return CKR_GENERAL_ERROR;
    parsed.attributes()[0].ulValueLen = value.size();
    if (parsed.attributes()[0].pValue)
      memcpy(parsed.attributes()[0].pValue, value.data(), value.size());
    parsed.Serialize(attributes_out);
    return CKR_OK;
  }

  // Supports writing CKA_VALUE.
  virtual uint32_t SetAttributeValue(const brillo::SecureBlob& isolate,
                                     uint64_t session_id,
                                     uint64_t object_handle,
                                     const std::vector<uint8_t>& attributes) {
    values_[handles_[object_handle]] = GetValue(attributes, CKA_VALUE);
    return CKR_OK;
  }

  // Finds stored objects by CKA_LABEL or CKA_VALUE. If no CKA_LABEL or
  // CKA_VALUE, find all objects.
  virtual uint32_t FindObjectsInit(const brillo::SecureBlob& isolate,
                                   uint64_t session_id,
                                   const std::vector<uint8_t>& attributes) {
    std::string label = GetValue(attributes, CKA_LABEL);
    std::string value = GetValue(attributes, CKA_VALUE);
    found_objects_.clear();
    if (label.empty() && value.empty()) {
      // Find all objects.
      found_objects_ = brillo::GetMapKeysAsVector(handles_);
    } else if (!label.empty() && labels_.count(label) > 0) {
      // Find only the object with |label|.
      found_objects_.push_back(labels_[label]);
    } else {
      // Find all objects with |value|.
      for (const auto& item : values_) {
        if (item.second == value && labels_.count(item.first) > 0) {
          found_objects_.push_back(labels_[item.first]);
        }
      }
    }
    return CKR_OK;
  }

  // Reports a 'found' object based on find_status_.
  virtual uint32_t FindObjects(const brillo::SecureBlob& isolate,
                               uint64_t session_id,
                               uint64_t max_object_count,
                               std::vector<uint64_t>* object_list) {
    while (!found_objects_.empty() && object_list->size() < max_object_count) {
      object_list->push_back(found_objects_.back());
      found_objects_.pop_back();
    }
    return CKR_OK;
  }

 protected:
  NiceMock<Pkcs11Mock> pkcs11_;

 private:
  // A helper to pull the value for a given attribute out of a serialized
  // template.
  std::string GetValue(const std::vector<uint8_t>& attributes,
                       CK_ATTRIBUTE_TYPE type) {
    chaps::Attributes parsed;
    parsed.Parse(attributes);
    CK_ATTRIBUTE_PTR array = parsed.attributes();
    for (CK_ULONG i = 0; i < parsed.num_attributes(); ++i) {
      if (array[i].type == type) {
        if (!array[i].pValue)
          return "";
        return std::string(reinterpret_cast<char*>(array[i].pValue),
                           array[i].ulValueLen);
      }
    }
    return "";
  }

  std::map<std::string, std::string> values_;  // The fake store: label->value
  std::map<uint64_t, std::string> handles_;    // The fake store: handle->label
  std::map<std::string, uint64_t> labels_;     // The fake store: label->handle
  std::vector<uint64_t> found_objects_;        // The most recent search results
  uint64_t next_handle_;                       // Tracks handle assignment
  ScopedFakeSalt fake_system_salt_;
  // We want to avoid all the Chaps verbose logging.
  ScopedDisableVerboseLogging no_verbose_logging;
};

// Exercises the key store when PKCS #11 returns success.  This exercises all
// non-error-handling code paths.
TEST_F(PKCS11DataStoreTest, Pkcs11Success) {
  Pkcs11DataStore key_store;
  std::string blob;
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test", &blob));
  EXPECT_TRUE(key_store.Write(kDefaultSlot, "test", "test_data"));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "test", &blob));
  EXPECT_EQ("test_data", blob);
  // Try with a different key name.
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test2", &blob));
  EXPECT_TRUE(key_store.Write(kDefaultSlot, "test2", "test_data2"));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "test2", &blob));
  EXPECT_EQ("test_data2", blob);
  // Read the original key again.
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "test", &blob));
  EXPECT_EQ("test_data", blob);
  // Replace key data.
  EXPECT_TRUE(key_store.Write(kDefaultSlot, "test", "test_data3"));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "test", &blob));
  EXPECT_EQ("test_data3", blob);
  // Delete key data.
  EXPECT_TRUE(key_store.Delete(kDefaultSlot, "test2"));
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test2", &blob));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "test", &blob));
}

// Tests the key store when PKCS #11 fails to open a session.
TEST_F(PKCS11DataStoreTest, NoSession) {
  EXPECT_CALL(pkcs11_, OpenSession(_, _, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  Pkcs11DataStore key_store;
  std::string blob;
  EXPECT_FALSE(key_store.Write(kDefaultSlot, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test", &blob));
}

// Tests the key store when PKCS #11 fails to create an object.
TEST_F(PKCS11DataStoreTest, CreateObjectFail) {
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  Pkcs11DataStore key_store;
  std::string blob;
  EXPECT_FALSE(key_store.Write(kDefaultSlot, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test", &blob));
}

// Tests the key store when PKCS #11 fails to read attribute values.
TEST_F(PKCS11DataStoreTest, ReadValueFail) {
  EXPECT_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  Pkcs11DataStore key_store;
  std::string blob;
  EXPECT_TRUE(key_store.Write(kDefaultSlot, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "test", &blob));
}

// Tests the key store when PKCS #11 fails to delete key data.
TEST_F(PKCS11DataStoreTest, DeleteValueFail) {
  EXPECT_CALL(pkcs11_, DestroyObject(_, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  Pkcs11DataStore key_store;
  EXPECT_TRUE(key_store.Write(kDefaultSlot, "test", "test_data"));
  EXPECT_FALSE(key_store.Write(kDefaultSlot, "test", "test_data2"));
  EXPECT_FALSE(key_store.Delete(kDefaultSlot, "test"));
}

// Tests that the DeleteByPrefix() method removes the correct objects and only
// the correct objects.
TEST_F(PKCS11DataStoreTest, DeleteByPrefix) {
  Pkcs11DataStore key_store;

  // Test with no keys.
  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultSlot, "prefix"));

  // Test with a single matching key.
  ASSERT_TRUE(key_store.Write(kDefaultSlot, "prefix_test", "test"));
  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultSlot, "prefix"));
  std::string blob;
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "prefix_test", &blob));

  // Test with a single non-matching key.
  ASSERT_TRUE(key_store.Write(kDefaultSlot, "_prefix_", "test"));
  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultSlot, "prefix"));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "_prefix_", &blob));

  // Test with an empty prefix.
  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultSlot, ""));
  EXPECT_FALSE(key_store.Read(kDefaultSlot, "_prefix_", &blob));

  // Test with multiple matching and non-matching keys.
  const int kNumKeys = 110;  // Pkcs11DataStore max is 100 for FindObjects.
  key_store.Write(kDefaultSlot, "other1", "test");
  for (int i = 0; i < kNumKeys; ++i) {
    std::string key_name = std::string("prefix") + base::NumberToString(i);
    key_store.Write(kDefaultSlot, key_name, std::string(key_name));
  }
  ASSERT_TRUE(key_store.Write(kDefaultSlot, "other2", "test"));
  ASSERT_TRUE(key_store.DeleteByPrefix(kDefaultSlot, "prefix"));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "other1", &blob));
  EXPECT_TRUE(key_store.Read(kDefaultSlot, "other2", &blob));
  for (int i = 0; i < kNumKeys; ++i) {
    std::string key_name = std::string("prefix") + base::NumberToString(i);
    EXPECT_FALSE(key_store.Read(kDefaultSlot, key_name, &blob));
  }
}

}  // namespace shill
