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