// Copyright 2018 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/signature/rsa_ssa_pss_sign_key_manager.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_set.h"
#include "openssl/rsa.h"
#include "tink/public_key_sign.h"
#include "tink/signature/rsa_ssa_pss_verify_key_manager.h"
#include "tink/signature/signature_key_templates.h"
#include "tink/subtle/rsa_ssa_pss_verify_boringssl.h"
#include "tink/subtle/subtle_util_boringssl.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/rsa_ssa_pss.pb.h"

namespace crypto {
namespace tink {
namespace {

using ::crypto::tink::subtle::SubtleUtilBoringSSL;
using ::crypto::tink::test::IsOk;
using ::crypto::tink::util::StatusOr;
using ::google::crypto::tink::HashType;
using ::google::crypto::tink::KeyData;
using ::google::crypto::tink::RsaSsaPssKeyFormat;
using ::google::crypto::tink::RsaSsaPssPrivateKey;
using ::google::crypto::tink::RsaSsaPssPublicKey;
using ::testing::Eq;
using ::testing::Gt;
using ::testing::Not;
using ::testing::SizeIs;

TEST(RsaSsaPssSignKeyManagerTest, Basic) {
  EXPECT_THAT(RsaSsaPssSignKeyManager().get_version(), Eq(0));
  EXPECT_THAT(RsaSsaPssSignKeyManager().key_material_type(),
              Eq(KeyData::ASYMMETRIC_PRIVATE));
  EXPECT_THAT(RsaSsaPssSignKeyManager().get_key_type(),
              Eq("type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey"));
}

RsaSsaPssKeyFormat CreateKeyFormat(HashType sig_hash, HashType mgf1_hash,
                                   int salt_length, int modulus_size_in_bits,
                                   int public_exponent) {
  RsaSsaPssKeyFormat key_format;
  auto params = key_format.mutable_params();
  params->set_sig_hash(sig_hash);
  params->set_mgf1_hash(mgf1_hash);
  params->set_salt_length(salt_length);
  key_format.set_modulus_size_in_bits(modulus_size_in_bits);

  bssl::UniquePtr<BIGNUM> e(BN_new());
  BN_set_word(e.get(), public_exponent);
  key_format.set_public_exponent(
      subtle::SubtleUtilBoringSSL::bn2str(e.get(), BN_num_bytes(e.get()))
          .ValueOrDie());

  return key_format;
}

RsaSsaPssKeyFormat ValidKeyFormat() {
  return CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4);
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormat) {
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(ValidKeyFormat()),
              IsOk());
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSha512Allowed) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.mutable_params()->set_sig_hash(HashType::SHA512);
  key_format.mutable_params()->set_mgf1_hash(HashType::SHA512);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(ValidKeyFormat()),
              IsOk());
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSha1Disallowed) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.mutable_params()->set_sig_hash(HashType::SHA1);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format),
              Not(IsOk()));
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatSmallModulusDisallowed) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.set_modulus_size_in_bits(512);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format),
              Not(IsOk()));
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatHashMismatchDisallowed) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.mutable_params()->set_sig_hash(HashType::SHA512);
  key_format.mutable_params()->set_mgf1_hash(HashType::SHA256);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format),
              Not(IsOk()));
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatHashMismatchDisallowed2) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.mutable_params()->set_sig_hash(HashType::SHA256);
  key_format.mutable_params()->set_mgf1_hash(HashType::SHA512);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format),
              Not(IsOk()));
}

TEST(RsaSsaPssSignKeyManagerTest, ValidateKeyFormatUnkownHashDisallowed) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  key_format.mutable_params()->set_sig_hash(HashType::UNKNOWN_HASH);
  key_format.mutable_params()->set_mgf1_hash(HashType::UNKNOWN_HASH);
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKeyFormat(key_format),
              Not(IsOk()));
}

// Runs several sanity checks, checking if a given private key fits a format.
void CheckNewKey(const RsaSsaPssPrivateKey& private_key,
                 const RsaSsaPssKeyFormat& key_format) {
  RsaSsaPssPublicKey public_key = private_key.public_key();

  EXPECT_THAT(private_key.version(), Eq(0));
  EXPECT_THAT(private_key.version(), Eq(public_key.version()));
  EXPECT_THAT(public_key.n().length(), Gt(0));
  EXPECT_THAT(public_key.e().length(), Gt(0));
  EXPECT_THAT(public_key.params().sig_hash(),
              Eq(key_format.params().sig_hash()));
  EXPECT_THAT(public_key.params().mgf1_hash(),
              Eq(key_format.params().mgf1_hash()));
  EXPECT_THAT(public_key.params().salt_length(),
              Eq(key_format.params().salt_length()));

  EXPECT_THAT(key_format.public_exponent(), Eq(public_key.e()));
  auto n = std::move(SubtleUtilBoringSSL::str2bn(public_key.n()).ValueOrDie());
  auto d = std::move(SubtleUtilBoringSSL::str2bn(private_key.d()).ValueOrDie());
  auto p = std::move(SubtleUtilBoringSSL::str2bn(private_key.p()).ValueOrDie());
  auto q = std::move(SubtleUtilBoringSSL::str2bn(private_key.q()).ValueOrDie());
  auto dp =
      std::move(SubtleUtilBoringSSL::str2bn(private_key.dp()).ValueOrDie());
  auto dq =
      std::move(SubtleUtilBoringSSL::str2bn(private_key.dq()).ValueOrDie());
  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());

  // Check n = p * q.
  auto n_calc = bssl::UniquePtr<BIGNUM>(BN_new());
  EXPECT_TRUE(BN_mul(n_calc.get(), p.get(), q.get(), ctx.get()));
  EXPECT_TRUE(BN_equal_consttime(n_calc.get(), n.get()));

  // Check n size >= modulus_size_in_bits bit.
  EXPECT_GE(BN_num_bits(n.get()), key_format.modulus_size_in_bits());

  // dp = d mod (p - 1)
  auto pm1 = bssl::UniquePtr<BIGNUM>(BN_dup(p.get()));
  EXPECT_TRUE(BN_sub_word(pm1.get(), 1));
  auto dp_calc = bssl::UniquePtr<BIGNUM>(BN_new());
  EXPECT_TRUE(BN_mod(dp_calc.get(), d.get(), pm1.get(), ctx.get()));
  EXPECT_TRUE(BN_equal_consttime(dp_calc.get(), dp.get()));

  // dq = d mod (q - 1)
  auto qm1 = bssl::UniquePtr<BIGNUM>(BN_dup(q.get()));
  EXPECT_TRUE(BN_sub_word(qm1.get(), 1));
  auto dq_calc = bssl::UniquePtr<BIGNUM>(BN_new());
  EXPECT_TRUE(BN_mod(dq_calc.get(), d.get(), qm1.get(), ctx.get()));
  EXPECT_TRUE(BN_equal_consttime(dq_calc.get(), dq.get()));
}

TEST(RsaSsaPssSignKeyManagerTest, CreateKey) {
  RsaSsaPssKeyFormat key_format = ValidKeyFormat();
  StatusOr<RsaSsaPssPrivateKey> private_key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(private_key_or.status(), IsOk());
  CheckNewKey(private_key_or.ValueOrDie(), key_format);
}

TEST(RsaSsaPssSignKeyManagerTest, CreateKeySmallKey) {
  RsaSsaPssKeyFormat key_format =
      CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4);

  StatusOr<RsaSsaPssPrivateKey> private_key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(private_key_or.status(), IsOk());
  CheckNewKey(private_key_or.ValueOrDie(), key_format);
}

TEST(RsaSsaPssSignKeyManagerTest, CreateKeyLargeKey) {
  RsaSsaPssKeyFormat key_format =
      CreateKeyFormat(HashType::SHA512, HashType::SHA512, 64, 4096, RSA_F4);

  StatusOr<RsaSsaPssPrivateKey> private_key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(private_key_or.status(), IsOk());
  CheckNewKey(private_key_or.ValueOrDie(), key_format);
}

TEST(RsaSsaPssSignKeyManagerTest, CreateKeyValid) {
  StatusOr<RsaSsaPssPrivateKey> key_or =
      RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat());
  ASSERT_THAT(key_or.status(), IsOk());
  EXPECT_THAT(RsaSsaPssSignKeyManager().ValidateKey(key_or.ValueOrDie()),
              IsOk());
}

// Check that in a bunch of CreateKey calls all generated primes are distinct.
TEST(RsaSsaPssSignKeyManagerTest, CreateKeyAlwaysNewRsaPair) {
  absl::flat_hash_set<std::string> keys;
  // This test takes about a second per key.
  int num_generated_keys = 5;
  for (int i = 0; i < num_generated_keys; ++i) {
    StatusOr<RsaSsaPssPrivateKey> key_or =
        RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat());
    ASSERT_THAT(key_or.status(), IsOk());
    keys.insert(key_or.ValueOrDie().p());
    keys.insert(key_or.ValueOrDie().q());
  }
  EXPECT_THAT(keys, SizeIs(2 * num_generated_keys));
}

TEST(RsaSsaPssSignKeyManagerTest, GetPublicKey) {
  StatusOr<RsaSsaPssPrivateKey> key_or =
      RsaSsaPssSignKeyManager().CreateKey(ValidKeyFormat());
  ASSERT_THAT(key_or.status(), IsOk());
  StatusOr<RsaSsaPssPublicKey> public_key_or =
      RsaSsaPssSignKeyManager().GetPublicKey(key_or.ValueOrDie());
  ASSERT_THAT(public_key_or.status(), IsOk());
  EXPECT_THAT(public_key_or.ValueOrDie().version(),
              Eq(key_or.ValueOrDie().public_key().version()));
  EXPECT_THAT(public_key_or.ValueOrDie().n(),
              Eq(key_or.ValueOrDie().public_key().n()));
  EXPECT_THAT(public_key_or.ValueOrDie().e(),
              Eq(key_or.ValueOrDie().public_key().e()));
}

TEST(EcdsaSignKeyManagerTest, Create) {
  RsaSsaPssKeyFormat key_format =
      CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4);
  StatusOr<RsaSsaPssPrivateKey> key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(key_or.status(), IsOk());
  RsaSsaPssPrivateKey key = key_or.ValueOrDie();

  auto signer_or = RsaSsaPssSignKeyManager().GetPrimitive<PublicKeySign>(key);
  ASSERT_THAT(signer_or.status(), IsOk());

  subtle::SubtleUtilBoringSSL::RsaSsaPssParams params;
  params.sig_hash = subtle::HashType::SHA256;
  params.mgf1_hash = subtle::HashType::SHA256;
  params.salt_length = 32;
  auto direct_verifier_or = subtle::RsaSsaPssVerifyBoringSsl::New(
      {key.public_key().n(), key.public_key().e()}, params);

  ASSERT_THAT(direct_verifier_or.status(), IsOk());

  std::string message = "Some message";
  EXPECT_THAT(direct_verifier_or.ValueOrDie()->Verify(
                  signer_or.ValueOrDie()->Sign(message).ValueOrDie(), message),
              IsOk());
}

TEST(EcdsaSignKeyManagerTest, CreateWrongKey) {
  RsaSsaPssKeyFormat key_format =
      CreateKeyFormat(HashType::SHA256, HashType::SHA256, 32, 3072, RSA_F4);
  StatusOr<RsaSsaPssPrivateKey> key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(key_or.status(), IsOk());
  RsaSsaPssPrivateKey key = key_or.ValueOrDie();

  auto signer_or = RsaSsaPssSignKeyManager().GetPrimitive<PublicKeySign>(key);

  StatusOr<RsaSsaPssPrivateKey> second_key_or =
      RsaSsaPssSignKeyManager().CreateKey(key_format);
  ASSERT_THAT(second_key_or.status(), IsOk());
  RsaSsaPssPrivateKey second_key = second_key_or.ValueOrDie();

  ASSERT_THAT(signer_or.status(), IsOk());

  subtle::SubtleUtilBoringSSL::RsaSsaPssParams params;
  params.sig_hash = subtle::HashType::SHA256;
  params.mgf1_hash = subtle::HashType::SHA256;
  params.salt_length = 32;
  auto direct_verifier_or = subtle::RsaSsaPssVerifyBoringSsl::New(
      {second_key.public_key().n(), second_key.public_key().e()}, params);

  ASSERT_THAT(direct_verifier_or.status(), IsOk());

  std::string message = "Some message";
  EXPECT_THAT(direct_verifier_or.ValueOrDie()->Verify(
                  signer_or.ValueOrDie()->Sign(message).ValueOrDie(), message),
              Not(IsOk()));
}

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