|  | // Copyright (c) 2021 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_ | 
|  | #define QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_ | 
|  |  | 
|  | #include "quic/core/crypto/proof_source.h" | 
|  |  | 
|  | namespace quic { | 
|  | namespace test { | 
|  |  | 
|  | // FakeProofSourceHandle allows its behavior to be scripted for testing. | 
|  | class FakeProofSourceHandle : public ProofSourceHandle { | 
|  | public: | 
|  | // What would an operation return when it is called. | 
|  | enum class Action { | 
|  | // Delegate the operation to |delegate_| immediately. | 
|  | DELEGATE_SYNC = 0, | 
|  | // Handle the operation asynchronously. Delegate the operation to | 
|  | // |delegate_| when the caller calls CompletePendingOperation(). | 
|  | DELEGATE_ASYNC, | 
|  | // Fail the operation immediately. | 
|  | FAIL_SYNC, | 
|  | // Handle the operation asynchronously. Fail the operation when the caller | 
|  | // calls CompletePendingOperation(). | 
|  | FAIL_ASYNC, | 
|  | // Similar to FAIL_SYNC, but do not QUICHE_CHECK(!closed_) when invoked. | 
|  | FAIL_SYNC_DO_NOT_CHECK_CLOSED, | 
|  | }; | 
|  |  | 
|  | // |delegate| must do cert selection and signature synchronously. | 
|  | // |dealyed_ssl_config| is the config passed to OnSelectCertificateDone. | 
|  | FakeProofSourceHandle( | 
|  | ProofSource* delegate, ProofSourceHandleCallback* callback, | 
|  | Action select_cert_action, Action compute_signature_action, | 
|  | QuicDelayedSSLConfig dealyed_ssl_config = QuicDelayedSSLConfig()); | 
|  |  | 
|  | ~FakeProofSourceHandle() override = default; | 
|  |  | 
|  | void CloseHandle() override; | 
|  |  | 
|  | QuicAsyncStatus SelectCertificate( | 
|  | const QuicSocketAddress& server_address, | 
|  | const QuicSocketAddress& client_address, | 
|  | absl::string_view ssl_capabilities, | 
|  | const std::string& hostname, | 
|  | absl::string_view client_hello, | 
|  | const std::string& alpn, | 
|  | absl::optional<std::string> alps, | 
|  | const std::vector<uint8_t>& quic_transport_params, | 
|  | const absl::optional<std::vector<uint8_t>>& early_data_context, | 
|  | const QuicSSLConfig& ssl_config) override; | 
|  |  | 
|  | QuicAsyncStatus 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) override; | 
|  |  | 
|  | ProofSourceHandleCallback* callback() override; | 
|  |  | 
|  | // Whether there's a pending operation in |this|. | 
|  | bool HasPendingOperation() const; | 
|  | void CompletePendingOperation(); | 
|  |  | 
|  | struct SelectCertArgs { | 
|  | SelectCertArgs(QuicSocketAddress server_address, | 
|  | QuicSocketAddress client_address, | 
|  | absl::string_view ssl_capabilities, | 
|  | std::string hostname, | 
|  | absl::string_view client_hello, | 
|  | std::string alpn, | 
|  | absl::optional<std::string> alps, | 
|  | std::vector<uint8_t> quic_transport_params, | 
|  | absl::optional<std::vector<uint8_t>> early_data_context, | 
|  | QuicSSLConfig ssl_config) | 
|  | : server_address(server_address), | 
|  | client_address(client_address), | 
|  | ssl_capabilities(ssl_capabilities), | 
|  | hostname(hostname), | 
|  | client_hello(client_hello), | 
|  | alpn(alpn), | 
|  | alps(alps), | 
|  | quic_transport_params(quic_transport_params), | 
|  | early_data_context(early_data_context), | 
|  | ssl_config(ssl_config) {} | 
|  |  | 
|  | QuicSocketAddress server_address; | 
|  | QuicSocketAddress client_address; | 
|  | std::string ssl_capabilities; | 
|  | std::string hostname; | 
|  | std::string client_hello; | 
|  | std::string alpn; | 
|  | absl::optional<std::string> alps; | 
|  | std::vector<uint8_t> quic_transport_params; | 
|  | absl::optional<std::vector<uint8_t>> early_data_context; | 
|  | QuicSSLConfig ssl_config; | 
|  | }; | 
|  |  | 
|  | struct ComputeSignatureArgs { | 
|  | ComputeSignatureArgs(QuicSocketAddress server_address, | 
|  | QuicSocketAddress client_address, | 
|  | std::string hostname, | 
|  | uint16_t signature_algorithm, | 
|  | absl::string_view in, | 
|  | size_t max_signature_size) | 
|  | : server_address(server_address), | 
|  | client_address(client_address), | 
|  | hostname(hostname), | 
|  | signature_algorithm(signature_algorithm), | 
|  | in(in), | 
|  | max_signature_size(max_signature_size) {} | 
|  |  | 
|  | QuicSocketAddress server_address; | 
|  | QuicSocketAddress client_address; | 
|  | std::string hostname; | 
|  | uint16_t signature_algorithm; | 
|  | std::string in; | 
|  | size_t max_signature_size; | 
|  | }; | 
|  |  | 
|  | std::vector<SelectCertArgs> all_select_cert_args() const { | 
|  | return all_select_cert_args_; | 
|  | } | 
|  |  | 
|  | std::vector<ComputeSignatureArgs> all_compute_signature_args() const { | 
|  | return all_compute_signature_args_; | 
|  | } | 
|  |  | 
|  | private: | 
|  | class PendingOperation { | 
|  | public: | 
|  | PendingOperation(ProofSource* delegate, | 
|  | ProofSourceHandleCallback* callback, | 
|  | Action action) | 
|  | : delegate_(delegate), callback_(callback), action_(action) {} | 
|  | virtual ~PendingOperation() = default; | 
|  | virtual void Run() = 0; | 
|  |  | 
|  | protected: | 
|  | ProofSource* delegate_; | 
|  | ProofSourceHandleCallback* callback_; | 
|  | Action action_; | 
|  | }; | 
|  |  | 
|  | class SelectCertOperation : public PendingOperation { | 
|  | public: | 
|  | SelectCertOperation(ProofSource* delegate, | 
|  | ProofSourceHandleCallback* callback, Action action, | 
|  | SelectCertArgs args, | 
|  | QuicDelayedSSLConfig dealyed_ssl_config); | 
|  |  | 
|  | ~SelectCertOperation() override = default; | 
|  |  | 
|  | void Run() override; | 
|  |  | 
|  | private: | 
|  | const SelectCertArgs args_; | 
|  | const QuicDelayedSSLConfig dealyed_ssl_config_; | 
|  | }; | 
|  |  | 
|  | class ComputeSignatureOperation : public PendingOperation { | 
|  | public: | 
|  | ComputeSignatureOperation(ProofSource* delegate, | 
|  | ProofSourceHandleCallback* callback, | 
|  | Action action, | 
|  | ComputeSignatureArgs args); | 
|  |  | 
|  | ~ComputeSignatureOperation() override = default; | 
|  |  | 
|  | void Run() override; | 
|  |  | 
|  | private: | 
|  | const ComputeSignatureArgs args_; | 
|  | }; | 
|  |  | 
|  | private: | 
|  | int NumPendingOperations() const; | 
|  |  | 
|  | bool closed_ = false; | 
|  | ProofSource* delegate_; | 
|  | ProofSourceHandleCallback* callback_; | 
|  | // Action for the next select cert operation. | 
|  | Action select_cert_action_ = Action::DELEGATE_SYNC; | 
|  | // Action for the next compute signature operation. | 
|  | Action compute_signature_action_ = Action::DELEGATE_SYNC; | 
|  | const QuicDelayedSSLConfig dealyed_ssl_config_; | 
|  | absl::optional<SelectCertOperation> select_cert_op_; | 
|  | absl::optional<ComputeSignatureOperation> compute_signature_op_; | 
|  |  | 
|  | // Save all the select cert and compute signature args for tests to inspect. | 
|  | std::vector<SelectCertArgs> all_select_cert_args_; | 
|  | std::vector<ComputeSignatureArgs> all_compute_signature_args_; | 
|  | }; | 
|  |  | 
|  | }  // namespace test | 
|  | }  // namespace quic | 
|  |  | 
|  | #endif  // QUICHE_QUIC_TEST_TOOLS_FAKE_PROOF_SOURCE_HANDLE_H_ |