1 // Copyright 2016 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 "quiche/quic/core/crypto/quic_compressed_certs_cache.h"
6 
7 #include <string>
8 
9 #include "absl/strings/str_cat.h"
10 #include "quiche/quic/core/crypto/cert_compressor.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 #include "quiche/quic/test_tools/crypto_test_utils.h"
13 
14 namespace quic {
15 
16 namespace test {
17 
18 namespace {
19 
20 class QuicCompressedCertsCacheTest : public QuicTest {
21  public:
QuicCompressedCertsCacheTest()22   QuicCompressedCertsCacheTest()
23       : certs_cache_(QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) {}
24 
25  protected:
26   QuicCompressedCertsCache certs_cache_;
27 };
28 
TEST_F(QuicCompressedCertsCacheTest,CacheHit)29 TEST_F(QuicCompressedCertsCacheTest, CacheHit) {
30   std::vector<std::string> certs = {"leaf cert", "intermediate cert",
31                                     "root cert"};
32   quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
33       new ProofSource::Chain(certs));
34   std::string cached_certs = "cached certs";
35   std::string compressed = "compressed cert";
36 
37   certs_cache_.Insert(chain, cached_certs, compressed);
38 
39   const std::string* cached_value =
40       certs_cache_.GetCompressedCert(chain, cached_certs);
41   ASSERT_NE(nullptr, cached_value);
42   EXPECT_EQ(*cached_value, compressed);
43 }
44 
TEST_F(QuicCompressedCertsCacheTest,CacheMiss)45 TEST_F(QuicCompressedCertsCacheTest, CacheMiss) {
46   std::vector<std::string> certs = {"leaf cert", "intermediate cert",
47                                     "root cert"};
48   quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
49       new ProofSource::Chain(certs));
50 
51   std::string cached_certs = "cached certs";
52   std::string compressed = "compressed cert";
53 
54   certs_cache_.Insert(chain, cached_certs, compressed);
55 
56   EXPECT_EQ(nullptr,
57             certs_cache_.GetCompressedCert(chain, "mismatched cached certs"));
58 
59   // A different chain though with equivalent certs should get a cache miss.
60   quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain2(
61       new ProofSource::Chain(certs));
62   EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain2, cached_certs));
63 }
64 
TEST_F(QuicCompressedCertsCacheTest,CacheMissDueToEviction)65 TEST_F(QuicCompressedCertsCacheTest, CacheMissDueToEviction) {
66   // Test cache returns a miss when a queried uncompressed certs was cached but
67   // then evicted.
68   std::vector<std::string> certs = {"leaf cert", "intermediate cert",
69                                     "root cert"};
70   quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain(
71       new ProofSource::Chain(certs));
72 
73   std::string cached_certs = "cached certs";
74   std::string compressed = "compressed cert";
75   certs_cache_.Insert(chain, cached_certs, compressed);
76 
77   // Insert another kQuicCompressedCertsCacheSize certs to evict the first
78   // cached cert.
79   for (unsigned int i = 0;
80        i < QuicCompressedCertsCache::kQuicCompressedCertsCacheSize; i++) {
81     EXPECT_EQ(certs_cache_.Size(), i + 1);
82     certs_cache_.Insert(chain, absl::StrCat(i), absl::StrCat(i));
83   }
84   EXPECT_EQ(certs_cache_.MaxSize(), certs_cache_.Size());
85 
86   EXPECT_EQ(nullptr, certs_cache_.GetCompressedCert(chain, cached_certs));
87 }
88 
89 }  // namespace
90 }  // namespace test
91 }  // namespace quic
92