xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 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 #ifndef QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
6 #define QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
7 
8 #include <cstdarg>
9 #include <cstddef>
10 #include <cstdint>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "absl/strings/string_view.h"
16 #include "absl/types/span.h"
17 #include "openssl/evp.h"
18 #include "quiche/quic/core/crypto/crypto_framer.h"
19 #include "quiche/quic/core/crypto/quic_random.h"
20 #include "quiche/quic/core/quic_connection.h"
21 #include "quiche/quic/core/quic_framer.h"
22 #include "quiche/quic/core/quic_packets.h"
23 #include "quiche/quic/core/quic_types.h"
24 #include "quiche/quic/test_tools/quic_test_utils.h"
25 #include "quiche/common/quiche_callbacks.h"
26 
27 namespace quic {
28 
29 class ProofSource;
30 class ProofVerifier;
31 class ProofVerifyContext;
32 class QuicClock;
33 class QuicConfig;
34 class QuicCryptoClientStream;
35 class QuicCryptoServerConfig;
36 class QuicCryptoServerStreamBase;
37 class QuicCryptoStream;
38 class QuicServerId;
39 
40 namespace test {
41 
42 class PacketSaver;
43 class PacketSavingConnection;
44 
45 namespace crypto_test_utils {
46 
47 // An interface for a source of callbacks. This is used for invoking
48 // callbacks asynchronously.
49 //
50 // Call the RunPendingCallbacks method regularly to run the callbacks from
51 // this source.
52 class CallbackSource {
53  public:
~CallbackSource()54   virtual ~CallbackSource() {}
55 
56   // Runs pending callbacks from this source. If there is no pending
57   // callback, does nothing.
58   virtual void RunPendingCallbacks() = 0;
59 };
60 
61 // FakeClientOptions bundles together a number of options for configuring
62 // HandshakeWithFakeClient.
63 struct FakeClientOptions {
64   FakeClientOptions();
65   ~FakeClientOptions();
66 
67   // If only_tls_versions is set, then the client will only use TLS for the
68   // crypto handshake.
69   bool only_tls_versions = false;
70 
71   // If only_quic_crypto_versions is set, then the client will only use
72   // PROTOCOL_QUIC_CRYPTO for the crypto handshake.
73   bool only_quic_crypto_versions = false;
74 };
75 
76 // Returns a QuicCryptoServerConfig that is in a reasonable configuration to
77 // pass into HandshakeWithFakeServer.
78 std::unique_ptr<QuicCryptoServerConfig> CryptoServerConfigForTesting();
79 
80 // returns: the number of client hellos that the client sent.
81 int HandshakeWithFakeServer(QuicConfig* server_quic_config,
82                             QuicCryptoServerConfig* crypto_config,
83                             MockQuicConnectionHelper* helper,
84                             MockAlarmFactory* alarm_factory,
85                             PacketSavingConnection* client_conn,
86                             QuicCryptoClientStreamBase* client,
87                             std::string alpn);
88 
89 // returns: the number of client hellos that the client sent.
90 int HandshakeWithFakeClient(MockQuicConnectionHelper* helper,
91                             MockAlarmFactory* alarm_factory,
92                             PacketSavingConnection* server_conn,
93                             QuicCryptoServerStreamBase* server,
94                             const QuicServerId& server_id,
95                             const FakeClientOptions& options, std::string alpn);
96 
97 // SetupCryptoServerConfigForTest configures |crypto_config|
98 // with sensible defaults for testing.
99 void SetupCryptoServerConfigForTest(const QuicClock* clock, QuicRandom* rand,
100                                     QuicCryptoServerConfig* crypto_config);
101 
102 // Sends the handshake message |message| to stream |stream| with the perspective
103 // that the message is coming from |perspective|.
104 void SendHandshakeMessageToStream(QuicCryptoStream* stream,
105                                   const CryptoHandshakeMessage& message,
106                                   Perspective perspective);
107 
108 // CommunicateHandshakeMessages moves messages from `client` (or
109 // `packets_from_client`) to `server` from `server` (or `packets_from_server`)
110 // to `client` until `clients`'s handshake has completed.
111 void CommunicateHandshakeMessages(PacketSavingConnection* client_conn,
112                                   QuicCryptoStream* client,
113                                   PacketSavingConnection* server_conn,
114                                   QuicCryptoStream* server);
115 void CommunicateHandshakeMessages(QuicConnection& client_conn,
116                                   QuicCryptoStream& client,
117                                   QuicConnection& server_conn,
118                                   QuicCryptoStream& server,
119                                   PacketProvider& packets_from_client,
120                                   PacketProvider& packets_from_server);
121 
122 // CommunicateHandshakeMessagesUntil:
123 // 1) Moves messages from `client` (or `packets_from_client`) to `server` until
124 //    `server_condition` is met.
125 // 2) Moves messages from `server` (or `packets_from_server`) to `client` until
126 //    `client_condition` is met.
127 // 3)  For IETF QUIC, if `process_stream_data` is true, STREAM_FRAME within the
128 // packet containing crypto messages is also processed.
129 // 4) Returns true if both conditions are met.
130 // 5) Returns false if either connection is closed or there is no more packet to
131 // deliver before both conditions are met.
132 // TODO(ericorth): If the callers are eventually converted and these overloads
133 // are merged, consider also converting `process_stream_data` to an enum.
134 bool CommunicateHandshakeMessagesUntil(
135     PacketSavingConnection* client_conn, QuicCryptoStream* client,
136     quiche::UnretainedCallback<bool()> client_condition,
137     PacketSavingConnection* server_conn, QuicCryptoStream* server,
138     quiche::UnretainedCallback<bool()> server_condition,
139     bool process_stream_data);
140 bool CommunicateHandshakeMessagesUntil(
141     QuicConnection& client_conn, QuicCryptoStream& client,
142     quiche::UnretainedCallback<bool()> client_condition,
143     QuicConnection& server_conn, QuicCryptoStream& server,
144     quiche::UnretainedCallback<bool()> server_condition,
145     bool process_stream_data, PacketProvider& packets_from_client,
146     PacketProvider& packets_from_server);
147 
148 // AdvanceHandshake attempts to move all current messages:
149 // * Starting at `client_i`, from `client` to `server`
150 // * Starting at `server_i`, from `server` to `client`
151 //
152 // Returns the total number of messages attempted to be moved so far from each
153 // of `client` and `server` (number moved in this call plus `client_i` or
154 // `server_i`).
155 std::pair<size_t, size_t> AdvanceHandshake(PacketSavingConnection* client_conn,
156                                            QuicCryptoStream* client,
157                                            size_t client_i,
158                                            PacketSavingConnection* server_conn,
159                                            QuicCryptoStream* server,
160                                            size_t server_i);
161 
162 // AdvanceHandshake attempts to move all messages from `packets_from_client` to
163 // `server` and from `packets_from_server` to `client`.
164 void AdvanceHandshake(
165     absl::Span<const QuicEncryptedPacket* const> packets_from_client,
166     QuicConnection& client_conn, QuicCryptoStream& client,
167     absl::Span<const QuicEncryptedPacket* const> packets_from_server,
168     QuicConnection& server_conn, QuicCryptoStream& server);
169 
170 // Returns the value for the tag |tag| in the tag value map of |message|.
171 std::string GetValueForTag(const CryptoHandshakeMessage& message, QuicTag tag);
172 
173 // Returns a new |ProofSource| that serves up test certificates.
174 std::unique_ptr<ProofSource> ProofSourceForTesting();
175 
176 // Returns a new |ProofVerifier| that uses the QUIC testing root CA.
177 std::unique_ptr<ProofVerifier> ProofVerifierForTesting();
178 
179 // Returns the hostname used by the proof source and the proof verifier above.
180 std::string CertificateHostnameForTesting();
181 
182 // Returns a hash of the leaf test certificate.
183 uint64_t LeafCertHashForTesting();
184 
185 // Returns a |ProofVerifyContext| that must be used with the verifier
186 // returned by |ProofVerifierForTesting|.
187 std::unique_ptr<ProofVerifyContext> ProofVerifyContextForTesting();
188 
189 // Creates a minimal dummy reject message that will pass the client-config
190 // validation tests. This will include a server config, but no certs, proof
191 // source address token, or server nonce.
192 void FillInDummyReject(CryptoHandshakeMessage* rej);
193 
194 // ParseTag returns a QuicTag from parsing |tagstr|. |tagstr| may either be
195 // in the format "EXMP" (i.e. ASCII format), or "#11223344" (an explicit hex
196 // format). It QUICHE_CHECK fails if there's a parse error.
197 QuicTag ParseTag(const char* tagstr);
198 
199 // Message constructs a CHLO message from a provided vector of tag/value pairs.
200 // The first of each pair is the tag of a tag/value and is given as an argument
201 // to |ParseTag|. The second is the value of the tag/value pair and is either a
202 // hex dump, preceeded by a '#', or a raw value. If minimum_size_bytes is
203 // provided then the message will be padded to this minimum size.
204 //
205 //   CreateCHLO(
206 //       {{"NOCE", "#11223344"},
207 //        {"SNI", "www.example.com"}},
208 //       optional_minimum_size_bytes);
209 CryptoHandshakeMessage CreateCHLO(
210     std::vector<std::pair<std::string, std::string>> tags_and_values);
211 CryptoHandshakeMessage CreateCHLO(
212     std::vector<std::pair<std::string, std::string>> tags_and_values,
213     int minimum_size_bytes);
214 
215 // Return an inchoate CHLO with some basic tag value pairs.
216 CryptoHandshakeMessage GenerateDefaultInchoateCHLO(
217     const QuicClock* clock, QuicTransportVersion version,
218     QuicCryptoServerConfig* crypto_config);
219 
220 // Takes a inchoate CHLO, returns a full CHLO in |out| which can pass
221 // |crypto_config|'s validation.
222 void GenerateFullCHLO(
223     const CryptoHandshakeMessage& inchoate_chlo,
224     QuicCryptoServerConfig* crypto_config, QuicSocketAddress server_addr,
225     QuicSocketAddress client_addr, QuicTransportVersion transport_version,
226     const QuicClock* clock,
227     quiche::QuicheReferenceCountedPointer<QuicSignedServerConfig> signed_config,
228     QuicCompressedCertsCache* compressed_certs_cache,
229     CryptoHandshakeMessage* out);
230 
231 void CompareClientAndServerKeys(QuicCryptoClientStreamBase* client,
232                                 QuicCryptoServerStreamBase* server);
233 
234 // Return a CHLO nonce in hexadecimal.
235 std::string GenerateClientNonceHex(const QuicClock* clock,
236                                    QuicCryptoServerConfig* crypto_config);
237 
238 // Return a CHLO PUBS in hexadecimal.
239 std::string GenerateClientPublicValuesHex();
240 
241 }  // namespace crypto_test_utils
242 
243 }  // namespace test
244 
245 }  // namespace quic
246 
247 #endif  // QUICHE_QUIC_TEST_TOOLS_CRYPTO_TEST_UTILS_H_
248