OLD | NEW |
| (Empty) |
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 NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_ | |
6 #define NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_ | |
7 | |
8 #include <cstdint> | |
9 #include <memory> | |
10 #include <string> | |
11 | |
12 #include "base/macros.h" | |
13 #include "net/quic/crypto/channel_id.h" | |
14 #include "net/quic/crypto/proof_verifier.h" | |
15 #include "net/quic/crypto/quic_crypto_client_config.h" | |
16 #include "net/quic/quic_config.h" | |
17 #include "net/quic/quic_crypto_stream.h" | |
18 #include "net/quic/quic_server_id.h" | |
19 | |
20 namespace net { | |
21 | |
22 namespace test { | |
23 class CryptoTestUtils; | |
24 class QuicChromiumClientSessionPeer; | |
25 } // namespace test | |
26 | |
27 class NET_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream { | |
28 public: | |
29 explicit QuicCryptoClientStreamBase(QuicSession* session); | |
30 | |
31 ~QuicCryptoClientStreamBase() override{}; | |
32 | |
33 // Performs a crypto handshake with the server. | |
34 virtual void CryptoConnect() = 0; | |
35 | |
36 // num_sent_client_hellos returns the number of client hello messages that | |
37 // have been sent. If the handshake has completed then this is one greater | |
38 // than the number of round-trips needed for the handshake. | |
39 virtual int num_sent_client_hellos() const = 0; | |
40 | |
41 // The number of server config update messages received by the | |
42 // client. Does not count update messages that were received prior | |
43 // to handshake confirmation. | |
44 virtual int num_scup_messages_received() const = 0; | |
45 }; | |
46 | |
47 class NET_EXPORT_PRIVATE QuicCryptoClientStream | |
48 : public QuicCryptoClientStreamBase { | |
49 public: | |
50 // kMaxClientHellos is the maximum number of times that we'll send a client | |
51 // hello. The value 3 accounts for: | |
52 // * One failure due to an incorrect or missing source-address token. | |
53 // * One failure due the server's certificate chain being unavailible and | |
54 // the server being unwilling to send it without a valid source-address | |
55 // token. | |
56 static const int kMaxClientHellos = 3; | |
57 | |
58 // ProofHandler is an interface that handles callbacks from the crypto | |
59 // stream when the client has proof verification details of the server. | |
60 class NET_EXPORT_PRIVATE ProofHandler { | |
61 public: | |
62 virtual ~ProofHandler() {} | |
63 | |
64 // Called when the proof in |cached| is marked valid. If this is a secure | |
65 // QUIC session, then this will happen only after the proof verifier | |
66 // completes. | |
67 virtual void OnProofValid( | |
68 const QuicCryptoClientConfig::CachedState& cached) = 0; | |
69 | |
70 // Called when proof verification details become available, either because | |
71 // proof verification is complete, or when cached details are used. This | |
72 // will only be called for secure QUIC connections. | |
73 virtual void OnProofVerifyDetailsAvailable( | |
74 const ProofVerifyDetails& verify_details) = 0; | |
75 }; | |
76 | |
77 QuicCryptoClientStream(const QuicServerId& server_id, | |
78 QuicSession* session, | |
79 ProofVerifyContext* verify_context, | |
80 QuicCryptoClientConfig* crypto_config, | |
81 ProofHandler* proof_handler); | |
82 | |
83 ~QuicCryptoClientStream() override; | |
84 | |
85 // From QuicCryptoClientStreamBase | |
86 void CryptoConnect() override; | |
87 int num_sent_client_hellos() const override; | |
88 | |
89 int num_scup_messages_received() const override; | |
90 | |
91 // CryptoFramerVisitorInterface implementation | |
92 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override; | |
93 | |
94 // Returns true if a channel ID was sent on this connection. | |
95 bool WasChannelIDSent() const; | |
96 | |
97 // Returns true if our ChannelIDSourceCallback was run, which implies the | |
98 // ChannelIDSource operated asynchronously. Intended for testing. | |
99 bool WasChannelIDSourceCallbackRun() const; | |
100 | |
101 private: | |
102 // ChannelIDSourceCallbackImpl is passed as the callback method to | |
103 // GetChannelIDKey. The ChannelIDSource calls this class with the result of | |
104 // channel ID lookup when lookup is performed asynchronously. | |
105 class ChannelIDSourceCallbackImpl : public ChannelIDSourceCallback { | |
106 public: | |
107 explicit ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream); | |
108 ~ChannelIDSourceCallbackImpl() override; | |
109 | |
110 // ChannelIDSourceCallback interface. | |
111 void Run(std::unique_ptr<ChannelIDKey>* channel_id_key) override; | |
112 | |
113 // Cancel causes any future callbacks to be ignored. It must be called on | |
114 // the same thread as the callback will be made on. | |
115 void Cancel(); | |
116 | |
117 private: | |
118 QuicCryptoClientStream* stream_; | |
119 }; | |
120 | |
121 // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof. | |
122 // The ProofVerifier calls this class with the result of proof verification | |
123 // when verification is performed asynchronously. | |
124 class ProofVerifierCallbackImpl : public ProofVerifierCallback { | |
125 public: | |
126 explicit ProofVerifierCallbackImpl(QuicCryptoClientStream* stream); | |
127 ~ProofVerifierCallbackImpl() override; | |
128 | |
129 // ProofVerifierCallback interface. | |
130 void Run(bool ok, | |
131 const std::string& error_details, | |
132 std::unique_ptr<ProofVerifyDetails>* details) override; | |
133 | |
134 // Cancel causes any future callbacks to be ignored. It must be called on | |
135 // the same thread as the callback will be made on. | |
136 void Cancel(); | |
137 | |
138 private: | |
139 QuicCryptoClientStream* stream_; | |
140 }; | |
141 | |
142 friend class test::CryptoTestUtils; | |
143 friend class test::QuicChromiumClientSessionPeer; | |
144 | |
145 enum State { | |
146 STATE_IDLE, | |
147 STATE_INITIALIZE, | |
148 STATE_SEND_CHLO, | |
149 STATE_RECV_REJ, | |
150 STATE_VERIFY_PROOF, | |
151 STATE_VERIFY_PROOF_COMPLETE, | |
152 STATE_GET_CHANNEL_ID, | |
153 STATE_GET_CHANNEL_ID_COMPLETE, | |
154 STATE_RECV_SHLO, | |
155 STATE_INITIALIZE_SCUP, | |
156 STATE_NONE, | |
157 }; | |
158 | |
159 // Handles new server config and optional source-address token provided by the | |
160 // server during a connection. | |
161 void HandleServerConfigUpdateMessage( | |
162 const CryptoHandshakeMessage& server_config_update); | |
163 | |
164 // DoHandshakeLoop performs a step of the handshake state machine. Note that | |
165 // |in| may be nullptr if the call did not result from a received message. | |
166 void DoHandshakeLoop(const CryptoHandshakeMessage* in); | |
167 | |
168 // Start the handshake process. | |
169 void DoInitialize(QuicCryptoClientConfig::CachedState* cached); | |
170 | |
171 // Send either InchoateClientHello or ClientHello message to the server. | |
172 void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached); | |
173 | |
174 // Process REJ message from the server. | |
175 void DoReceiveREJ(const CryptoHandshakeMessage* in, | |
176 QuicCryptoClientConfig::CachedState* cached); | |
177 | |
178 // Start the proof verification process. Returns the QuicAsyncStatus returned | |
179 // by the ProofVerifier's VerifyProof. | |
180 QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached); | |
181 | |
182 // If proof is valid then it sets the proof as valid (which persists the | |
183 // server config). If not, it closes the connection. | |
184 void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached); | |
185 | |
186 // Start the look up of Channel ID process. Returns either QUIC_SUCCESS if | |
187 // RequiresChannelID returns false or QuicAsyncStatus returned by | |
188 // GetChannelIDKey. | |
189 QuicAsyncStatus DoGetChannelID(QuicCryptoClientConfig::CachedState* cached); | |
190 | |
191 // If there is no channel ID, then close the connection otherwise transtion to | |
192 // STATE_SEND_CHLO state. | |
193 void DoGetChannelIDComplete(); | |
194 | |
195 // Process SHLO message from the server. | |
196 void DoReceiveSHLO(const CryptoHandshakeMessage* in, | |
197 QuicCryptoClientConfig::CachedState* cached); | |
198 | |
199 // Start the proof verification if |server_id_| is https and |cached| has | |
200 // signature. | |
201 void DoInitializeServerConfigUpdate( | |
202 QuicCryptoClientConfig::CachedState* cached); | |
203 | |
204 // Called to set the proof of |cached| valid. Also invokes the session's | |
205 // OnProofValid() method. | |
206 void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached); | |
207 | |
208 // Returns true if the server crypto config in |cached| requires a ChannelID | |
209 // and the client config settings also allow sending a ChannelID. | |
210 bool RequiresChannelID(QuicCryptoClientConfig::CachedState* cached); | |
211 | |
212 State next_state_; | |
213 // num_client_hellos_ contains the number of client hello messages that this | |
214 // connection has sent. | |
215 int num_client_hellos_; | |
216 | |
217 QuicCryptoClientConfig* const crypto_config_; | |
218 | |
219 // SHA-256 hash of the most recently sent CHLO. | |
220 std::string chlo_hash_; | |
221 | |
222 // Server's (hostname, port, is_https, privacy_mode) tuple. | |
223 const QuicServerId server_id_; | |
224 | |
225 // Generation counter from QuicCryptoClientConfig's CachedState. | |
226 uint64_t generation_counter_; | |
227 | |
228 // True if a channel ID was sent. | |
229 bool channel_id_sent_; | |
230 | |
231 // True if channel_id_source_callback_ was run. | |
232 bool channel_id_source_callback_run_; | |
233 | |
234 // channel_id_source_callback_ contains the callback object that we passed | |
235 // to an asynchronous channel ID lookup. The ChannelIDSource owns this | |
236 // object. | |
237 ChannelIDSourceCallbackImpl* channel_id_source_callback_; | |
238 | |
239 // These members are used to store the result of an asynchronous channel ID | |
240 // lookup. These members must not be used after | |
241 // STATE_GET_CHANNEL_ID_COMPLETE. | |
242 std::unique_ptr<ChannelIDKey> channel_id_key_; | |
243 | |
244 // verify_context_ contains the context object that we pass to asynchronous | |
245 // proof verifications. | |
246 std::unique_ptr<ProofVerifyContext> verify_context_; | |
247 | |
248 // proof_verify_callback_ contains the callback object that we passed to an | |
249 // asynchronous proof verification. The ProofVerifier owns this object. | |
250 ProofVerifierCallbackImpl* proof_verify_callback_; | |
251 // proof_handler_ contains the callback object used by a quic client | |
252 // for proof verification. It is not owned by this class. | |
253 ProofHandler* proof_handler_; | |
254 | |
255 // These members are used to store the result of an asynchronous proof | |
256 // verification. These members must not be used after | |
257 // STATE_VERIFY_PROOF_COMPLETE. | |
258 bool verify_ok_; | |
259 std::string verify_error_details_; | |
260 std::unique_ptr<ProofVerifyDetails> verify_details_; | |
261 | |
262 // True if the server responded to a previous CHLO with a stateless | |
263 // reject. Used for book-keeping between the STATE_RECV_REJ, | |
264 // STATE_VERIFY_PROOF*, and subsequent STATE_SEND_CHLO state. | |
265 bool stateless_reject_received_; | |
266 | |
267 base::TimeTicks proof_verify_start_time_; | |
268 | |
269 int num_scup_messages_received_; | |
270 | |
271 DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream); | |
272 }; | |
273 | |
274 } // namespace net | |
275 | |
276 #endif // NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_ | |
OLD | NEW |