// Copyright 2022 Google LLC
//
// 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 "tink/keyset_handle_builder.h"

#include <cstdint>
#include <memory>
#include <set>
#include <string>
#include <utility>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "tink/aead.h"
#include "tink/aead/aes_gcm_parameters.h"
#include "tink/config/global_registry.h"
#include "tink/config/tink_config.h"
#include "tink/core/key_type_manager.h"
#include "tink/core/template_util.h"
#include "tink/input_stream.h"
#include "tink/insecure_secret_key_access.h"
#include "tink/internal/legacy_proto_key.h"
#include "tink/internal/legacy_proto_parameters.h"
#include "tink/internal/proto_key_serialization.h"
#include "tink/internal/proto_parameters_serialization.h"
#include "tink/key_status.h"
#include "tink/keyset_handle.h"
#include "tink/mac.h"
#include "tink/mac/aes_cmac_key.h"
#include "tink/mac/aes_cmac_parameters.h"
#include "tink/mac/mac_key_templates.h"
#include "tink/partial_key_access.h"
#include "tink/primitive_set.h"
#include "tink/primitive_wrapper.h"
#include "tink/registry.h"
#include "tink/restricted_data.h"
#include "tink/subtle/random.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "tink/util/test_matchers.h"
#include "tink/util/test_util.h"
#include "proto/aes_cmac.pb.h"
#include "proto/aes_gcm.pb.h"
#include "proto/tink.pb.h"

namespace crypto {
namespace tink {
namespace {

using ::crypto::tink::test::AddTinkKey;
using ::crypto::tink::test::IsOk;
using ::crypto::tink::test::IsOkAndHolds;
using ::crypto::tink::test::StatusIs;
using ::google::crypto::tink::AesCmacParams;
using ::google::crypto::tink::AesGcmKey;
using ::google::crypto::tink::AesGcmKeyFormat;
using ::google::crypto::tink::KeyData;
using ::google::crypto::tink::Keyset;
using ::google::crypto::tink::KeyStatusType;
using ::google::crypto::tink::KeyTemplate;
using ::google::crypto::tink::OutputPrefixType;
using ::testing::_;
using ::testing::Eq;
using ::testing::IsFalse;
using ::testing::IsTrue;
using ::testing::SizeIs;
using ::testing::Test;

class KeysetHandleBuilderTest : public Test {
 protected:
  void SetUp() override {
    util::Status status = TinkConfig::Register();
    ASSERT_TRUE(status.ok()) << status;
  }
};

using KeysetHandleBuilderDeathTest = KeysetHandleBuilderTest;

util::StatusOr<internal::LegacyProtoParameters> CreateLegacyProtoParameters(
    KeyTemplate key_template) {
  util::StatusOr<internal::ProtoParametersSerialization> serialization =
      internal::ProtoParametersSerialization::Create(key_template);
  if (!serialization.ok()) return serialization.status();

  return internal::LegacyProtoParameters(*serialization);
}

TEST_F(KeysetHandleBuilderTest, BuildWithSingleKey) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/123);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
  EXPECT_THAT(*handle, SizeIs(1));

  EXPECT_THAT((*handle)[0].GetStatus(), Eq(KeyStatus::kEnabled));
  EXPECT_THAT((*handle)[0].GetId(), Eq(123));
  EXPECT_THAT((*handle)[0].IsPrimary(), IsTrue());
  EXPECT_THAT((*handle)[0].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());
}

TEST_F(KeysetHandleBuilderTest, BuildWithMultipleKeys) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kDestroyed,
          /*is_primary=*/false,
          /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/456);

  KeysetHandleBuilder::Entry entry2 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kDisabled,
          /*is_primary=*/false, /*id=*/789);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(entry0))
                                            .AddEntry(std::move(entry1))
                                            .AddEntry(std::move(entry2))
                                            .Build();
  ASSERT_THAT(handle.status(), IsOk());
  EXPECT_THAT(*handle, SizeIs(3));

  EXPECT_THAT((*handle)[0].GetStatus(), Eq(KeyStatus::kDestroyed));
  EXPECT_THAT((*handle)[0].GetId(), Eq(123));
  EXPECT_THAT((*handle)[0].IsPrimary(), IsFalse());
  EXPECT_THAT((*handle)[0].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());

  EXPECT_THAT((*handle)[1].GetStatus(), Eq(KeyStatus::kEnabled));
  EXPECT_THAT((*handle)[1].GetId(), Eq(456));
  EXPECT_THAT((*handle)[1].IsPrimary(), IsTrue());
  EXPECT_THAT((*handle)[1].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());

  EXPECT_THAT((*handle)[2].GetStatus(), Eq(KeyStatus::kDisabled));
  EXPECT_THAT((*handle)[2].GetId(), Eq(789));
  EXPECT_THAT((*handle)[2].IsPrimary(), IsFalse());
  EXPECT_THAT((*handle)[2].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());
}

TEST_F(KeysetHandleBuilderTest, BuildCopy) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kDestroyed,
          /*is_primary=*/false,
          /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/456);

  KeysetHandleBuilder::Entry entry2 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kDisabled,
          /*is_primary=*/false, /*id=*/789);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(entry0))
                                            .AddEntry(std::move(entry1))
                                            .AddEntry(std::move(entry2))
                                            .Build();
  ASSERT_THAT(handle.status(), IsOk());

  util::StatusOr<KeysetHandle> copy = KeysetHandleBuilder(*handle).Build();
  ASSERT_THAT(copy.status(), IsOk());
  EXPECT_THAT(copy->size(), Eq(3));

  EXPECT_THAT((*copy)[0].GetStatus(), Eq(KeyStatus::kDestroyed));
  EXPECT_THAT((*copy)[0].GetId(), Eq(123));
  EXPECT_THAT((*copy)[0].IsPrimary(), IsFalse());
  EXPECT_THAT((*copy)[0].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());

  EXPECT_THAT((*copy)[1].GetStatus(), Eq(KeyStatus::kEnabled));
  EXPECT_THAT((*copy)[1].GetId(), Eq(456));
  EXPECT_THAT((*copy)[1].IsPrimary(), IsTrue());
  EXPECT_THAT((*copy)[1].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());

  EXPECT_THAT((*copy)[2].GetStatus(), Eq(KeyStatus::kDisabled));
  EXPECT_THAT((*copy)[2].GetId(), Eq(789));
  EXPECT_THAT((*copy)[2].IsPrimary(), IsFalse());
  EXPECT_THAT((*copy)[2].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());
}

TEST_F(KeysetHandleBuilderTest, IsPrimary) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(*parameters,
                                                           KeyStatus::kEnabled,
                                                           /*is_primary=*/false,
                                                           /*id=*/123);
  EXPECT_THAT(entry.IsPrimary(), IsFalse());

  entry.SetPrimary();
  EXPECT_THAT(entry.IsPrimary(), IsTrue());
}

TEST_F(KeysetHandleBuilderTest, SetAndGetStatus) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false,
          /*id=*/123);

  entry.SetStatus(KeyStatus::kDisabled);
  EXPECT_THAT(entry.GetStatus(), Eq(KeyStatus::kDisabled));
  entry.SetStatus(KeyStatus::kEnabled);
  EXPECT_THAT(entry.GetStatus(), Eq(KeyStatus::kEnabled));
  entry.SetStatus(KeyStatus::kDestroyed);
  EXPECT_THAT(entry.GetStatus(), Eq(KeyStatus::kDestroyed));
}

TEST_F(KeysetHandleBuilderTest, BuildWithRandomId) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry primary =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true);

  KeysetHandleBuilder builder;
  builder.AddEntry(std::move(primary));

  int num_non_primary_entries = 1 << 16;
  for (int i = 0; i < num_non_primary_entries; ++i) {
    KeysetHandleBuilder::Entry non_primary =
        KeysetHandleBuilder::Entry::CreateFromCopyableParams(
            *parameters, KeyStatus::kEnabled, /*is_primary=*/false);
    builder.AddEntry(std::move(non_primary));
  }

  util::StatusOr<KeysetHandle> handle = builder.Build();
  ASSERT_THAT(handle.status(), IsOk());

  std::set<int> ids;
  for (int i = 0; i < handle->size(); ++i) {
    ids.insert((*handle)[i].GetId());
  }
  EXPECT_THAT(ids, SizeIs(num_non_primary_entries + 1));
}

TEST_F(KeysetHandleBuilderTest, BuildWithRandomIdAfterFixedId) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry fixed =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  KeysetHandleBuilder::Entry random =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(fixed))
                                            .AddEntry(std::move(random))
                                            .Build();
  ASSERT_THAT(handle.status(), IsOk());

  EXPECT_THAT(*handle, SizeIs(2));
  EXPECT_THAT((*handle)[0].GetId(), Eq(123));
}

TEST_F(KeysetHandleBuilderTest, BuildWithFixedIdAfterRandomIdFails) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry random =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false);

  KeysetHandleBuilder::Entry fixed =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(random))
                                            .AddEntry(std::move(fixed))
                                            .Build();
  ASSERT_THAT(handle.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
}

TEST_F(KeysetHandleBuilderDeathTest, AddEntryToAnotherBuilderCrashes) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  KeysetHandleBuilder builder0;
  builder0.AddEntry(std::move(entry));
  KeysetHandleBuilder builder1;
  EXPECT_DEATH_IF_SUPPORTED(
      builder1.AddEntry(std::move(builder0[0])),
      "Keyset handle builder entry already added to a builder.");
}

TEST_F(KeysetHandleBuilderDeathTest, ReAddEntryToSameBuilderCrashes) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  KeysetHandleBuilder builder;
  builder.AddEntry(std::move(entry));
  EXPECT_DEATH_IF_SUPPORTED(
      builder.AddEntry(std::move(builder[0])),
      "Keyset handle builder entry already added to a builder.");
}

TEST_F(KeysetHandleBuilderDeathTest,
       AddDereferencedEntryToAnotherBuilderCrashes) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  KeysetHandleBuilder builder0;
  builder0.AddEntry(std::move(entry));
  KeysetHandleBuilder builder1;
  EXPECT_DEATH_IF_SUPPORTED(
      builder1.AddEntry(std::move(*&(builder0[0]))),
      "Keyset handle builder entry already added to a builder.");
}

TEST_F(KeysetHandleBuilderTest, RemoveEntry) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false, /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/456);

  util::StatusOr<KeysetHandle> handle0 = KeysetHandleBuilder()
                                             .AddEntry(std::move(entry0))
                                             .AddEntry(std::move(entry1))
                                             .Build();
  ASSERT_THAT(handle0.status(), IsOk());
  ASSERT_THAT(*handle0, SizeIs(2));

  util::StatusOr<KeysetHandle> handle1 =
      KeysetHandleBuilder(*handle0).RemoveEntry(0).Build();
  ASSERT_THAT(handle1.status(), IsOk());
  ASSERT_THAT(*handle1, SizeIs(1));

  EXPECT_THAT((*handle1)[0].GetStatus(), Eq(KeyStatus::kEnabled));
  EXPECT_THAT((*handle1)[0].GetId(), Eq(456));
  EXPECT_THAT((*handle1)[0].IsPrimary(), IsTrue());
  EXPECT_THAT((*handle1)[0].GetKey()->GetParameters().HasIdRequirement(),
              IsTrue());
}

TEST_F(KeysetHandleBuilderDeathTest, RemoveOutofRangeIndexEntryCrashes) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true, /*id=*/123);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
  ASSERT_THAT(*handle, SizeIs(1));

  EXPECT_DEATH_IF_SUPPORTED(
      KeysetHandleBuilder(*handle).RemoveEntry(1),
      "Keyset handle builder entry removal index out of range.");
}

TEST_F(KeysetHandleBuilderTest, Size) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kDestroyed,
          /*is_primary=*/false,
          /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/456);

  KeysetHandleBuilder builder;
  ASSERT_THAT(builder, SizeIs(0));
  builder.AddEntry(std::move(entry0));
  ASSERT_THAT(builder, SizeIs(1));
  builder.AddEntry(std::move(entry1));
  EXPECT_THAT(builder, SizeIs(2));
}

TEST_F(KeysetHandleBuilderTest, NoPrimaryFails) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false,
          /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false,
          /*id=*/456);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(entry0))
                                            .AddEntry(std::move(entry1))
                                            .Build();
  ASSERT_THAT(handle.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
}

TEST_F(KeysetHandleBuilderTest, RemovePrimaryFails) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry0 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/123);

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/false,
          /*id=*/456);

  util::StatusOr<KeysetHandle> handle = KeysetHandleBuilder()
                                            .AddEntry(std::move(entry0))
                                            .AddEntry(std::move(entry1))
                                            .RemoveEntry(0)
                                            .Build();
  ASSERT_THAT(handle.status(), StatusIs(absl::StatusCode::kFailedPrecondition));
}

TEST_F(KeysetHandleBuilderTest, AddPrimaryClearsOtherPrimary) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder builder;
  builder.AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
      *parameters, KeyStatus::kEnabled,
      /*is_primary=*/true,
      /*id=*/123));
  builder.AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
      *parameters, KeyStatus::kEnabled,
      /*is_primary=*/true,
      /*id=*/456));

  ASSERT_THAT(builder[0].IsPrimary(), IsFalse());
  ASSERT_THAT(builder[1].IsPrimary(), IsTrue());
}

TEST_F(KeysetHandleBuilderTest, NoIdStrategySucceeds) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle, IsOk());
}

TEST_F(KeysetHandleBuilderTest, DuplicateId) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
              *parameters, KeyStatus::kEnabled,
              /*is_primary=*/true,
              /*id=*/123))
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
              *parameters, KeyStatus::kEnabled,
              /*is_primary=*/false,
              /*id=*/123))
          .Build();
  ASSERT_THAT(handle.status(), StatusIs(absl::StatusCode::kAlreadyExists));
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromParams) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kTink);
  ASSERT_THAT(params, IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromParams(
          absl::make_unique<AesCmacParameters>(std::move(*params)),
          KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromLegacyKey) {
  Keyset keyset;
  Keyset::Key key;
  AddTinkKey("first_key_type", 11, key, KeyStatusType::DISABLED,
             KeyData::SYMMETRIC, &keyset);

  util::StatusOr<internal::ProtoKeySerialization> serialization =
      internal::ProtoKeySerialization::Create(
          key.key_data().type_url(),
          RestrictedData(key.SerializeAsString(),
                         InsecureSecretKeyAccess::Get()),
          key.key_data().key_material_type(), key.output_prefix_type(),
          key.key_id());

  util::StatusOr<internal::LegacyProtoKey> proto_key =
      internal::LegacyProtoKey::Create(*serialization,
                                       InsecureSecretKeyAccess::Get());
  ASSERT_THAT(proto_key.status(), IsOk());

  KeysetHandleBuilder::Entry entry = KeysetHandleBuilder::Entry::CreateFromKey(
      absl::make_unique<internal::LegacyProtoKey>(std::move(*proto_key)),
      KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromKey) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kTink);
  ASSERT_THAT(params, IsOk());

  RestrictedData secret = RestrictedData(32);
  util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
      *params, secret, /*id_requirement=*/123, GetPartialKeyAccess());
  ASSERT_THAT(key.status(), IsOk());

  KeysetHandleBuilder::Entry entry = KeysetHandleBuilder::Entry::CreateFromKey(
      absl::make_unique<AesCmacKey>(std::move(*key)), KeyStatus::kEnabled,
      /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest,
       MergeTwoKeysetsWithTheSameIdButNoIdRequirementWorks) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kNoPrefix);
  ASSERT_THAT(params, IsOk());

  KeysetHandleBuilder::Entry entry1 =
      KeysetHandleBuilder::Entry::CreateFromParams(
          absl::make_unique<AesCmacParameters>(std::move(*params)),
          KeyStatus::kEnabled, /*is_primary=*/true);
  entry1.SetFixedId(123);
  util::StatusOr<KeysetHandle> handle1 =
      KeysetHandleBuilder().AddEntry(std::move(entry1)).Build();
  ASSERT_THAT(handle1.status(), IsOk());

  KeysetHandleBuilder::Entry entry2 =
      KeysetHandleBuilder::Entry::CreateFromParams(
          absl::make_unique<AesCmacParameters>(std::move(*params)),
          KeyStatus::kEnabled, /*is_primary=*/true);
  entry2.SetFixedId(123);
  util::StatusOr<KeysetHandle> handle2 =
      KeysetHandleBuilder().AddEntry(std::move(entry2)).Build();
  ASSERT_THAT(handle2.status(), IsOk());

  // handle1 and handle2 each contain one key with the same ID, but no ID
  // requirement. We can add them to a new keyset because they will get new,
  // random and distinct IDs.
  util::StatusOr<KeysetHandle> handle12 =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromKey(
              (*handle1)[0].GetKey(), KeyStatus::kEnabled, /*is_primary=*/true))
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromKey(
              (*handle2)[0].GetKey(), KeyStatus::kEnabled,
              /*is_primary=*/false))
          .Build();
  ASSERT_THAT(handle12.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromCopyableKey) {
  Keyset keyset;
  Keyset::Key key;
  AddTinkKey("first_key_type", 11, key, KeyStatusType::DISABLED,
             KeyData::SYMMETRIC, &keyset);

  util::StatusOr<internal::ProtoKeySerialization> serialization =
      internal::ProtoKeySerialization::Create(
          key.key_data().type_url(),
          RestrictedData(key.SerializeAsString(),
                         InsecureSecretKeyAccess::Get()),
          key.key_data().key_material_type(), key.output_prefix_type(),
          key.key_id());

  util::StatusOr<internal::LegacyProtoKey> proto_key =
      internal::LegacyProtoKey::Create(*serialization,
                                       InsecureSecretKeyAccess::Get());
  ASSERT_THAT(proto_key.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableKey(
          *proto_key, KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromParameters) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromParams(
          absl::make_unique<internal::LegacyProtoParameters>(*parameters),
          KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, CreateBuilderEntryFromCopyableParameters) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());
}

TEST_F(KeysetHandleBuilderTest, UsePrimitiveFromLegacyProtoParams) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());

  util::StatusOr<std::unique_ptr<Mac>> mac =
      handle->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac.status(), IsOk());
  util::StatusOr<std::string> tag = (*mac)->ComputeMac("some input");
  ASSERT_THAT(tag.status(), IsOk());
  util::Status verified = (*mac)->VerifyMac(*tag, "some input");
  EXPECT_THAT(verified, IsOk());
}

TEST_F(KeysetHandleBuilderTest, UsePrimitiveFromParams) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kTink);
  ASSERT_THAT(params, IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromParams(
          absl::make_unique<AesCmacParameters>(std::move(*params)),
          KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());

  util::StatusOr<std::unique_ptr<Mac>> mac =
      handle->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac.status(), IsOk());
  util::StatusOr<std::string> tag = (*mac)->ComputeMac("some input");
  ASSERT_THAT(tag.status(), IsOk());
  util::Status verified = (*mac)->VerifyMac(*tag, "some input");
  EXPECT_THAT(verified, IsOk());
}

TEST_F(KeysetHandleBuilderTest, UsePrimitiveFromLegacyProtoKey) {
  AesCmacParams params;
  params.set_tag_size(16);
  google::crypto::tink::AesCmacKey key;
  *key.mutable_params() = params;
  key.set_version(0);
  key.set_key_value(subtle::Random::GetRandomBytes(32));

  util::StatusOr<internal::ProtoKeySerialization> serialization =
      internal::ProtoKeySerialization::Create(
          "type.googleapis.com/google.crypto.tink.AesCmacKey",
          RestrictedData(key.SerializeAsString(),
                         InsecureSecretKeyAccess::Get()),
          KeyData::SYMMETRIC, OutputPrefixType::TINK,
          /*id_requirement=*/123);
  ASSERT_THAT(serialization, IsOk());

  util::StatusOr<internal::LegacyProtoKey> proto_key =
      internal::LegacyProtoKey::Create(*serialization,
                                       InsecureSecretKeyAccess::Get());
  ASSERT_THAT(proto_key.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableKey(
          *proto_key, KeyStatus::kEnabled, /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());

  util::StatusOr<std::unique_ptr<Mac>> mac =
      handle->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac.status(), IsOk());
  util::StatusOr<std::string> tag = (*mac)->ComputeMac("some input");
  ASSERT_THAT(tag.status(), IsOk());
  util::Status verified = (*mac)->VerifyMac(*tag, "some input");
  EXPECT_THAT(verified, IsOk());
}

TEST_F(KeysetHandleBuilderTest, UsePrimitiveFromKey) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kTink);
  ASSERT_THAT(params, IsOk());

  RestrictedData secret = RestrictedData(32);
  util::StatusOr<AesCmacKey> key = AesCmacKey::Create(
      *params, secret, /*id_requirement=*/123, GetPartialKeyAccess());
  ASSERT_THAT(key.status(), IsOk());

  KeysetHandleBuilder::Entry entry = KeysetHandleBuilder::Entry::CreateFromKey(
      absl::make_unique<AesCmacKey>(std::move(*key)), KeyStatus::kEnabled,
      /*is_primary=*/true);

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder().AddEntry(std::move(entry)).Build();
  ASSERT_THAT(handle.status(), IsOk());

  util::StatusOr<std::unique_ptr<Mac>> mac =
      handle->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac.status(), IsOk());
  util::StatusOr<std::string> tag = (*mac)->ComputeMac("some input");
  ASSERT_THAT(tag.status(), IsOk());
  util::Status verified = (*mac)->VerifyMac(*tag, "some input");
  EXPECT_THAT(verified, IsOk());
}

TEST_F(KeysetHandleBuilderTest, BuildTwiceFails) {
  util::StatusOr<internal::LegacyProtoParameters> parameters =
      CreateLegacyProtoParameters(MacKeyTemplates::AesCmac());
  ASSERT_THAT(parameters.status(), IsOk());

  KeysetHandleBuilder::Entry entry =
      KeysetHandleBuilder::Entry::CreateFromCopyableParams(
          *parameters, KeyStatus::kEnabled, /*is_primary=*/true,
          /*id=*/123);

  KeysetHandleBuilder builder;
  builder.AddEntry(std::move(entry));

  EXPECT_THAT(builder.Build(), IsOk());
  EXPECT_THAT(builder.Build().status(),
              StatusIs(absl::StatusCode::kFailedPrecondition));
}

TEST_F(KeysetHandleBuilderTest, UsePrimitivesFromSplitKeyset) {
  util::StatusOr<AesCmacParameters> params = AesCmacParameters::Create(
      /*key_size_in_bytes=*/32, /*cryptographic_tag_size_in_bytes=*/16,
      AesCmacParameters::Variant::kTink);
  ASSERT_THAT(params, IsOk());

  util::StatusOr<KeysetHandle> handle =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
              *params, KeyStatus::kEnabled, /*is_primary=*/false))
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
              *params, KeyStatus::kEnabled, /*is_primary=*/true))
          .Build();
  ASSERT_THAT(handle, IsOkAndHolds(SizeIs(2)));

  util::StatusOr<KeysetHandle> handle0 =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromKey(
              (*handle)[0].GetKey(), KeyStatus::kEnabled,
              /*is_primary=*/true))
          .Build();
  ASSERT_THAT(handle0, IsOkAndHolds(SizeIs(1)));
  ASSERT_THAT((*handle)[0].GetId(), Eq((*handle0)[0].GetId()));

  util::StatusOr<KeysetHandle> handle1 =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromKey(
              (*handle)[1].GetKey(), KeyStatus::kEnabled,
              /*is_primary=*/true))
          .Build();
  ASSERT_THAT(handle1, IsOkAndHolds(SizeIs(1)));
  ASSERT_THAT((*handle)[1].GetId(), Eq((*handle1)[0].GetId()));

  util::StatusOr<std::unique_ptr<Mac>> mac0 =
      handle0->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac0.status(), IsOk());
  util::StatusOr<std::string> tag0 = (*mac0)->ComputeMac("some input");
  ASSERT_THAT(tag0.status(), IsOk());

  util::StatusOr<std::unique_ptr<Mac>> mac1 =
      handle1->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac1.status(), IsOk());
  util::StatusOr<std::string> tag1 = (*mac1)->ComputeMac("some other input");
  ASSERT_THAT(tag1.status(), IsOk());

  // Use original keyset to verify tags computed from new keysets.
  util::StatusOr<std::unique_ptr<Mac>> mac =
      handle->GetPrimitive<crypto::tink::Mac>(ConfigGlobalRegistry());
  ASSERT_THAT(mac.status(), IsOk());
  EXPECT_THAT((*mac)->VerifyMac(*tag0, "some input"), IsOk());
  EXPECT_THAT((*mac)->VerifyMac(*tag1, "some other input"), IsOk());
}

class MockAeadPrimitiveWrapper : public PrimitiveWrapper<Aead, Aead> {
 public:
  MOCK_METHOD(util::StatusOr<std::unique_ptr<Aead>>, Wrap,
              (std::unique_ptr<PrimitiveSet<Aead>> primitive_set),
              (const override));
};

class FakeAeadKeyManager
    : public KeyTypeManager<AesGcmKey, AesGcmKeyFormat, List<Aead>> {
 public:
  class AeadFactory : public PrimitiveFactory<Aead> {
   public:
    explicit AeadFactory(absl::string_view key_type) : key_type_(key_type) {}

    util::StatusOr<std::unique_ptr<Aead>> Create(
        const AesGcmKey& key) const override {
      return {absl::make_unique<test::DummyAead>(key_type_)};
    }

   private:
    const std::string key_type_;
  };

  explicit FakeAeadKeyManager(absl::string_view key_type)
      : KeyTypeManager(absl::make_unique<AeadFactory>(key_type)),
        key_type_(key_type) {}

  google::crypto::tink::KeyData::KeyMaterialType key_material_type()
      const override {
    return google::crypto::tink::KeyData::SYMMETRIC;
  }

  uint32_t get_version() const override { return 0; }

  const std::string& get_key_type() const override { return key_type_; }

  crypto::tink::util::Status ValidateKey(const AesGcmKey& key) const override {
    return util::OkStatus();
  }

  crypto::tink::util::Status ValidateKeyFormat(
      const AesGcmKeyFormat& key_format) const override {
    return util::OkStatus();
  }

  crypto::tink::util::StatusOr<AesGcmKey> CreateKey(
      const AesGcmKeyFormat& key_format) const override {
    return AesGcmKey();
  }

  crypto::tink::util::StatusOr<AesGcmKey> DeriveKey(
      const AesGcmKeyFormat& key_format,
      InputStream* input_stream) const override {
    return AesGcmKey();
  }

 private:
  const std::string key_type_;
};

TEST_F(KeysetHandleBuilderTest, BuildWithAnnotations) {
  const absl::flat_hash_map<std::string, std::string> kAnnotations = {
      {"key1", "value1"}, {"key2", "value2"}};
  util::StatusOr<AesGcmParameters> aes_128_gcm =
      AesGcmParameters::Builder()
          .SetKeySizeInBytes(16)
          .SetIvSizeInBytes(12)
          .SetTagSizeInBytes(16)
          .SetVariant(AesGcmParameters::Variant::kTink)
          .Build();
  ASSERT_THAT(aes_128_gcm, IsOk());

  util::StatusOr<KeysetHandle> keyset_handle =
      KeysetHandleBuilder()
          .AddEntry(KeysetHandleBuilder::Entry::CreateFromCopyableParams(
              *aes_128_gcm, crypto::tink::KeyStatus::kEnabled,
              /*is_primary=*/true))
          .SetMonitoringAnnotations(kAnnotations)
          .Build();
  ASSERT_THAT(keyset_handle, IsOk());

  // In order to validate annotations are set correctly, we need acceess to the
  // generated primitive set, which is populated by KeysetWrapperImpl and passed
  // to the primitive wrapper. We thus register a mock primitive wrapper for
  // Aead so that we can copy the annotations and later check them.
  auto primitive_wrapper = absl::make_unique<MockAeadPrimitiveWrapper>();
  absl::flat_hash_map<std::string, std::string> generated_annotations;
  EXPECT_CALL(*primitive_wrapper, Wrap(_))
      .WillOnce(
          [&generated_annotations](
              std::unique_ptr<PrimitiveSet<Aead>> generated_primitive_set) {
            generated_annotations = generated_primitive_set->get_annotations();
            std::unique_ptr<Aead> aead = absl::make_unique<test::DummyAead>("");
            return aead;
          });
  Registry::Reset();
  ASSERT_THAT(Registry::RegisterPrimitiveWrapper(std::move(primitive_wrapper)),
              IsOk());
  ASSERT_THAT(Registry::RegisterKeyTypeManager(
                  absl::make_unique<FakeAeadKeyManager>(
                      "type.googleapis.com/google.crypto.tink.AesGcmKey"),
                  /*new_key_allowed=*/true),
              IsOk());

  ASSERT_THAT(
      keyset_handle->GetPrimitive<crypto::tink::Aead>(ConfigGlobalRegistry()),
      IsOk());
  EXPECT_EQ(generated_annotations, kAnnotations);
  // This is needed to cleanup mocks.
  Registry::Reset();
}

}  // namespace
}  // namespace tink
}  // namespace crypto
