Chromium Code Reviews| 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 |