OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_crypto_client_stream.h" | 5 #include "net/quic/quic_crypto_client_stream.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "net/base/completion_callback.h" | 8 #include "net/base/completion_callback.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/quic/crypto/crypto_protocol.h" | 10 #include "net/quic/crypto/crypto_protocol.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 | 59 |
60 // The ProofVerifier owns this object and will delete it when this method | 60 // The ProofVerifier owns this object and will delete it when this method |
61 // returns. | 61 // returns. |
62 } | 62 } |
63 | 63 |
64 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { | 64 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { |
65 stream_ = NULL; | 65 stream_ = NULL; |
66 } | 66 } |
67 | 67 |
68 QuicCryptoClientStream::QuicCryptoClientStream( | 68 QuicCryptoClientStream::QuicCryptoClientStream( |
69 const string& server_hostname, | 69 const QuicSessionKey& server_key, |
70 QuicSession* session, | 70 QuicSession* session, |
71 QuicCryptoClientConfig* crypto_config) | 71 QuicCryptoClientConfig* crypto_config) |
72 : QuicCryptoStream(session), | 72 : QuicCryptoStream(session), |
73 next_state_(STATE_IDLE), | 73 next_state_(STATE_IDLE), |
74 num_client_hellos_(0), | 74 num_client_hellos_(0), |
75 crypto_config_(crypto_config), | 75 crypto_config_(crypto_config), |
76 server_hostname_(server_hostname), | 76 server_key_(server_key), |
77 generation_counter_(0), | 77 generation_counter_(0), |
78 proof_verify_callback_(NULL), | 78 proof_verify_callback_(NULL), |
79 disk_cache_load_result_(ERR_UNEXPECTED), | 79 disk_cache_load_result_(ERR_UNEXPECTED), |
80 weak_factory_(this) { | 80 weak_factory_(this) { |
81 } | 81 } |
82 | 82 |
83 QuicCryptoClientStream::~QuicCryptoClientStream() { | 83 QuicCryptoClientStream::~QuicCryptoClientStream() { |
84 if (proof_verify_callback_) { | 84 if (proof_verify_callback_) { |
85 proof_verify_callback_->Cancel(); | 85 proof_verify_callback_->Cancel(); |
86 } | 86 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 // * One failure due the server's certificate chain being unavailible and the | 145 // * One failure due the server's certificate chain being unavailible and the |
146 // server being unwilling to send it without a valid source-address token. | 146 // server being unwilling to send it without a valid source-address token. |
147 static const int kMaxClientHellos = 3; | 147 static const int kMaxClientHellos = 3; |
148 | 148 |
149 void QuicCryptoClientStream::DoHandshakeLoop( | 149 void QuicCryptoClientStream::DoHandshakeLoop( |
150 const CryptoHandshakeMessage* in) { | 150 const CryptoHandshakeMessage* in) { |
151 CryptoHandshakeMessage out; | 151 CryptoHandshakeMessage out; |
152 QuicErrorCode error; | 152 QuicErrorCode error; |
153 string error_details; | 153 string error_details; |
154 QuicCryptoClientConfig::CachedState* cached = | 154 QuicCryptoClientConfig::CachedState* cached = |
155 crypto_config_->LookupOrCreate(server_hostname_); | 155 crypto_config_->LookupOrCreate(server_key_); |
156 | 156 |
157 if (in != NULL) { | 157 if (in != NULL) { |
158 DVLOG(1) << "Client: Received " << in->DebugString(); | 158 DVLOG(1) << "Client: Received " << in->DebugString(); |
159 } | 159 } |
160 | 160 |
161 for (;;) { | 161 for (;;) { |
162 const State state = next_state_; | 162 const State state = next_state_; |
163 next_state_ = STATE_IDLE; | 163 next_state_ = STATE_IDLE; |
164 switch (state) { | 164 switch (state) { |
165 case STATE_LOAD_QUIC_SERVER_INFO: { | 165 case STATE_LOAD_QUIC_SERVER_INFO: { |
(...skipping 10 matching lines...) Expand all Loading... |
176 // Send the client hello in plaintext. | 176 // Send the client hello in plaintext. |
177 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 177 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
178 if (num_client_hellos_ > kMaxClientHellos) { | 178 if (num_client_hellos_ > kMaxClientHellos) { |
179 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 179 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
180 return; | 180 return; |
181 } | 181 } |
182 num_client_hellos_++; | 182 num_client_hellos_++; |
183 | 183 |
184 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 184 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
185 crypto_config_->FillInchoateClientHello( | 185 crypto_config_->FillInchoateClientHello( |
186 server_hostname_, | 186 server_key_.host(), |
187 session()->connection()->supported_versions().front(), | 187 session()->connection()->supported_versions().front(), |
188 cached, &crypto_negotiated_params_, &out); | 188 cached, &crypto_negotiated_params_, &out); |
189 // Pad the inchoate client hello to fill up a packet. | 189 // Pad the inchoate client hello to fill up a packet. |
190 const size_t kFramingOverhead = 50; // A rough estimate. | 190 const size_t kFramingOverhead = 50; // A rough estimate. |
191 const size_t max_packet_size = | 191 const size_t max_packet_size = |
192 session()->connection()->options()->max_packet_length; | 192 session()->connection()->options()->max_packet_length; |
193 if (max_packet_size <= kFramingOverhead) { | 193 if (max_packet_size <= kFramingOverhead) { |
194 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 194 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
195 << ") has no room for framing overhead."; | 195 << ") has no room for framing overhead."; |
196 CloseConnection(QUIC_INTERNAL_ERROR); | 196 CloseConnection(QUIC_INTERNAL_ERROR); |
197 return; | 197 return; |
198 } | 198 } |
199 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { | 199 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { |
200 DLOG(DFATAL) << "Client hello won't fit in a single packet."; | 200 DLOG(DFATAL) << "Client hello won't fit in a single packet."; |
201 CloseConnection(QUIC_INTERNAL_ERROR); | 201 CloseConnection(QUIC_INTERNAL_ERROR); |
202 return; | 202 return; |
203 } | 203 } |
204 out.set_minimum_size(max_packet_size - kFramingOverhead); | 204 out.set_minimum_size(max_packet_size - kFramingOverhead); |
205 next_state_ = STATE_RECV_REJ; | 205 next_state_ = STATE_RECV_REJ; |
206 DVLOG(1) << "Client: Sending " << out.DebugString(); | 206 DVLOG(1) << "Client: Sending " << out.DebugString(); |
207 SendHandshakeMessage(out); | 207 SendHandshakeMessage(out); |
208 return; | 208 return; |
209 } | 209 } |
210 session()->config()->ToHandshakeMessage(&out); | 210 session()->config()->ToHandshakeMessage(&out); |
211 error = crypto_config_->FillClientHello( | 211 error = crypto_config_->FillClientHello( |
212 server_hostname_, | 212 server_key_.host(), |
213 session()->connection()->connection_id(), | 213 session()->connection()->connection_id(), |
214 session()->connection()->supported_versions().front(), | 214 session()->connection()->supported_versions().front(), |
215 cached, | 215 cached, |
216 session()->connection()->clock()->WallNow(), | 216 session()->connection()->clock()->WallNow(), |
217 session()->connection()->random_generator(), | 217 session()->connection()->random_generator(), |
218 &crypto_negotiated_params_, | 218 &crypto_negotiated_params_, |
219 &out, | 219 &out, |
220 &error_details); | 220 &error_details); |
221 if (error != QUIC_NO_ERROR) { | 221 if (error != QUIC_NO_ERROR) { |
222 // Flush the cached config so that, if it's bad, the server has a | 222 // Flush the cached config so that, if it's bad, the server has a |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 DCHECK(verifier); | 290 DCHECK(verifier); |
291 next_state_ = STATE_VERIFY_PROOF_COMPLETE; | 291 next_state_ = STATE_VERIFY_PROOF_COMPLETE; |
292 generation_counter_ = cached->generation_counter(); | 292 generation_counter_ = cached->generation_counter(); |
293 | 293 |
294 ProofVerifierCallbackImpl* proof_verify_callback = | 294 ProofVerifierCallbackImpl* proof_verify_callback = |
295 new ProofVerifierCallbackImpl(this); | 295 new ProofVerifierCallbackImpl(this); |
296 | 296 |
297 verify_ok_ = false; | 297 verify_ok_ = false; |
298 | 298 |
299 ProofVerifier::Status status = verifier->VerifyProof( | 299 ProofVerifier::Status status = verifier->VerifyProof( |
300 server_hostname_, | 300 server_key_.host(), |
301 cached->server_config(), | 301 cached->server_config(), |
302 cached->certs(), | 302 cached->certs(), |
303 cached->signature(), | 303 cached->signature(), |
304 &verify_error_details_, | 304 &verify_error_details_, |
305 &verify_details_, | 305 &verify_details_, |
306 proof_verify_callback); | 306 proof_verify_callback); |
307 | 307 |
308 switch (status) { | 308 switch (status) { |
309 case ProofVerifier::PENDING: | 309 case ProofVerifier::PENDING: |
310 proof_verify_callback_ = proof_verify_callback; | 310 proof_verify_callback_ = proof_verify_callback; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 | 510 |
511 state->server_config = cached.server_config(); | 511 state->server_config = cached.server_config(); |
512 state->source_address_token = cached.source_address_token(); | 512 state->source_address_token = cached.source_address_token(); |
513 state->server_config_sig = cached.signature(); | 513 state->server_config_sig = cached.signature(); |
514 state->certs = cached.certs(); | 514 state->certs = cached.certs(); |
515 | 515 |
516 quic_server_info_->Persist(); | 516 quic_server_info_->Persist(); |
517 } | 517 } |
518 | 518 |
519 } // namespace net | 519 } // namespace net |
OLD | NEW |