// Copyright 2017 Google Inc.
//
// 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/mac/hmac_key_manager.h"

#include <memory>
#include <string>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "tink/core/key_manager_impl.h"
#include "tink/chunked_mac.h"
#include "tink/mac.h"
#include "tink/util/istream_input_stream.h"
#include "tink/util/secret_data.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "tink/util/test_matchers.h"
#include "proto/hmac.pb.h"

namespace crypto {
namespace tink {

using ::crypto::tink::test::IsOk;
using ::crypto::tink::test::StatusIs;
using ::crypto::tink::util::IstreamInputStream;
using ::crypto::tink::util::StatusOr;
using ::google::crypto::tink::HashType;
using ::google::crypto::tink::HmacKey;
using ::google::crypto::tink::HmacKeyFormat;
using ::google::crypto::tink::KeyData;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Not;
using ::testing::SizeIs;

namespace {

TEST(HmacKeyManagerTest, Basics) {
  EXPECT_EQ(HmacKeyManager().get_version(), 0);
  EXPECT_EQ(HmacKeyManager().get_key_type(),
            "type.googleapis.com/google.crypto.tink.HmacKey");
  EXPECT_EQ(HmacKeyManager().key_material_type(),
            google::crypto::tink::KeyData::SYMMETRIC);
}

TEST(HmacKeyManagerTest, ValidateEmptyKey) {
  EXPECT_THAT(HmacKeyManager().ValidateKey(HmacKey()), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateEmptyKeyFormat) {
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(HmacKeyFormat()), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidKeyFormat) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_tag_size(16);
  key_format.mutable_params()->set_hash(HashType::SHA256);
  key_format.set_key_size(16);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
}

TEST(HmacKeyManagerTest, ValidateKeyFormatSmallTagSizes) {
  for (int i = 0; i < 10; ++i) {
    HmacKeyFormat key_format;
    key_format.mutable_params()->set_tag_size(i);
    key_format.mutable_params()->set_hash(HashType::SHA256);
    key_format.set_key_size(16);
    EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()))
        << " for length " << i;
  }
}

TEST(HmacKeyManagerTest, ValidateKeyFormatTagSizesSha1) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA1);
  key_format.set_key_size(16);

  key_format.mutable_params()->set_tag_size(20);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
  key_format.mutable_params()->set_tag_size(21);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyFormatTagSizesSha224) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA224);
  key_format.set_key_size(16);

  key_format.mutable_params()->set_tag_size(28);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
  key_format.mutable_params()->set_tag_size(29);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyFormatTagSizesSha256) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA256);
  key_format.set_key_size(16);

  key_format.mutable_params()->set_tag_size(32);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
  key_format.mutable_params()->set_tag_size(33);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyFormatTagSizesSha384) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA384);
  key_format.set_key_size(16);

  key_format.mutable_params()->set_tag_size(48);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
  key_format.mutable_params()->set_tag_size(49);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyFormatTagSizesSha512) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA512);
  key_format.set_key_size(16);

  key_format.mutable_params()->set_tag_size(64);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
  key_format.mutable_params()->set_tag_size(65);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyFormatKeySizes) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_hash(HashType::SHA512);
  key_format.mutable_params()->set_tag_size(64);

  key_format.set_key_size(15);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), Not(IsOk()));

  key_format.set_key_size(16);
  EXPECT_THAT(HmacKeyManager().ValidateKeyFormat(key_format), IsOk());
}

TEST(HmacKeyManagerTest, CreateKey) {
  HmacKeyFormat key_format;
  key_format.set_key_size(16);
  key_format.mutable_params()->set_tag_size(10);
  key_format.mutable_params()->set_hash(HashType::SHA512);
  auto hmac_key_or = HmacKeyManager().CreateKey(key_format);
  ASSERT_THAT(hmac_key_or, IsOk());
  EXPECT_EQ(hmac_key_or.value().version(), 0);
  EXPECT_EQ(hmac_key_or.value().params().hash(), key_format.params().hash());
  EXPECT_EQ(hmac_key_or.value().params().tag_size(),
            key_format.params().tag_size());
  EXPECT_THAT(hmac_key_or.value().key_value(), SizeIs(key_format.key_size()));

  EXPECT_THAT(HmacKeyManager().ValidateKey(hmac_key_or.value()), IsOk());
}

TEST(HmacKeyManagerTest, ValidKey) {
  HmacKey key;
  key.set_version(0);

  key.mutable_params()->set_hash(HashType::SHA256);
  key.mutable_params()->set_tag_size(10);
  key.set_key_value("0123456789abcdef");

  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
}

TEST(HmacKeyManagerTest, ValidateKeyTagSizesSha1) {
  HmacKey key;
  key.set_version(0);
  key.mutable_params()->set_hash(HashType::SHA1);
  key.set_key_value("0123456789abcdef");

  key.mutable_params()->set_tag_size(20);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
  key.mutable_params()->set_tag_size(21);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyTagSizesSha224) {
  HmacKey key;
  key.set_version(0);
  key.mutable_params()->set_hash(HashType::SHA224);
  key.set_key_value("0123456789abcdef");

  key.mutable_params()->set_tag_size(28);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
  key.mutable_params()->set_tag_size(29);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyTagSizesSha256) {
  HmacKey key;
  key.set_version(0);
  key.mutable_params()->set_hash(HashType::SHA256);
  key.set_key_value("0123456789abcdef");

  key.mutable_params()->set_tag_size(32);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
  key.mutable_params()->set_tag_size(33);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyTagSizesSha384) {
  HmacKey key;
  key.set_version(0);
  key.mutable_params()->set_hash(HashType::SHA384);
  key.set_key_value("0123456789abcdef");

  key.mutable_params()->set_tag_size(48);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
  key.mutable_params()->set_tag_size(49);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyTagSizesSha512) {
  HmacKey key;
  key.set_version(0);
  key.mutable_params()->set_hash(HashType::SHA512);
  key.set_key_value("0123456789abcdef");

  key.mutable_params()->set_tag_size(64);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), IsOk());
  key.mutable_params()->set_tag_size(65);
  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, ValidateKeyShortKey) {
  HmacKey key;
  key.set_version(0);

  key.mutable_params()->set_hash(HashType::SHA256);
  key.mutable_params()->set_tag_size(10);
  key.set_key_value("0123456789abcde");

  EXPECT_THAT(HmacKeyManager().ValidateKey(key), Not(IsOk()));
}

TEST(HmacKeyManagerTest, DeriveKey) {
  HmacKeyFormat format;
  format.set_key_size(23);
  format.set_version(0);
  format.mutable_params()->set_hash(HashType::SHA256);
  format.mutable_params()->set_tag_size(10);

  IstreamInputStream input_stream{
      absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};

  StatusOr<HmacKey> key_or = HmacKeyManager().DeriveKey(format, &input_stream);
  ASSERT_THAT(key_or, IsOk());
  EXPECT_EQ(key_or.value().key_value(), "0123456789abcdefghijklm");
  EXPECT_EQ(key_or.value().params().hash(), format.params().hash());
  EXPECT_EQ(key_or.value().params().tag_size(), format.params().tag_size());
}

TEST(HmacKeyManagerTest, DeriveKeyNotEnoughRandomness) {
  HmacKeyFormat format;
  format.set_key_size(17);
  format.set_version(0);
  format.mutable_params()->set_hash(HashType::SHA256);
  format.mutable_params()->set_tag_size(10);

  IstreamInputStream input_stream{
      absl::make_unique<std::stringstream>("0123456789abcdef")};

  ASSERT_THAT(HmacKeyManager().DeriveKey(format, &input_stream).status(),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(HmacKeyManagerTest, DeriveKeyWrongVersion) {
  HmacKeyFormat format;
  format.set_key_size(16);
  format.set_version(1);
  format.mutable_params()->set_hash(HashType::SHA256);
  format.mutable_params()->set_tag_size(10);

  IstreamInputStream input_stream{
      absl::make_unique<std::stringstream>("0123456789abcdef")};

  ASSERT_THAT(
      HmacKeyManager().DeriveKey(format, &input_stream).status(),
      StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("version")));
}

TEST(HmacKeyManagerTest, GetMacPrimitive) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_tag_size(16);
  key_format.mutable_params()->set_hash(HashType::SHA256);
  key_format.set_key_size(16);
  HmacKey key = HmacKeyManager().CreateKey(key_format).value();
  auto manager_mac_or = HmacKeyManager().GetPrimitive<Mac>(key);
  ASSERT_THAT(manager_mac_or, IsOk());
  auto mac_value_or = manager_mac_or.value()->ComputeMac("some plaintext");
  ASSERT_THAT(mac_value_or, IsOk());

  auto direct_mac_or = subtle::HmacBoringSsl::New(
      util::Enums::ProtoToSubtle(key.params().hash()), key.params().tag_size(),
      util::SecretDataFromStringView(key.key_value()));
  ASSERT_THAT(direct_mac_or, IsOk());
  EXPECT_THAT(
      direct_mac_or.value()->VerifyMac(mac_value_or.value(), "some plaintext"),
      IsOk());
}

TEST(HmacKeyManagerTest, GetChunkedMacPrimitive) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_tag_size(16);
  key_format.mutable_params()->set_hash(HashType::SHA256);
  key_format.set_key_size(16);
  HmacKey key = HmacKeyManager().CreateKey(key_format).value();

  util::StatusOr<std::unique_ptr<ChunkedMac>> chunked_mac =
      HmacKeyManager().GetPrimitive<ChunkedMac>(key);
  ASSERT_THAT(chunked_mac, IsOk());

  util::StatusOr<std::unique_ptr<ChunkedMacComputation>> computation =
      (*chunked_mac)->CreateComputation();
  ASSERT_THAT(computation, IsOk());
  ASSERT_THAT((*computation)->Update("abc"), IsOk());
  ASSERT_THAT((*computation)->Update("xyz"), IsOk());
  util::StatusOr<std::string> tag = (*computation)->ComputeMac();
  ASSERT_THAT(tag, IsOk());

  util::StatusOr<std::unique_ptr<ChunkedMacVerification>> verification =
      (*chunked_mac)->CreateVerification(*tag);
  ASSERT_THAT(verification, IsOk());
  ASSERT_THAT((*verification)->Update("abc"), IsOk());
  ASSERT_THAT((*verification)->Update("xyz"), IsOk());
  EXPECT_THAT((*verification)->VerifyMac(), IsOk());
}

TEST(HmacKeyManagerTest, MixPrimitives) {
  HmacKeyFormat key_format;
  key_format.mutable_params()->set_tag_size(16);
  key_format.mutable_params()->set_hash(HashType::SHA256);
  key_format.set_key_size(16);
  HmacKey key = HmacKeyManager().CreateKey(key_format).value();

  util::StatusOr<std::unique_ptr<Mac>> mac =
      HmacKeyManager().GetPrimitive<Mac>(key);
  ASSERT_THAT(mac, IsOk());

  util::StatusOr<std::unique_ptr<ChunkedMac>> chunked_mac =
      HmacKeyManager().GetPrimitive<ChunkedMac>(key);
  ASSERT_THAT(chunked_mac, IsOk());

  // Compute tag with Mac.
  util::StatusOr<std::string> tag = (*mac)->ComputeMac("abcxyz");
  ASSERT_THAT(tag, IsOk());

  // Compute chunked tag with ChunkedMac.
  util::StatusOr<std::unique_ptr<ChunkedMacComputation>> computation =
      (*chunked_mac)->CreateComputation();
  ASSERT_THAT(computation, IsOk());
  ASSERT_THAT((*computation)->Update("abc"), IsOk());
  ASSERT_THAT((*computation)->Update("xyz"), IsOk());
  util::StatusOr<std::string> chunked_tag = (*computation)->ComputeMac();
  ASSERT_THAT(chunked_tag, IsOk());
  ASSERT_THAT(*chunked_tag, Eq(*tag));  // Both primitives generated same tag.

  // Verify chunked tag with Mac.
  ASSERT_THAT((*mac)->VerifyMac(*chunked_tag, "abcxyz"), IsOk());

  // Verify tag with ChunkedMac.
  util::StatusOr<std::unique_ptr<ChunkedMacVerification>> verification =
      (*chunked_mac)->CreateVerification(*tag);
  ASSERT_THAT(verification, IsOk());
  ASSERT_THAT((*verification)->Update("abc"), IsOk());
  ASSERT_THAT((*verification)->Update("xyz"), IsOk());
  EXPECT_THAT((*verification)->VerifyMac(), IsOk());
}

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