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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 | 68 |
69 QuicCryptoClientStream::QuicCryptoClientStream( | 69 QuicCryptoClientStream::QuicCryptoClientStream( |
70 const string& server_hostname, | 70 const QuicSessionKey& session_key, |
wtc
2014/03/13 22:22:03
Nit: this parameter probably should be named |serv
ramant (doing other things)
2014/03/13 23:46:36
Done.
| |
71 QuicSession* session, | 71 QuicSession* session, |
72 QuicCryptoClientConfig* crypto_config) | 72 QuicCryptoClientConfig* crypto_config) |
73 : QuicCryptoStream(session), | 73 : QuicCryptoStream(session), |
74 next_state_(STATE_IDLE), | 74 next_state_(STATE_IDLE), |
75 num_client_hellos_(0), | 75 num_client_hellos_(0), |
76 crypto_config_(crypto_config), | 76 crypto_config_(crypto_config), |
77 server_hostname_(server_hostname), | 77 session_key_(session_key), |
78 generation_counter_(0), | 78 generation_counter_(0), |
79 proof_verify_callback_(NULL), | 79 proof_verify_callback_(NULL), |
80 disk_cache_load_result_(ERR_UNEXPECTED), | 80 disk_cache_load_result_(ERR_UNEXPECTED), |
81 weak_factory_(this) { | 81 weak_factory_(this) { |
82 } | 82 } |
83 | 83 |
84 QuicCryptoClientStream::~QuicCryptoClientStream() { | 84 QuicCryptoClientStream::~QuicCryptoClientStream() { |
85 if (proof_verify_callback_) { | 85 if (proof_verify_callback_) { |
86 proof_verify_callback_->Cancel(); | 86 proof_verify_callback_->Cancel(); |
87 } | 87 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 // * One failure due the server's certificate chain being unavailible and the | 146 // * One failure due the server's certificate chain being unavailible and the |
147 // server being unwilling to send it without a valid source-address token. | 147 // server being unwilling to send it without a valid source-address token. |
148 static const int kMaxClientHellos = 3; | 148 static const int kMaxClientHellos = 3; |
149 | 149 |
150 void QuicCryptoClientStream::DoHandshakeLoop( | 150 void QuicCryptoClientStream::DoHandshakeLoop( |
151 const CryptoHandshakeMessage* in) { | 151 const CryptoHandshakeMessage* in) { |
152 CryptoHandshakeMessage out; | 152 CryptoHandshakeMessage out; |
153 QuicErrorCode error; | 153 QuicErrorCode error; |
154 string error_details; | 154 string error_details; |
155 QuicCryptoClientConfig::CachedState* cached = | 155 QuicCryptoClientConfig::CachedState* cached = |
156 crypto_config_->LookupOrCreate(server_hostname_); | 156 crypto_config_->LookupOrCreate(session_key_); |
157 | 157 |
158 if (in != NULL) { | 158 if (in != NULL) { |
159 DVLOG(1) << "Client: Received " << in->DebugString(); | 159 DVLOG(1) << "Client: Received " << in->DebugString(); |
160 } | 160 } |
161 | 161 |
162 for (;;) { | 162 for (;;) { |
163 const State state = next_state_; | 163 const State state = next_state_; |
164 next_state_ = STATE_IDLE; | 164 next_state_ = STATE_IDLE; |
165 switch (state) { | 165 switch (state) { |
166 case STATE_LOAD_QUIC_SERVER_INFO: { | 166 case STATE_LOAD_QUIC_SERVER_INFO: { |
(...skipping 10 matching lines...) Expand all Loading... | |
177 // Send the client hello in plaintext. | 177 // Send the client hello in plaintext. |
178 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 178 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
179 if (num_client_hellos_ > kMaxClientHellos) { | 179 if (num_client_hellos_ > kMaxClientHellos) { |
180 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 180 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
181 return; | 181 return; |
182 } | 182 } |
183 num_client_hellos_++; | 183 num_client_hellos_++; |
184 | 184 |
185 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 185 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
186 crypto_config_->FillInchoateClientHello( | 186 crypto_config_->FillInchoateClientHello( |
187 server_hostname_, | 187 session_key_.host_port_pair().host(), |
188 session()->connection()->supported_versions().front(), | 188 session()->connection()->supported_versions().front(), |
189 cached, &crypto_negotiated_params_, &out); | 189 cached, &crypto_negotiated_params_, &out); |
190 // Pad the inchoate client hello to fill up a packet. | 190 // Pad the inchoate client hello to fill up a packet. |
191 const size_t kFramingOverhead = 50; // A rough estimate. | 191 const size_t kFramingOverhead = 50; // A rough estimate. |
192 const size_t max_packet_size = | 192 const size_t max_packet_size = |
193 session()->connection()->options()->max_packet_length; | 193 session()->connection()->options()->max_packet_length; |
194 if (max_packet_size <= kFramingOverhead) { | 194 if (max_packet_size <= kFramingOverhead) { |
195 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 195 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
196 << ") has no room for framing overhead."; | 196 << ") has no room for framing overhead."; |
197 CloseConnection(QUIC_INTERNAL_ERROR); | 197 CloseConnection(QUIC_INTERNAL_ERROR); |
198 return; | 198 return; |
199 } | 199 } |
200 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { | 200 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { |
201 DLOG(DFATAL) << "Client hello won't fit in a single packet."; | 201 DLOG(DFATAL) << "Client hello won't fit in a single packet."; |
202 CloseConnection(QUIC_INTERNAL_ERROR); | 202 CloseConnection(QUIC_INTERNAL_ERROR); |
203 return; | 203 return; |
204 } | 204 } |
205 out.set_minimum_size(max_packet_size - kFramingOverhead); | 205 out.set_minimum_size(max_packet_size - kFramingOverhead); |
206 next_state_ = STATE_RECV_REJ; | 206 next_state_ = STATE_RECV_REJ; |
207 DVLOG(1) << "Client: Sending " << out.DebugString(); | 207 DVLOG(1) << "Client: Sending " << out.DebugString(); |
208 SendHandshakeMessage(out); | 208 SendHandshakeMessage(out); |
209 return; | 209 return; |
210 } | 210 } |
211 session()->config()->ToHandshakeMessage(&out); | 211 session()->config()->ToHandshakeMessage(&out); |
212 error = crypto_config_->FillClientHello( | 212 error = crypto_config_->FillClientHello( |
213 server_hostname_, | 213 session_key_.host_port_pair().host(), |
214 session()->connection()->connection_id(), | 214 session()->connection()->connection_id(), |
215 session()->connection()->supported_versions().front(), | 215 session()->connection()->supported_versions().front(), |
216 cached, | 216 cached, |
217 session()->connection()->clock()->WallNow(), | 217 session()->connection()->clock()->WallNow(), |
218 session()->connection()->random_generator(), | 218 session()->connection()->random_generator(), |
219 &crypto_negotiated_params_, | 219 &crypto_negotiated_params_, |
220 &out, | 220 &out, |
221 &error_details); | 221 &error_details); |
222 if (error != QUIC_NO_ERROR) { | 222 if (error != QUIC_NO_ERROR) { |
223 // Flush the cached config so that, if it's bad, the server has a | 223 // Flush the cached config so that, if it's bad, the server has a |
(...skipping 66 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 session_key_.host_port_pair().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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 480 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
481 if (!verifier) { | 481 if (!verifier) { |
482 // If no verifier is set then we don't check the certificates. | 482 // If no verifier is set then we don't check the certificates. |
483 cached->SetProofValid(); | 483 cached->SetProofValid(); |
484 } else if (!cached->signature().empty()) { | 484 } else if (!cached->signature().empty()) { |
485 next_state_ = STATE_VERIFY_PROOF; | 485 next_state_ = STATE_VERIFY_PROOF; |
486 } | 486 } |
487 } | 487 } |
488 | 488 |
489 } // namespace net | 489 } // namespace net |
OLD | NEW |