//
// 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_t> 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
