Home | History | Annotate | Download | only in crypto
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/crypto/cert_compressor.h"
      6 
      7 #include "base/strings/string_number_conversions.h"
      8 #include "net/quic/quic_utils.h"
      9 #include "net/quic/test_tools/crypto_test_utils.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 using base::StringPiece;
     13 using std::string;
     14 using std::vector;
     15 
     16 namespace net {
     17 namespace test {
     18 
     19 TEST(CertCompressor, EmptyChain) {
     20   vector<string> chain;
     21   const string compressed =
     22       CertCompressor::CompressChain(chain, StringPiece(), StringPiece(), NULL);
     23   EXPECT_EQ("00", base::HexEncode(compressed.data(), compressed.size()));
     24 
     25   vector<string> chain2, cached_certs;
     26   ASSERT_TRUE(
     27       CertCompressor::DecompressChain(compressed, cached_certs, NULL, &chain2));
     28   EXPECT_EQ(chain.size(), chain2.size());
     29 }
     30 
     31 TEST(CertCompressor, Compressed) {
     32   vector<string> chain;
     33   chain.push_back("testcert");
     34   const string compressed =
     35       CertCompressor::CompressChain(chain, StringPiece(), StringPiece(), NULL);
     36   ASSERT_GE(compressed.size(), 2u);
     37   EXPECT_EQ("0100", base::HexEncode(compressed.substr(0, 2).data(), 2));
     38 
     39   vector<string> chain2, cached_certs;
     40   ASSERT_TRUE(
     41       CertCompressor::DecompressChain(compressed, cached_certs, NULL, &chain2));
     42   EXPECT_EQ(chain.size(), chain2.size());
     43   EXPECT_EQ(chain[0], chain2[0]);
     44 }
     45 
     46 TEST(CertCompressor, Common) {
     47   vector<string> chain;
     48   chain.push_back("testcert");
     49   static const uint64 set_hash = 42;
     50   scoped_ptr<CommonCertSets> common_sets(
     51       CryptoTestUtils::MockCommonCertSets(chain[0], set_hash, 1));
     52   const string compressed = CertCompressor::CompressChain(
     53       chain,
     54       StringPiece(reinterpret_cast<const char*>(&set_hash), sizeof(set_hash)),
     55       StringPiece(), common_sets.get());
     56   const string common("03"               /* common */
     57                       "2A00000000000000" /* set hash 42 */
     58                       "01000000"         /* index 1 */
     59                       "00"               /* end of list */);
     60   EXPECT_EQ(common.data(),
     61             base::HexEncode(compressed.data(), compressed.size()));
     62 
     63   vector<string> chain2, cached_certs;
     64   ASSERT_TRUE(CertCompressor::DecompressChain(compressed, cached_certs,
     65                                               common_sets.get(), &chain2));
     66   EXPECT_EQ(chain.size(), chain2.size());
     67   EXPECT_EQ(chain[0], chain2[0]);
     68 }
     69 
     70 TEST(CertCompressor, Cached) {
     71   vector<string> chain;
     72   chain.push_back("testcert");
     73   uint64 hash = QuicUtils::FNV1a_64_Hash(chain[0].data(), chain[0].size());
     74   StringPiece hash_bytes(reinterpret_cast<char*>(&hash), sizeof(hash));
     75   const string compressed =
     76       CertCompressor::CompressChain(chain, StringPiece(), hash_bytes, NULL);
     77 
     78   EXPECT_EQ("02" /* cached */ +
     79             base::HexEncode(hash_bytes.data(), hash_bytes.size()) +
     80             "00" /* end of list */,
     81             base::HexEncode(compressed.data(), compressed.size()));
     82 
     83   vector<string> cached_certs, chain2;
     84   cached_certs.push_back(chain[0]);
     85   ASSERT_TRUE(
     86       CertCompressor::DecompressChain(compressed, cached_certs, NULL, &chain2));
     87   EXPECT_EQ(chain.size(), chain2.size());
     88   EXPECT_EQ(chain[0], chain2[0]);
     89 }
     90 
     91 TEST(CertCompressor, BadInputs) {
     92   vector<string> cached_certs, chain;
     93 
     94   /* bad entry type */
     95   const string bad_entry("04");
     96   EXPECT_FALSE(CertCompressor::DecompressChain(
     97       base::HexEncode(bad_entry.data(), bad_entry.size()),
     98       cached_certs, NULL, &chain));
     99 
    100   /* no terminator */
    101   const string no_terminator("01");
    102   EXPECT_FALSE(CertCompressor::DecompressChain(
    103       base::HexEncode(no_terminator.data(), no_terminator.size()),
    104       cached_certs, NULL, &chain));
    105 
    106   /* hash truncated */
    107   const string hash_truncated("0200");
    108   EXPECT_FALSE(CertCompressor::DecompressChain(
    109       base::HexEncode(hash_truncated.data(), hash_truncated.size()),
    110       cached_certs, NULL, &chain));
    111 
    112   /* hash and index truncated */
    113   const string hash_and_index_truncated("0300");
    114   EXPECT_FALSE(CertCompressor::DecompressChain(
    115       base::HexEncode(hash_and_index_truncated.data(),
    116                       hash_and_index_truncated.size()),
    117       cached_certs, NULL, &chain));
    118 
    119   /* without a CommonCertSets */
    120   const string without_a_common_cert_set(
    121       "03" "0000000000000000" "00000000");
    122   EXPECT_FALSE(CertCompressor::DecompressChain(
    123       base::HexEncode(without_a_common_cert_set.data(),
    124                       without_a_common_cert_set.size()),
    125       cached_certs, NULL, &chain));
    126 
    127   scoped_ptr<CommonCertSets> common_sets(
    128       CryptoTestUtils::MockCommonCertSets("foo", 42, 1));
    129 
    130   /* incorrect hash and index */
    131   const string incorrect_hash_and_index(
    132       "03" "a200000000000000" "00000000");
    133   EXPECT_FALSE(CertCompressor::DecompressChain(
    134       base::HexEncode(incorrect_hash_and_index.data(),
    135                       incorrect_hash_and_index.size()),
    136       cached_certs, NULL, &chain));
    137 }
    138 
    139 }  // namespace test
    140 }  // namespace net
    141