xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/simple_ticket_crypter_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 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/tools/simple_ticket_crypter.h"
6 
7 #include "quiche/quic/platform/api/quic_test.h"
8 #include "quiche/quic/test_tools/mock_clock.h"
9 
10 namespace quic {
11 namespace test {
12 
13 namespace {
14 
15 constexpr QuicTime::Delta kOneDay = QuicTime::Delta::FromSeconds(60 * 60 * 24);
16 
17 }  // namespace
18 
19 class DecryptCallback : public quic::ProofSource::DecryptCallback {
20  public:
DecryptCallback(std::vector<uint8_t> * out)21   explicit DecryptCallback(std::vector<uint8_t>* out) : out_(out) {}
22 
Run(std::vector<uint8_t> plaintext)23   void Run(std::vector<uint8_t> plaintext) override { *out_ = plaintext; }
24 
25  private:
26   std::vector<uint8_t>* out_;
27 };
28 
StringPiece(const std::vector<uint8_t> & in)29 absl::string_view StringPiece(const std::vector<uint8_t>& in) {
30   return absl::string_view(reinterpret_cast<const char*>(in.data()), in.size());
31 }
32 
33 class SimpleTicketCrypterTest : public QuicTest {
34  public:
SimpleTicketCrypterTest()35   SimpleTicketCrypterTest() : ticket_crypter_(&mock_clock_) {}
36 
37  protected:
38   MockClock mock_clock_;
39   SimpleTicketCrypter ticket_crypter_;
40 };
41 
TEST_F(SimpleTicketCrypterTest,EncryptDecrypt)42 TEST_F(SimpleTicketCrypterTest, EncryptDecrypt) {
43   std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
44   std::vector<uint8_t> ciphertext =
45       ticket_crypter_.Encrypt(StringPiece(plaintext), {});
46   EXPECT_NE(plaintext, ciphertext);
47 
48   std::vector<uint8_t> out_plaintext;
49   ticket_crypter_.Decrypt(StringPiece(ciphertext),
50                           std::make_unique<DecryptCallback>(&out_plaintext));
51   EXPECT_EQ(out_plaintext, plaintext);
52 }
53 
TEST_F(SimpleTicketCrypterTest,CiphertextsDiffer)54 TEST_F(SimpleTicketCrypterTest, CiphertextsDiffer) {
55   std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
56   std::vector<uint8_t> ciphertext1 =
57       ticket_crypter_.Encrypt(StringPiece(plaintext), {});
58   std::vector<uint8_t> ciphertext2 =
59       ticket_crypter_.Encrypt(StringPiece(plaintext), {});
60   EXPECT_NE(ciphertext1, ciphertext2);
61 }
62 
TEST_F(SimpleTicketCrypterTest,DecryptionFailureWithModifiedCiphertext)63 TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithModifiedCiphertext) {
64   std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
65   std::vector<uint8_t> ciphertext =
66       ticket_crypter_.Encrypt(StringPiece(plaintext), {});
67   EXPECT_NE(plaintext, ciphertext);
68 
69   // Check that a bit flip in any byte will cause a decryption failure.
70   for (size_t i = 0; i < ciphertext.size(); i++) {
71     SCOPED_TRACE(i);
72     std::vector<uint8_t> munged_ciphertext = ciphertext;
73     munged_ciphertext[i] ^= 1;
74     std::vector<uint8_t> out_plaintext;
75     ticket_crypter_.Decrypt(StringPiece(munged_ciphertext),
76                             std::make_unique<DecryptCallback>(&out_plaintext));
77     EXPECT_TRUE(out_plaintext.empty());
78   }
79 }
80 
TEST_F(SimpleTicketCrypterTest,DecryptionFailureWithEmptyCiphertext)81 TEST_F(SimpleTicketCrypterTest, DecryptionFailureWithEmptyCiphertext) {
82   std::vector<uint8_t> out_plaintext;
83   ticket_crypter_.Decrypt(absl::string_view(),
84                           std::make_unique<DecryptCallback>(&out_plaintext));
85   EXPECT_TRUE(out_plaintext.empty());
86 }
87 
TEST_F(SimpleTicketCrypterTest,KeyRotation)88 TEST_F(SimpleTicketCrypterTest, KeyRotation) {
89   std::vector<uint8_t> plaintext = {1, 2, 3};
90   std::vector<uint8_t> ciphertext =
91       ticket_crypter_.Encrypt(StringPiece(plaintext), {});
92   EXPECT_FALSE(ciphertext.empty());
93 
94   // Advance the clock 8 days, so the key used for |ciphertext| is now the
95   // previous key. Check that decryption still works.
96   mock_clock_.AdvanceTime(kOneDay * 8);
97   std::vector<uint8_t> out_plaintext;
98   ticket_crypter_.Decrypt(StringPiece(ciphertext),
99                           std::make_unique<DecryptCallback>(&out_plaintext));
100   EXPECT_EQ(out_plaintext, plaintext);
101 
102   // Advance the clock 8 more days. Now the original key should be expired and
103   // decryption should fail.
104   mock_clock_.AdvanceTime(kOneDay * 8);
105   ticket_crypter_.Decrypt(StringPiece(ciphertext),
106                           std::make_unique<DecryptCallback>(&out_plaintext));
107   EXPECT_TRUE(out_plaintext.empty());
108 }
109 
110 }  // namespace test
111 }  // namespace quic
112