xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/fake_proof_source_handle.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2021 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/fake_proof_source_handle.h"
6 
7 #include <cstddef>
8 #include <cstdint>
9 #include <memory>
10 #include <optional>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "absl/strings/string_view.h"
16 #include "quiche/quic/core/crypto/proof_source.h"
17 #include "quiche/quic/core/quic_connection_id.h"
18 #include "quiche/quic/core/quic_types.h"
19 #include "quiche/quic/platform/api/quic_bug_tracker.h"
20 #include "quiche/quic/platform/api/quic_socket_address.h"
21 #include "quiche/common/platform/api/quiche_logging.h"
22 #include "quiche/common/platform/api/quiche_reference_counted.h"
23 
24 namespace quic {
25 namespace test {
26 namespace {
27 
28 struct ComputeSignatureResult {
29   bool ok;
30   std::string signature;
31   std::unique_ptr<ProofSource::Details> details;
32 };
33 
34 class ResultSavingSignatureCallback : public ProofSource::SignatureCallback {
35  public:
ResultSavingSignatureCallback(std::optional<ComputeSignatureResult> * result)36   explicit ResultSavingSignatureCallback(
37       std::optional<ComputeSignatureResult>* result)
38       : result_(result) {
39     QUICHE_DCHECK(!result_->has_value());
40   }
Run(bool ok,std::string signature,std::unique_ptr<ProofSource::Details> details)41   void Run(bool ok, std::string signature,
42            std::unique_ptr<ProofSource::Details> details) override {
43     result_->emplace(
44         ComputeSignatureResult{ok, std::move(signature), std::move(details)});
45   }
46 
47  private:
48   std::optional<ComputeSignatureResult>* result_;
49 };
50 
ComputeSignatureNow(ProofSource * delegate,const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const std::string & hostname,uint16_t signature_algorithm,absl::string_view in)51 ComputeSignatureResult ComputeSignatureNow(
52     ProofSource* delegate, const QuicSocketAddress& server_address,
53     const QuicSocketAddress& client_address, const std::string& hostname,
54     uint16_t signature_algorithm, absl::string_view in) {
55   std::optional<ComputeSignatureResult> result;
56   delegate->ComputeTlsSignature(
57       server_address, client_address, hostname, signature_algorithm, in,
58       std::make_unique<ResultSavingSignatureCallback>(&result));
59   QUICHE_CHECK(result.has_value())
60       << "delegate->ComputeTlsSignature must computes a "
61          "signature immediately";
62   return std::move(result.value());
63 }
64 }  // namespace
65 
FakeProofSourceHandle(ProofSource * delegate,ProofSourceHandleCallback * callback,Action select_cert_action,Action compute_signature_action,QuicDelayedSSLConfig delayed_ssl_config)66 FakeProofSourceHandle::FakeProofSourceHandle(
67     ProofSource* delegate, ProofSourceHandleCallback* callback,
68     Action select_cert_action, Action compute_signature_action,
69     QuicDelayedSSLConfig delayed_ssl_config)
70     : delegate_(delegate),
71       callback_(callback),
72       select_cert_action_(select_cert_action),
73       compute_signature_action_(compute_signature_action),
74       delayed_ssl_config_(delayed_ssl_config) {}
75 
CloseHandle()76 void FakeProofSourceHandle::CloseHandle() {
77   select_cert_op_.reset();
78   compute_signature_op_.reset();
79   closed_ = true;
80 }
81 
SelectCertificate(const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const QuicConnectionId & original_connection_id,absl::string_view ssl_capabilities,const std::string & hostname,absl::string_view client_hello,const std::string & alpn,std::optional<std::string> alps,const std::vector<uint8_t> & quic_transport_params,const std::optional<std::vector<uint8_t>> & early_data_context,const QuicSSLConfig & ssl_config)82 QuicAsyncStatus FakeProofSourceHandle::SelectCertificate(
83     const QuicSocketAddress& server_address,
84     const QuicSocketAddress& client_address,
85     const QuicConnectionId& original_connection_id,
86     absl::string_view ssl_capabilities, const std::string& hostname,
87     absl::string_view client_hello, const std::string& alpn,
88     std::optional<std::string> alps,
89     const std::vector<uint8_t>& quic_transport_params,
90     const std::optional<std::vector<uint8_t>>& early_data_context,
91     const QuicSSLConfig& ssl_config) {
92   if (select_cert_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
93     QUICHE_CHECK(!closed_);
94   }
95   all_select_cert_args_.push_back(
96       SelectCertArgs(server_address, client_address, original_connection_id,
97                      ssl_capabilities, hostname, client_hello, alpn, alps,
98                      quic_transport_params, early_data_context, ssl_config));
99 
100   if (select_cert_action_ == Action::DELEGATE_ASYNC ||
101       select_cert_action_ == Action::FAIL_ASYNC) {
102     select_cert_op_.emplace(delegate_, callback_, select_cert_action_,
103                             all_select_cert_args_.back(), delayed_ssl_config_);
104     return QUIC_PENDING;
105   } else if (select_cert_action_ == Action::FAIL_SYNC ||
106              select_cert_action_ == Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
107     callback()->OnSelectCertificateDone(
108         /*ok=*/false,
109         /*is_sync=*/true,
110         ProofSourceHandleCallback::LocalSSLConfig{nullptr, delayed_ssl_config_},
111         /*ticket_encryption_key=*/absl::string_view(),
112         /*cert_matched_sni=*/false);
113     return QUIC_FAILURE;
114   }
115 
116   QUICHE_DCHECK(select_cert_action_ == Action::DELEGATE_SYNC);
117   bool cert_matched_sni;
118   quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
119       delegate_->GetCertChain(server_address, client_address, hostname,
120                               &cert_matched_sni);
121 
122   bool ok = chain && !chain->certs.empty();
123   callback_->OnSelectCertificateDone(
124       ok, /*is_sync=*/true,
125       ProofSourceHandleCallback::LocalSSLConfig{chain.get(),
126                                                 delayed_ssl_config_},
127       /*ticket_encryption_key=*/absl::string_view(),
128       /*cert_matched_sni=*/cert_matched_sni);
129   return ok ? QUIC_SUCCESS : QUIC_FAILURE;
130 }
131 
ComputeSignature(const QuicSocketAddress & server_address,const QuicSocketAddress & client_address,const std::string & hostname,uint16_t signature_algorithm,absl::string_view in,size_t max_signature_size)132 QuicAsyncStatus FakeProofSourceHandle::ComputeSignature(
133     const QuicSocketAddress& server_address,
134     const QuicSocketAddress& client_address, const std::string& hostname,
135     uint16_t signature_algorithm, absl::string_view in,
136     size_t max_signature_size) {
137   if (compute_signature_action_ != Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
138     QUICHE_CHECK(!closed_);
139   }
140   all_compute_signature_args_.push_back(
141       ComputeSignatureArgs(server_address, client_address, hostname,
142                            signature_algorithm, in, max_signature_size));
143 
144   if (compute_signature_action_ == Action::DELEGATE_ASYNC ||
145       compute_signature_action_ == Action::FAIL_ASYNC) {
146     compute_signature_op_.emplace(delegate_, callback_,
147                                   compute_signature_action_,
148                                   all_compute_signature_args_.back());
149     return QUIC_PENDING;
150   } else if (compute_signature_action_ == Action::FAIL_SYNC ||
151              compute_signature_action_ ==
152                  Action::FAIL_SYNC_DO_NOT_CHECK_CLOSED) {
153     callback()->OnComputeSignatureDone(/*ok=*/false, /*is_sync=*/true,
154                                        /*signature=*/"", /*details=*/nullptr);
155     return QUIC_FAILURE;
156   }
157 
158   QUICHE_DCHECK(compute_signature_action_ == Action::DELEGATE_SYNC);
159   ComputeSignatureResult result =
160       ComputeSignatureNow(delegate_, server_address, client_address, hostname,
161                           signature_algorithm, in);
162   callback_->OnComputeSignatureDone(
163       result.ok, /*is_sync=*/true, result.signature, std::move(result.details));
164   return result.ok ? QUIC_SUCCESS : QUIC_FAILURE;
165 }
166 
callback()167 ProofSourceHandleCallback* FakeProofSourceHandle::callback() {
168   return callback_;
169 }
170 
HasPendingOperation() const171 bool FakeProofSourceHandle::HasPendingOperation() const {
172   int num_pending_operations = NumPendingOperations();
173   return num_pending_operations > 0;
174 }
175 
CompletePendingOperation()176 void FakeProofSourceHandle::CompletePendingOperation() {
177   QUICHE_DCHECK_LE(NumPendingOperations(), 1);
178 
179   if (select_cert_op_.has_value()) {
180     select_cert_op_->Run();
181     select_cert_op_.reset();
182   } else if (compute_signature_op_.has_value()) {
183     compute_signature_op_->Run();
184     compute_signature_op_.reset();
185   }
186 }
187 
NumPendingOperations() const188 int FakeProofSourceHandle::NumPendingOperations() const {
189   return static_cast<int>(select_cert_op_.has_value()) +
190          static_cast<int>(compute_signature_op_.has_value());
191 }
192 
SelectCertOperation(ProofSource * delegate,ProofSourceHandleCallback * callback,Action action,SelectCertArgs args,QuicDelayedSSLConfig delayed_ssl_config)193 FakeProofSourceHandle::SelectCertOperation::SelectCertOperation(
194     ProofSource* delegate, ProofSourceHandleCallback* callback, Action action,
195     SelectCertArgs args, QuicDelayedSSLConfig delayed_ssl_config)
196     : PendingOperation(delegate, callback, action),
197       args_(std::move(args)),
198       delayed_ssl_config_(delayed_ssl_config) {}
199 
Run()200 void FakeProofSourceHandle::SelectCertOperation::Run() {
201   if (action_ == Action::FAIL_ASYNC) {
202     callback_->OnSelectCertificateDone(
203         /*ok=*/false,
204         /*is_sync=*/false,
205         ProofSourceHandleCallback::LocalSSLConfig{nullptr, delayed_ssl_config_},
206         /*ticket_encryption_key=*/absl::string_view(),
207         /*cert_matched_sni=*/false);
208   } else if (action_ == Action::DELEGATE_ASYNC) {
209     bool cert_matched_sni;
210     quiche::QuicheReferenceCountedPointer<ProofSource::Chain> chain =
211         delegate_->GetCertChain(args_.server_address, args_.client_address,
212                                 args_.hostname, &cert_matched_sni);
213     bool ok = chain && !chain->certs.empty();
214     callback_->OnSelectCertificateDone(
215         ok, /*is_sync=*/false,
216         ProofSourceHandleCallback::LocalSSLConfig{chain.get(),
217                                                   delayed_ssl_config_},
218         /*ticket_encryption_key=*/absl::string_view(),
219         /*cert_matched_sni=*/cert_matched_sni);
220   } else {
221     QUIC_BUG(quic_bug_10139_1)
222         << "Unexpected action: " << static_cast<int>(action_);
223   }
224 }
225 
ComputeSignatureOperation(ProofSource * delegate,ProofSourceHandleCallback * callback,Action action,ComputeSignatureArgs args)226 FakeProofSourceHandle::ComputeSignatureOperation::ComputeSignatureOperation(
227     ProofSource* delegate, ProofSourceHandleCallback* callback, Action action,
228     ComputeSignatureArgs args)
229     : PendingOperation(delegate, callback, action), args_(std::move(args)) {}
230 
Run()231 void FakeProofSourceHandle::ComputeSignatureOperation::Run() {
232   if (action_ == Action::FAIL_ASYNC) {
233     callback_->OnComputeSignatureDone(
234         /*ok=*/false, /*is_sync=*/false,
235         /*signature=*/"", /*details=*/nullptr);
236   } else if (action_ == Action::DELEGATE_ASYNC) {
237     ComputeSignatureResult result = ComputeSignatureNow(
238         delegate_, args_.server_address, args_.client_address, args_.hostname,
239         args_.signature_algorithm, args_.in);
240     callback_->OnComputeSignatureDone(result.ok, /*is_sync=*/false,
241                                       result.signature,
242                                       std::move(result.details));
243   } else {
244     QUIC_BUG(quic_bug_10139_2)
245         << "Unexpected action: " << static_cast<int>(action_);
246   }
247 }
248 
249 }  // namespace test
250 }  // namespace quic
251