// Copyright (c) 2012 The Chromium 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 "quic/core/crypto/crypto_framer.h"

#include <map>
#include <memory>
#include <vector>

#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "quic/core/crypto/crypto_handshake.h"
#include "quic/core/crypto/crypto_protocol.h"
#include "quic/core/quic_packets.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/crypto_test_utils.h"
#include "quic/test_tools/quic_test_utils.h"
#include "common/test_tools/quiche_test_utils.h"

namespace quic {
namespace test {
namespace {

char* AsChars(unsigned char* data) {
  return reinterpret_cast<char*>(data);
}

class TestCryptoVisitor : public CryptoFramerVisitorInterface {
 public:
  TestCryptoVisitor() : error_count_(0) {}

  void OnError(CryptoFramer* framer) override {
    QUIC_DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
    ++error_count_;
  }

  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override {
    messages_.push_back(message);
  }

  // Counters from the visitor callbacks.
  int error_count_;

  std::vector<CryptoHandshakeMessage> messages_;
};

TEST(CryptoFramerTest, ConstructHandshakeMessage) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  message.SetStringPiece(0x12345678, "abcdef");
  message.SetStringPiece(0x12345679, "ghijk");
  message.SetStringPiece(0x1234567A, "lmnopqr");

  unsigned char packet[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x03, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x06, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x0b, 0x00, 0x00, 0x00,
      // tag 3
      0x7A, 0x56, 0x34, 0x12,
      // end offset 3
      0x12, 0x00, 0x00, 0x00,
      // value 1
      'a', 'b', 'c', 'd', 'e', 'f',
      // value 2
      'g', 'h', 'i', 'j', 'k',
      // value 3
      'l', 'm', 'n', 'o', 'p', 'q', 'r',
  };

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  ASSERT_TRUE(data != nullptr);
  quiche::test::CompareCharArraysWithHexError(
      "constructed packet", data->data(), data->length(), AsChars(packet),
      ABSL_ARRAYSIZE(packet));
}

TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  message.SetStringPiece(0x12345678, "abcdef");
  message.SetStringPiece(0x12345679, "ghijk");

  unsigned char packet[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x06, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x0b, 0x00, 0x00, 0x00,
      // value 1
      'a', 'b', 'c', 'd', 'e', 'f',
      // value 2
      'g', 'h', 'i', 'j', 'k',
  };

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  ASSERT_TRUE(data != nullptr);

  quiche::test::CompareCharArraysWithHexError(
      "constructed packet", data->data(), data->length(), AsChars(packet),
      ABSL_ARRAYSIZE(packet));
}

TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  message.SetStringPiece(0x12345678, "");

  unsigned char packet[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x01, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x00, 0x00, 0x00, 0x00,
  };

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  ASSERT_TRUE(data != nullptr);

  quiche::test::CompareCharArraysWithHexError(
      "constructed packet", data->data(), data->length(), AsChars(packet),
      ABSL_ARRAYSIZE(packet));
}

TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  for (uint32_t key = 1; key <= kMaxEntries + 1; ++key) {
    message.SetStringPiece(key, "abcdef");
  }

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  EXPECT_TRUE(data == nullptr);
}

TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  message.SetStringPiece(0x01020304, "test");
  message.set_minimum_size(64);

  unsigned char packet[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      'P', 'A', 'D', 0,
      // end offset 1
      0x24, 0x00, 0x00, 0x00,
      // tag 2
      0x04, 0x03, 0x02, 0x01,
      // end offset 2
      0x28, 0x00, 0x00, 0x00,
      // 36 bytes of padding.
      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
      '-', '-', '-', '-', '-', '-',
      // value 2
      't', 'e', 's', 't',
  };

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  ASSERT_TRUE(data != nullptr);

  quiche::test::CompareCharArraysWithHexError(
      "constructed packet", data->data(), data->length(), AsChars(packet),
      ABSL_ARRAYSIZE(packet));
}

TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
  CryptoHandshakeMessage message;
  message.set_tag(0xFFAA7733);
  message.SetStringPiece(1, "");
  message.set_minimum_size(64);

  unsigned char packet[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x01, 0x00, 0x00, 0x00,
      // end offset 1
      0x00, 0x00, 0x00, 0x00,
      // tag 2
      'P', 'A', 'D', 0,
      // end offset 2
      0x28, 0x00, 0x00, 0x00,
      // 40 bytes of padding.
      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
      '-', '-', '-', '-', '-', '-', '-', '-', '-', '-',
  };

  CryptoFramer framer;
  std::unique_ptr<QuicData> data = framer.ConstructHandshakeMessage(message);
  ASSERT_TRUE(data != nullptr);

  quiche::test::CompareCharArraysWithHexError(
      "constructed packet", data->data(), data->length(), AsChars(packet),
      ABSL_ARRAYSIZE(packet));
}

TEST(CryptoFramerTest, ProcessInput) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x06, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x0b, 0x00, 0x00, 0x00,
      // value 1
      'a', 'b', 'c', 'd', 'e', 'f',
      // value 2
      'g', 'h', 'i', 'j', 'k',
  };

  EXPECT_TRUE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_EQ(0u, framer.InputBytesRemaining());
  EXPECT_EQ(0, visitor.error_count_);
  ASSERT_EQ(1u, visitor.messages_.size());
  const CryptoHandshakeMessage& message = visitor.messages_[0];
  EXPECT_EQ(0xFFAA7733, message.tag());
  EXPECT_EQ(2u, message.tag_value_map().size());
  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
}

TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x03, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x06, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x0b, 0x00, 0x00, 0x00,
      // tag 3
      0x7A, 0x56, 0x34, 0x12,
      // end offset 3
      0x12, 0x00, 0x00, 0x00,
      // value 1
      'a', 'b', 'c', 'd', 'e', 'f',
      // value 2
      'g', 'h', 'i', 'j', 'k',
      // value 3
      'l', 'm', 'n', 'o', 'p', 'q', 'r',
  };

  EXPECT_TRUE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_EQ(0u, framer.InputBytesRemaining());
  EXPECT_EQ(0, visitor.error_count_);
  ASSERT_EQ(1u, visitor.messages_.size());
  const CryptoHandshakeMessage& message = visitor.messages_[0];
  EXPECT_EQ(0xFFAA7733, message.tag());
  EXPECT_EQ(3u, message.tag_value_map().size());
  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
  EXPECT_EQ("lmnopqr", crypto_test_utils::GetValueForTag(message, 0x1234567A));
}

TEST(CryptoFramerTest, ProcessInputIncrementally) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x06, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x0b, 0x00, 0x00, 0x00,
      // value 1
      'a', 'b', 'c', 'd', 'e', 'f',
      // value 2
      'g', 'h', 'i', 'j', 'k',
  };

  for (size_t i = 0; i < ABSL_ARRAYSIZE(input); i++) {
    EXPECT_TRUE(framer.ProcessInput(absl::string_view(AsChars(input) + i, 1)));
  }
  EXPECT_EQ(0u, framer.InputBytesRemaining());
  ASSERT_EQ(1u, visitor.messages_.size());
  const CryptoHandshakeMessage& message = visitor.messages_[0];
  EXPECT_EQ(0xFFAA7733, message.tag());
  EXPECT_EQ(2u, message.tag_value_map().size());
  EXPECT_EQ("abcdef", crypto_test_utils::GetValueForTag(message, 0x12345678));
  EXPECT_EQ("ghijk", crypto_test_utils::GetValueForTag(message, 0x12345679));
}

TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x13,
      // end offset 1
      0x01, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x02, 0x00, 0x00, 0x00,
  };

  EXPECT_FALSE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
  EXPECT_EQ(1, visitor.error_count_);
}

TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x79, 0x56, 0x34, 0x12,
      // end offset 1
      0x01, 0x00, 0x00, 0x00,
      // tag 2
      0x78, 0x56, 0x34, 0x13,
      // end offset 2
      0x00, 0x00, 0x00, 0x00,
  };

  EXPECT_FALSE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TAGS_OUT_OF_ORDER));
  EXPECT_EQ(1, visitor.error_count_);
}

TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0xA0, 0x00,
      // padding
      0x00, 0x00,
  };

  EXPECT_FALSE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_THAT(framer.error(), IsError(QUIC_CRYPTO_TOO_MANY_ENTRIES));
  EXPECT_EQ(1, visitor.error_count_);
}

TEST(CryptoFramerTest, ProcessInputZeroLength) {
  test::TestCryptoVisitor visitor;
  CryptoFramer framer;
  framer.set_visitor(&visitor);

  unsigned char input[] = {
      // tag
      0x33, 0x77, 0xAA, 0xFF,
      // num entries
      0x02, 0x00,
      // padding
      0x00, 0x00,
      // tag 1
      0x78, 0x56, 0x34, 0x12,
      // end offset 1
      0x00, 0x00, 0x00, 0x00,
      // tag 2
      0x79, 0x56, 0x34, 0x12,
      // end offset 2
      0x05, 0x00, 0x00, 0x00,
  };

  EXPECT_TRUE(framer.ProcessInput(
      absl::string_view(AsChars(input), ABSL_ARRAYSIZE(input))));
  EXPECT_EQ(0, visitor.error_count_);
}

}  // namespace
}  // namespace test
}  // namespace quic
