//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "attestation/server/pkcs11_key_store.h"

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

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <chaps/attributes.h>
#include <chaps/chaps_proxy_mock.h>
#include <chaps/token_manager_client_mock.h>
#include <brillo/cryptohome.h>
#include <brillo/map_utils.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::SetArgumentPointee;

namespace {

const uint64_t kSession = 7;  // Arbitrary non-zero value.
const char kDefaultUser[] = "test_user";

const char kValidPublicKeyHex[] =
    "3082010A0282010100"
    "961037BC12D2A298BEBF06B2D5F8C9B64B832A2237F8CF27D5F96407A6041A4D"
    "AD383CB5F88E625F412E8ACD5E9D69DF0F4FA81FCE7955829A38366CBBA5A2B1"
    "CE3B48C14B59E9F094B51F0A39155874C8DE18A0C299EBF7A88114F806BE4F25"
    "3C29A509B10E4B19E31675AFE3B2DA77077D94F43D8CE61C205781ED04D183B4"
    "C349F61B1956C64B5398A3A98FAFF17D1B3D9120C832763EDFC8F4137F6EFBEF"
    "46D8F6DE03BD00E49DEF987C10BDD5B6F8758B6A855C23C982DDA14D8F0F2B74"
    "E6DEFA7EEE5A6FC717EB0FF103CB8049F693A2C8A5039EF1F5C025DC44BD8435"
    "E8D8375DADE00E0C0F5C196E04B8483CC98B1D5B03DCD7E0048B2AB343FFC11F"
    "0203"
    "010001";

const char kValidCertificateHex[] =
    "3082040f308202f7a003020102020900bd0f8fd6bf496b67300d06092a864886"
    "f70d01010b050030819d310b3009060355040613025553311330110603550408"
    "0c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e20"
    "5669657731133011060355040a0c0a4368726f6d69756d4f533111300f060355"
    "040b0c08556e6974546573743117301506035504030c0e506b637331314b6579"
    "53746f72653120301e06092a864886f70d010901161174657374406368726f6d"
    "69756d2e6f7267301e170d3135303231383137303132345a170d313731313133"
    "3137303132345a30819d310b3009060355040613025553311330110603550408"
    "0c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e20"
    "5669657731133011060355040a0c0a4368726f6d69756d4f533111300f060355"
    "040b0c08556e6974546573743117301506035504030c0e506b637331314b6579"
    "53746f72653120301e06092a864886f70d010901161174657374406368726f6d"
    "69756d2e6f726730820122300d06092a864886f70d01010105000382010f0030"
    "82010a0282010100a8fb9e12b1e5298b9a24fabc3901d00c32057392c763836e"
    "0b55cff8e67d39b9b9853920fd615688b3e13c03a10cb5668187819172d1d269"
    "70f0ff8d4371ac581f6970a0e43a1d0d61a94741a771fe86aee45ab0ca059b1f"
    "c067f7416f08544cc4d08ec884b6d4327bb3ec0dc0789639375bd159df0efd87"
    "1cf4d605778c7a68c96b94cf0a6c29f9a23bc027e8250084eb2dfca817b20f57"
    "a6fe09513f884389db7b90788aea70c6e1638f24e39553ac0f859e585965c425"
    "9ed7b9680fde3e059f254d8c9494f6ab425ede80d63366dfcb7cc311f5bc6fb0"
    "1c27d81f4c5112d04b7614c37ba19c014916816372c773e4e44564fac34565ad"
    "ebf38fe56c1413170203010001a350304e301d0603551d0e04160414fe13c7db"
    "459bd2881e9113198e1f072e16cea144301f0603551d23041830168014fe13c7"
    "db459bd2881e9113198e1f072e16cea144300c0603551d13040530030101ff30"
    "0d06092a864886f70d01010b05000382010100a163d636ac64bd6f67eca53708"
    "5f92abc993a40fd0c0222a56b262c29f88057a3edf9abac024756ad85d7453d8"
    "4782e0be65d176aecfb0fbfc88ca567d17124fa190cb5ce832264360dd6daee1"
    "e121428de28dda0b8ba117a1be3cf438efd060a3b5fc812e7eba70cec12cb609"
    "738fc7d0912546c42b5aaadb142adce2167c7f30cd9e0049687d384334335aff"
    "72aebd1745a0aac4be816365969347f064f36f7fdec69f970f28b87061650470"
    "c63be8475bb23d0485985fb77c7cdd9d9fe008211a9ddd0fe68efb0b47cf629c"
    "941d31e3c2f88e670e7e4ef1129febad000e6a16222779fbfe34641e5243ca38"
    "74e2ad06f9585a00bec014744d3175ecc4808d";

std::string HexDecode(const std::string hex) {
  std::vector<uint8> output;
  CHECK(base::HexStringToBytes(hex, &output));
  return std::string(reinterpret_cast<char*>(output.data()), output.size());
}

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::LOG_INFO);
  }
  ~ScopedDisableVerboseLogging() {
    logging::SetMinLogLevel(original_severity_);
  }

 private:
  logging::LogSeverity original_severity_;
};

}  // namespace

namespace attestation {

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 KeyStoreTest : public testing::Test {
 public:
  KeyStoreTest()
      : 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) {}
  ~KeyStoreTest() override = default;

  void SetUp() override {
    std::vector<uint64_t> slot_list = {0, 1};
    ON_CALL(pkcs11_, GetSlotList(_, _, _))
        .WillByDefault(DoAll(SetArgumentPointee<2>(slot_list), Return(0)));
    ON_CALL(pkcs11_, OpenSession(_, _, _, _))
        .WillByDefault(DoAll(SetArgumentPointee<3>(kSession), Return(0)));
    ON_CALL(pkcs11_, CloseSession(_, _))
        .WillByDefault(Return(0));
    ON_CALL(pkcs11_, CreateObject(_, _, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::CreateObject));
    ON_CALL(pkcs11_, DestroyObject(_, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::DestroyObject));
    ON_CALL(pkcs11_, GetAttributeValue(_, _, _, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::GetAttributeValue));
    ON_CALL(pkcs11_, SetAttributeValue(_, _, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::SetAttributeValue));
    ON_CALL(pkcs11_, FindObjectsInit(_, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::FindObjectsInit));
    ON_CALL(pkcs11_, FindObjects(_, _, _, _))
        .WillByDefault(Invoke(this, &KeyStoreTest::FindObjects));
    ON_CALL(pkcs11_, FindObjectsFinal(_, _))
        .WillByDefault(Return(0));
    base::FilePath system_path("/var/lib/chaps");
    ON_CALL(token_manager_, GetTokenPath(_, 0, _))
        .WillByDefault(DoAll(SetArgumentPointee<2>(system_path), Return(true)));
    base::FilePath user_path(brillo::cryptohome::home::GetDaemonPath(
        kDefaultUser, "chaps"));
    ON_CALL(token_manager_, GetTokenPath(_, 1, _))
        .WillByDefault(DoAll(SetArgumentPointee<2>(user_path), Return(true)));
  }

  // 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_;
  NiceMock<chaps::TokenManagerClientMock> token_manager_;

 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;

  DISALLOW_COPY_AND_ASSIGN(KeyStoreTest);
};

// This test assumes that chaps in not available on the system running the test.
// The purpose of this test is to exercise the C_Initialize failure code path.
// Without a mock, the Chaps library will attempt to connect to the Chaps daemon
// unsuccessfully, resulting in a C_Initialize failure.
TEST(KeyStoreTest_NoMock, Pkcs11NotAvailable) {
  chaps::TokenManagerClient token_manager;
  Pkcs11KeyStore key_store(&token_manager);
  std::string blob;
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", blob));
  EXPECT_FALSE(key_store.Read("", "test", &blob));
  EXPECT_FALSE(key_store.Write("", "test", blob));
}

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

TEST_F(KeyStoreTest, Pkcs11Success_NoUser) {
  Pkcs11KeyStore key_store(&token_manager_);
  std::string blob;
  EXPECT_FALSE(key_store.Read("", "test", &blob));
  EXPECT_TRUE(key_store.Write("", "test", "test_data"));
  EXPECT_TRUE(key_store.Read("", "test", &blob));
  EXPECT_EQ("test_data", blob);
  // Try with a different key name.
  EXPECT_FALSE(key_store.Read("", "test2", &blob));
  EXPECT_TRUE(key_store.Write("", "test2", "test_data2"));
  EXPECT_TRUE(key_store.Read("", "test2", &blob));
  EXPECT_EQ("test_data2", blob);
  // Read the original key again.
  EXPECT_TRUE(key_store.Read("", "test", &blob));
  EXPECT_EQ("test_data", blob);
  // Replace key data.
  EXPECT_TRUE(key_store.Write("", "test", "test_data3"));
  EXPECT_TRUE(key_store.Read("", "test", &blob));
  EXPECT_EQ("test_data3", blob);
  // Delete key data.
  EXPECT_TRUE(key_store.Delete("", "test2"));
  EXPECT_FALSE(key_store.Read("", "test2", &blob));
  EXPECT_TRUE(key_store.Read("", "test", &blob));
}

// Tests the key store when PKCS #11 has no token for the given user.
TEST_F(KeyStoreTest, TokenNotAvailable) {
  EXPECT_CALL(token_manager_, GetTokenPath(_, _, _))
      .WillRepeatedly(Return(false));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string blob;
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
  EXPECT_FALSE(key_store.Write(kDefaultUser, "test", blob));
  EXPECT_FALSE(key_store.Read("", "test", &blob));
  EXPECT_FALSE(key_store.Write("", "test", blob));
}

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

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

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

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

// Tests the key store when PKCS #11 fails to find objects.  Tests each part of
// the multi-part find operation individually.
TEST_F(KeyStoreTest, FindFail) {
  EXPECT_CALL(pkcs11_, FindObjectsInit(_, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string blob;
  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));

  EXPECT_CALL(pkcs11_, FindObjectsInit(_, _, _))
      .WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));

  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
      .WillRepeatedly(Return(CKR_OK));
  EXPECT_CALL(pkcs11_, FindObjectsFinal(_, _))
      .WillRepeatedly(Return(CKR_GENERAL_ERROR));
  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
}

// Tests the key store when PKCS #11 successfully finds zero objects.
TEST_F(KeyStoreTest, FindNoObjects) {
  std::vector<uint64_t> empty;
  EXPECT_CALL(pkcs11_, FindObjects(_, _, _, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<3>(empty), Return(CKR_OK)));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string blob;
  EXPECT_TRUE(key_store.Write(kDefaultUser, "test", "test_data"));
  EXPECT_FALSE(key_store.Read(kDefaultUser, "test", &blob));
}

TEST_F(KeyStoreTest, RegisterKeyWithoutCertificate) {
  Pkcs11KeyStore key_store(&token_manager_);
  // Try with a malformed public key.
  EXPECT_FALSE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                  KEY_USAGE_SIGN, "private_key_blob",
                                  "bad_pubkey", ""));
  // Try with a well-formed public key.
  std::string public_key_der = HexDecode(kValidPublicKeyHex);
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .Times(2)  // Public, private (no certificate).
      .WillRepeatedly(Return(CKR_OK));
  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                 KEY_USAGE_SIGN, "private_key_blob",
                                 public_key_der, ""));
}

TEST_F(KeyStoreTest, RegisterKeyWithCertificate) {
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .Times(3)  // Public, private, and certificate.
      .WillRepeatedly(Return(CKR_OK));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string public_key_der = HexDecode(kValidPublicKeyHex);
  std::string certificate_der = HexDecode(kValidCertificateHex);
  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                 KEY_USAGE_SIGN, "private_key_blob",
                                 public_key_der, certificate_der));
  // Also try with the system token.
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .Times(3)  // Public, private, and certificate.
      .WillRepeatedly(Return(CKR_OK));
  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                 KEY_USAGE_SIGN, "private_key_blob",
                                 public_key_der, certificate_der));
}

TEST_F(KeyStoreTest, RegisterKeyWithBadCertificate) {
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .Times(3)  // Public, private, and certificate.
      .WillRepeatedly(Return(CKR_OK));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string public_key_der = HexDecode(kValidPublicKeyHex);
  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                 KEY_USAGE_SIGN, "private_key_blob",
                                 public_key_der, "bad_certificate"));
}

TEST_F(KeyStoreTest, RegisterWithUnsupportedKeyType) {
  Pkcs11KeyStore key_store(&token_manager_);
  std::string public_key_der = HexDecode(kValidPublicKeyHex);
  EXPECT_FALSE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_ECC,
                                  KEY_USAGE_SIGN, "private_key_blob",
                                  public_key_der, ""));
}

TEST_F(KeyStoreTest, RegisterDecryptionKey) {
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .WillRepeatedly(Return(CKR_OK));
  Pkcs11KeyStore key_store(&token_manager_);
  std::string public_key_der = HexDecode(kValidPublicKeyHex);
  EXPECT_TRUE(key_store.Register(kDefaultUser, "test_label", KEY_TYPE_RSA,
                                 KEY_USAGE_DECRYPT, "private_key_blob",
                                 public_key_der, ""));
}

TEST_F(KeyStoreTest, RegisterCertificate) {
  Pkcs11KeyStore key_store(&token_manager_);
  std::string certificate_der = HexDecode(kValidCertificateHex);
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .Times(2);  // Once for valid, once for invalid.
  // Try with a valid certificate (hit multiple times to check dup logic).
  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
  // Try with an invalid certificate.
  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, "bad_certificate"));
}

TEST_F(KeyStoreTest, RegisterCertificateError) {
  Pkcs11KeyStore key_store(&token_manager_);
  std::string certificate_der = HexDecode(kValidCertificateHex);
  // Handle an error from PKCS #11.
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .WillOnce(Return(CKR_GENERAL_ERROR));
  EXPECT_FALSE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
}

TEST_F(KeyStoreTest, RegisterCertificateSystemToken) {
  Pkcs11KeyStore key_store(&token_manager_);
  std::string certificate_der = HexDecode(kValidCertificateHex);
  // Try with the system token.
  EXPECT_CALL(pkcs11_, CreateObject(_, _, _, _))
      .WillOnce(Return(CKR_OK));
  EXPECT_TRUE(key_store.RegisterCertificate(kDefaultUser, certificate_der));
}

// Tests that the DeleteByPrefix() method removes the correct objects and only
// the correct objects.
TEST_F(KeyStoreTest, DeleteByPrefix) {
  Pkcs11KeyStore key_store(&token_manager_);

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

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

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

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

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

}  // namespace attestation
