xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/test_ticket_crypter.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 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/test_tools/test_ticket_crypter.h"
6 
7 #include <cstring>
8 
9 #include "absl/base/macros.h"
10 #include "quiche/quic/core/crypto/quic_random.h"
11 
12 namespace quic {
13 namespace test {
14 
15 namespace {
16 
17 // A TicketCrypter implementation is supposed to encrypt and decrypt session
18 // tickets. However, the only requirement that is needed of a test
19 // implementation is that calling Decrypt(Encrypt(input), callback) results in
20 // callback being called with input. (The output of Encrypt must also not exceed
21 // the overhead specified by MaxOverhead.) This test implementation encrypts
22 // tickets by prepending kTicketPrefix to generate the ciphertext. The decrypt
23 // function checks that the prefix is present and strips it; otherwise it
24 // returns an empty vector to signal failure.
25 constexpr char kTicketPrefix[] = "TEST TICKET";
26 
27 }  // namespace
28 
TestTicketCrypter()29 TestTicketCrypter::TestTicketCrypter()
30     : ticket_prefix_(ABSL_ARRAYSIZE(kTicketPrefix) + 16) {
31   memcpy(ticket_prefix_.data(), kTicketPrefix, ABSL_ARRAYSIZE(kTicketPrefix));
32   QuicRandom::GetInstance()->RandBytes(
33       ticket_prefix_.data() + ABSL_ARRAYSIZE(kTicketPrefix), 16);
34 }
35 
MaxOverhead()36 size_t TestTicketCrypter::MaxOverhead() { return ticket_prefix_.size(); }
37 
Encrypt(absl::string_view in,absl::string_view)38 std::vector<uint8_t> TestTicketCrypter::Encrypt(
39     absl::string_view in, absl::string_view /* encryption_key */) {
40   if (fail_encrypt_) {
41     return {};
42   }
43   size_t prefix_len = ticket_prefix_.size();
44   std::vector<uint8_t> out(prefix_len + in.size());
45   memcpy(out.data(), ticket_prefix_.data(), prefix_len);
46   memcpy(out.data() + prefix_len, in.data(), in.size());
47   return out;
48 }
49 
Decrypt(absl::string_view in)50 std::vector<uint8_t> TestTicketCrypter::Decrypt(absl::string_view in) {
51   size_t prefix_len = ticket_prefix_.size();
52   if (fail_decrypt_ || in.size() < prefix_len ||
53       memcmp(ticket_prefix_.data(), in.data(), prefix_len) != 0) {
54     return std::vector<uint8_t>();
55   }
56   return std::vector<uint8_t>(in.begin() + prefix_len, in.end());
57 }
58 
Decrypt(absl::string_view in,std::shared_ptr<ProofSource::DecryptCallback> callback)59 void TestTicketCrypter::Decrypt(
60     absl::string_view in,
61     std::shared_ptr<ProofSource::DecryptCallback> callback) {
62   auto decrypted_ticket = Decrypt(in);
63   if (run_async_) {
64     pending_callbacks_.push_back({std::move(callback), decrypted_ticket});
65   } else {
66     callback->Run(decrypted_ticket);
67   }
68 }
69 
SetRunCallbacksAsync(bool run_async)70 void TestTicketCrypter::SetRunCallbacksAsync(bool run_async) {
71   run_async_ = run_async;
72 }
73 
NumPendingCallbacks()74 size_t TestTicketCrypter::NumPendingCallbacks() {
75   return pending_callbacks_.size();
76 }
77 
RunPendingCallback(size_t n)78 void TestTicketCrypter::RunPendingCallback(size_t n) {
79   const PendingCallback& callback = pending_callbacks_[n];
80   callback.callback->Run(callback.decrypted_ticket);
81 }
82 
83 }  // namespace test
84 }  // namespace quic
85