// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "missive/encryption/verification.h"

#include <memory>

#include "missive/encryption/primitives.h"
#include "missive/encryption/testing_primitives.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Ne;

namespace reporting {
namespace {

class VerificationTest : public ::testing::Test {
 protected:
  VerificationTest() = default;
  void SetUp() override {
    // Generate new pair of private key and public value.
    test::GenerateSigningKeyPair(private_key_, public_value_);
  }

  uint8_t public_value_[kKeySize];
  uint8_t private_key_[kSignKeySize];
};

TEST_F(VerificationTest, SignAndVerify) {
  static constexpr char message[] = "ABCDEF 012345";

  // Sign the message.
  uint8_t signature[kSignatureSize];
  test::SignMessage(private_key_, message, signature);

  // Verify the signature.
  SignatureVerifier verifier(
      std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
  EXPECT_OK(verifier.Verify(
      std::string(message, strlen(message)),
      std::string(reinterpret_cast<const char*>(signature), kSignatureSize)));
}

TEST_F(VerificationTest, SignAndFailBadSignature) {
  static constexpr char message[] = "ABCDEF 012345";

  // Sign the message.
  uint8_t signature[kSignatureSize];
  test::SignMessage(private_key_, message, signature);

  // Verify the signature - wrong length.
  SignatureVerifier verifier(
      std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
  Status status =
      verifier.Verify(std::string(message, strlen(message)),
                      std::string(reinterpret_cast<const char*>(signature),
                                  kSignatureSize - 1));
  EXPECT_THAT(status.code(), Eq(error::FAILED_PRECONDITION));
  EXPECT_THAT(status.message(), HasSubstr("Wrong signature size"));

  // Verify the signature - mismatch.
  signature[0] = ~signature[0];
  status = verifier.Verify(
      std::string(message, strlen(message)),
      std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
  EXPECT_THAT(status.code(), Eq(error::INVALID_ARGUMENT));
  EXPECT_THAT(status.message(), HasSubstr("Verification failed"));
}

TEST_F(VerificationTest, SignAndFailBadPublicKey) {
  static constexpr char message[] = "ABCDEF 012345";

  // Sign the message.
  uint8_t signature[kSignatureSize];
  test::SignMessage(private_key_, message, signature);

  // Verify the public key - wrong length.
  SignatureVerifier verifier(
      std::string(reinterpret_cast<const char*>(public_value_), kKeySize - 1));
  Status status = verifier.Verify(
      std::string(message, strlen(message)),
      std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
  EXPECT_THAT(status.code(), Eq(error::FAILED_PRECONDITION));
  EXPECT_THAT(status.message(), HasSubstr("Wrong public key size"));

  // Verify the public key - mismatch.
  public_value_[0] = ~public_value_[0];
  SignatureVerifier verifier2(
      std::string(reinterpret_cast<const char*>(public_value_), kKeySize));
  status = verifier2.Verify(
      std::string(message, strlen(message)),
      std::string(reinterpret_cast<const char*>(signature), kSignatureSize));
  EXPECT_THAT(status.code(), Eq(error::INVALID_ARGUMENT));
  EXPECT_THAT(status.message(), HasSubstr("Verification failed"));
}

TEST_F(VerificationTest, ValidateFixedKey) {
  // |dev_data_to_sign| is signed on DEV server, producing
  // |dev_server_signature|.
  static constexpr uint8_t dev_data_to_sign[] = {
      0x4D, 0x22, 0x5C, 0x4C, 0x74, 0x23, 0x82, 0x80, 0x58, 0xA2, 0x31, 0xA2,
      0xC6, 0xE2, 0x6D, 0xDA, 0x48, 0x82, 0x7A, 0x9C, 0xF7, 0xD0, 0x4A, 0xF2,
      0xFD, 0x19, 0x03, 0x7F, 0xC5, 0x6F, 0xBB, 0x49, 0xAF, 0x91, 0x7B, 0x74};
  static constexpr uint8_t dev_server_signature[kSignatureSize] = {
      0x0C, 0xA4, 0xAF, 0xE3, 0x27, 0x06, 0xD1, 0x4F, 0x0E, 0x05, 0x44,
      0x74, 0x0D, 0x4F, 0xA0, 0x4C, 0x26, 0xB1, 0x0C, 0x44, 0x92, 0x0F,
      0x96, 0xAF, 0x5A, 0x7E, 0x45, 0xED, 0x61, 0xB7, 0x87, 0xA8, 0xA3,
      0x98, 0x52, 0x97, 0x8D, 0x56, 0xA3, 0xED, 0xF7, 0x9B, 0x54, 0x17,
      0x61, 0x32, 0x6C, 0x06, 0x29, 0xBF, 0x30, 0x4E, 0x88, 0x72, 0xAB,
      0xE3, 0x60, 0xDA, 0xF0, 0x37, 0xEB, 0x56, 0x28, 0x0B};

  // Validate the signature using known DEV public key.
  SignatureVerifier dev_verifier(SignatureVerifier::VerificationKeyDev());
  const auto dev_result = dev_verifier.Verify(
      std::string(reinterpret_cast<const char*>(dev_data_to_sign),
                  sizeof(dev_data_to_sign)),
      std::string(reinterpret_cast<const char*>(dev_server_signature),
                  kSignatureSize));
  EXPECT_OK(dev_result) << dev_result;

  // |prod_data_to_sign| is signed on PROD server, producing
  // |prod_server_signature|.
  static constexpr uint8_t prod_data_to_sign[] = {
      0xB3, 0xF9, 0xA3, 0xCC, 0xEB, 0x42, 0x88, 0x6b, 0x3f, 0x7b, 0x93, 0xC3,
      0xD3, 0x61, 0x9C, 0x45, 0xB4, 0xD7, 0x4B, 0x7B, 0x4F, 0xA7, 0x1A, 0x29,
      0xE1, 0x95, 0x14, 0xA4, 0x8C, 0x21, 0x36, 0x9F, 0x34, 0xA7, 0x4A, 0x57};
  static constexpr uint8_t prod_server_signature[kSignatureSize] = {
      0x17, 0xA4, 0x18, 0xA3, 0x78, 0x7A, 0x75, 0x24, 0xD9, 0x81, 0x3D,
      0x9F, 0x17, 0x28, 0x40, 0xD8, 0xE7, 0x67, 0x88, 0x17, 0x44, 0x7C,
      0xC2, 0x1A, 0xE2, 0x73, 0xAC, 0xB1, 0x0B, 0xCE, 0x60, 0xBB, 0x30,
      0x58, 0xCE, 0xF6, 0x8E, 0x33, 0xB6, 0xC6, 0x18, 0x3C, 0xA7, 0xD4,
      0x38, 0x91, 0x90, 0x2C, 0xBC, 0xB9, 0x76, 0x3C, 0xFF, 0x6F, 0x84,
      0xEC, 0x2D, 0x1E, 0x73, 0x43, 0x1B, 0x75, 0x5E, 0x0E};

  // Validate the signature using known PROD public key.
  SignatureVerifier prod_verifier(SignatureVerifier::VerificationKey());
  const auto prod_result = prod_verifier.Verify(
      std::string(reinterpret_cast<const char*>(prod_data_to_sign),
                  sizeof(prod_data_to_sign)),
      std::string(reinterpret_cast<const char*>(prod_server_signature),
                  kSignatureSize));
  EXPECT_OK(prod_result) << prod_result;
}

}  // namespace
}  // namespace reporting
