// Copyright (c) 2013 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 "net/quic/crypto/cert_compressor.h"

#include "base/strings/string_number_conversions.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::StringPiece;
using std::string;
using std::vector;

namespace net {
namespace test {

TEST(CertCompressor, EmptyChain) {
  vector<string> chain;
  const string compressed = CertCompressor::CompressChain(
      chain, StringPiece(), StringPiece(), nullptr);
  EXPECT_EQ("00", base::HexEncode(compressed.data(), compressed.size()));

  vector<string> chain2, cached_certs;
  ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
                                              &chain2));
  EXPECT_EQ(chain.size(), chain2.size());
}

TEST(CertCompressor, Compressed) {
  vector<string> chain;
  chain.push_back("testcert");
  const string compressed = CertCompressor::CompressChain(
      chain, StringPiece(), StringPiece(), nullptr);
  ASSERT_GE(compressed.size(), 2u);
  EXPECT_EQ("0100", base::HexEncode(compressed.substr(0, 2).data(), 2));

  vector<string> chain2, cached_certs;
  ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
                                              &chain2));
  EXPECT_EQ(chain.size(), chain2.size());
  EXPECT_EQ(chain[0], chain2[0]);
}

TEST(CertCompressor, Common) {
  vector<string> chain;
  chain.push_back("testcert");
  static const uint64 set_hash = 42;
  scoped_ptr<CommonCertSets> common_sets(
      CryptoTestUtils::MockCommonCertSets(chain[0], set_hash, 1));
  const string compressed = CertCompressor::CompressChain(
      chain,
      StringPiece(reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)),
      StringPiece(), common_sets.get());
  const string common("03"               /* common */
                      "2A00000000000000" /* set hash 42 */
                      "01000000"         /* index 1 */
                      "00"               /* end of list */);
  EXPECT_EQ(common.data(),
            base::HexEncode(compressed.data(), compressed.size()));

  vector<string> chain2, cached_certs;
  ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs,
                                              common_sets.get(), &chain2));
  EXPECT_EQ(chain.size(), chain2.size());
  EXPECT_EQ(chain[0], chain2[0]);
}

TEST(CertCompressor, Cached) {
  vector<string> chain;
  chain.push_back("testcert");
  uint64 hash = QuicUtils::FNV1a_64_Hash(chain[0].data(), chain[0].size());
  StringPiece hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
  const string compressed =
      CertCompressor::CompressChain(chain, StringPiece(), hash_bytes, nullptr);

  EXPECT_EQ("02" /* cached */ +
            base::HexEncode(hash_bytes.data(), hash_bytes.size()) +
            "00" /* end of list */,
            base::HexEncode(compressed.data(), compressed.size()));

  vector<string> cached_certs, chain2;
  cached_certs.push_back(chain[0]);
  ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs, nullptr,
                                              &chain2));
  EXPECT_EQ(chain.size(), chain2.size());
  EXPECT_EQ(chain[0], chain2[0]);
}

TEST(CertCompressor, BadInputs) {
  vector<string> cached_certs, chain;

  /* bad entry type */
  const string bad_entry("04");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(bad_entry.data(), bad_entry.size()),
      cached_certs, nullptr, &chain));

  /* no terminator */
  const string no_terminator("01");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(no_terminator.data(), no_terminator.size()),
      cached_certs, nullptr, &chain));

  /* hash truncated */
  const string hash_truncated("0200");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(hash_truncated.data(), hash_truncated.size()),
      cached_certs, nullptr, &chain));

  /* hash and index truncated */
  const string hash_and_index_truncated("0300");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(hash_and_index_truncated.data(),
                      hash_and_index_truncated.size()),
      cached_certs, nullptr, &chain));

  /* without a CommonCertSets */
  const string without_a_common_cert_set(
      "03" "0000000000000000" "00000000");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(without_a_common_cert_set.data(),
                      without_a_common_cert_set.size()),
      cached_certs, nullptr, &chain));

  scoped_ptr<CommonCertSets> common_sets(
      CryptoTestUtils::MockCommonCertSets("foo", 42, 1));

  /* incorrect hash and index */
  const string incorrect_hash_and_index(
      "03" "a200000000000000" "00000000");
  EXPECT_FALSE(CertCompressor::DecompressChain(
      base::HexEncode(incorrect_hash_and_index.data(),
                      incorrect_hash_and_index.size()),
      cached_certs, nullptr, &chain));
}

}  // namespace test
}  // namespace net
