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 "net/base/completion_callback.h" | 7 #include "net/base/completion_callback.h" |
| 8 #include "net/base/net_errors.h" | 8 #include "net/base/net_errors.h" |
| 9 #include "net/quic/crypto/crypto_protocol.h" | 9 #include "net/quic/crypto/crypto_protocol.h" |
| 10 #include "net/quic/crypto/crypto_utils.h" | 10 #include "net/quic/crypto/crypto_utils.h" |
| 11 #include "net/quic/crypto/null_encrypter.h" | 11 #include "net/quic/crypto/null_encrypter.h" |
| 12 #include "net/quic/crypto/proof_verifier.h" | 12 #include "net/quic/crypto/proof_verifier.h" |
| 13 #include "net/quic/crypto/proof_verifier_chromium.h" | 13 #include "net/quic/crypto/proof_verifier_chromium.h" |
| 14 #include "net/quic/crypto/quic_server_info.h" | |
| 14 #include "net/quic/quic_protocol.h" | 15 #include "net/quic/quic_protocol.h" |
| 15 #include "net/quic/quic_session.h" | 16 #include "net/quic/quic_session.h" |
| 16 #include "net/ssl/ssl_connection_status_flags.h" | 17 #include "net/ssl/ssl_connection_status_flags.h" |
| 17 #include "net/ssl/ssl_info.h" | 18 #include "net/ssl/ssl_info.h" |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. | 24 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 } | 85 } |
| 85 | 86 |
| 86 void QuicCryptoClientStream::OnHandshakeMessage( | 87 void QuicCryptoClientStream::OnHandshakeMessage( |
| 87 const CryptoHandshakeMessage& message) { | 88 const CryptoHandshakeMessage& message) { |
| 88 QuicCryptoStream::OnHandshakeMessage(message); | 89 QuicCryptoStream::OnHandshakeMessage(message); |
| 89 | 90 |
| 90 DoHandshakeLoop(&message); | 91 DoHandshakeLoop(&message); |
| 91 } | 92 } |
| 92 | 93 |
| 93 bool QuicCryptoClientStream::CryptoConnect() { | 94 bool QuicCryptoClientStream::CryptoConnect() { |
| 94 next_state_ = STATE_SEND_CHLO; | 95 next_state_ = STATE_LOAD_QUIC_SERVER_INFO; |
| 95 DoHandshakeLoop(NULL); | 96 DoHandshakeLoop(NULL); |
| 96 return true; | 97 return true; |
| 97 } | 98 } |
| 98 | 99 |
| 99 int QuicCryptoClientStream::num_sent_client_hellos() const { | 100 int QuicCryptoClientStream::num_sent_client_hellos() const { |
| 100 return num_client_hellos_; | 101 return num_client_hellos_; |
| 101 } | 102 } |
| 102 | 103 |
| 103 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways | 104 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways |
| 104 // we learn about SSL info (sync vs async vs cached). | 105 // we learn about SSL info (sync vs async vs cached). |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 crypto_config_->LookupOrCreate(server_hostname_); | 153 crypto_config_->LookupOrCreate(server_hostname_); |
| 153 | 154 |
| 154 if (in != NULL) { | 155 if (in != NULL) { |
| 155 DVLOG(1) << "Client: Received " << in->DebugString(); | 156 DVLOG(1) << "Client: Received " << in->DebugString(); |
| 156 } | 157 } |
| 157 | 158 |
| 158 for (;;) { | 159 for (;;) { |
| 159 const State state = next_state_; | 160 const State state = next_state_; |
| 160 next_state_ = STATE_IDLE; | 161 next_state_ = STATE_IDLE; |
| 161 switch (state) { | 162 switch (state) { |
| 163 case STATE_LOAD_QUIC_SERVER_INFO: { | |
| 164 if (DoLoadQuicServerInfo(cached) == ERR_IO_PENDING) { | |
| 165 return; | |
| 166 } | |
| 167 break; | |
| 168 } | |
| 162 case STATE_SEND_CHLO: { | 169 case STATE_SEND_CHLO: { |
| 163 // Send the client hello in plaintext. | 170 // Send the client hello in plaintext. |
| 164 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 171 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
| 165 if (num_client_hellos_ > kMaxClientHellos) { | 172 if (num_client_hellos_ > kMaxClientHellos) { |
| 166 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 173 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
| 167 return; | 174 return; |
| 168 } | 175 } |
| 176 if (!cached->proof_valid() && crypto_config_->proof_verifier() && | |
| 177 !cached->signature().empty()) { | |
| 178 next_state_ = STATE_VERIFY_PROOF; | |
| 179 break; | |
| 180 } | |
|
wtc
2014/02/07 00:54:11
I think this should look like lines 274-283. In pa
ramant (doing other things)
2014/02/07 20:30:51
Done.
| |
| 169 num_client_hellos_++; | 181 num_client_hellos_++; |
| 170 | 182 |
| 171 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 183 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
| 172 crypto_config_->FillInchoateClientHello( | 184 crypto_config_->FillInchoateClientHello( |
| 173 server_hostname_, | 185 server_hostname_, |
| 174 session()->connection()->supported_versions().front(), | 186 session()->connection()->supported_versions().front(), |
| 175 cached, &crypto_negotiated_params_, &out); | 187 cached, &crypto_negotiated_params_, &out); |
| 176 // Pad the inchoate client hello to fill up a packet. | 188 // Pad the inchoate client hello to fill up a packet. |
| 177 const size_t kFramingOverhead = 50; // A rough estimate. | 189 const size_t kFramingOverhead = 50; // A rough estimate. |
| 178 const size_t max_packet_size = | 190 const size_t max_packet_size = |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); | 323 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); |
| 312 return; | 324 return; |
| 313 } | 325 } |
| 314 // Check if generation_counter has changed between STATE_VERIFY_PROOF | 326 // Check if generation_counter has changed between STATE_VERIFY_PROOF |
| 315 // and STATE_VERIFY_PROOF_COMPLETE state changes. | 327 // and STATE_VERIFY_PROOF_COMPLETE state changes. |
| 316 if (generation_counter_ != cached->generation_counter()) { | 328 if (generation_counter_ != cached->generation_counter()) { |
| 317 next_state_ = STATE_VERIFY_PROOF; | 329 next_state_ = STATE_VERIFY_PROOF; |
| 318 } else { | 330 } else { |
| 319 cached->SetProofValid(); | 331 cached->SetProofValid(); |
| 320 cached->SetProofVerifyDetails(verify_details_.release()); | 332 cached->SetProofVerifyDetails(verify_details_.release()); |
| 333 cached->SaveQuicServerInfo(); | |
|
wtc
2014/02/07 00:54:11
This can be refined. We only need to call cached->
ramant (doing other things)
2014/02/07 20:30:51
ACK (and changed the code).
We set need_to_persis
| |
| 321 next_state_ = STATE_SEND_CHLO; | 334 next_state_ = STATE_SEND_CHLO; |
| 322 } | 335 } |
| 323 break; | 336 break; |
| 324 case STATE_RECV_SHLO: { | 337 case STATE_RECV_SHLO: { |
| 325 // We sent a CHLO that we expected to be accepted and now we're hoping | 338 // We sent a CHLO that we expected to be accepted and now we're hoping |
| 326 // for a SHLO from the server to confirm that. | 339 // for a SHLO from the server to confirm that. |
| 327 if (in->tag() == kREJ) { | 340 if (in->tag() == kREJ) { |
| 328 // alternative_decrypter will be NULL if the original alternative | 341 // alternative_decrypter will be NULL if the original alternative |
| 329 // decrypter latched and became the primary decrypter. That happens | 342 // decrypter latched and became the primary decrypter. That happens |
| 330 // if we received a message encrypted with the INITIAL key. | 343 // if we received a message encrypted with the INITIAL key. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 return; | 400 return; |
| 388 } | 401 } |
| 389 case STATE_IDLE: | 402 case STATE_IDLE: |
| 390 // This means that the peer sent us a message that we weren't expecting. | 403 // This means that the peer sent us a message that we weren't expecting. |
| 391 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 404 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); |
| 392 return; | 405 return; |
| 393 } | 406 } |
| 394 } | 407 } |
| 395 } | 408 } |
| 396 | 409 |
| 410 void QuicCryptoClientStream::OnIOComplete(int result) { | |
| 411 DCHECK_EQ(STATE_LOAD_QUIC_SERVER_INFO, next_state_); | |
| 412 DoHandshakeLoop(NULL); | |
| 413 } | |
| 414 | |
| 415 int QuicCryptoClientStream::DoLoadQuicServerInfo( | |
|
wtc
2014/02/07 00:54:11
This function should be split into two state: STAT
ramant (doing other things)
2014/02/07 20:30:51
Done.
| |
| 416 QuicCryptoClientConfig::CachedState* cached) { | |
| 417 next_state_ = STATE_SEND_CHLO; | |
| 418 QuicServerInfo* quic_server_info = cached->quic_server_info(); | |
| 419 if (!quic_server_info) { | |
| 420 return OK; | |
| 421 } | |
| 422 | |
| 423 int rv = quic_server_info->WaitForDataReady( | |
| 424 base::Bind(&QuicCryptoClientStream::OnIOComplete, | |
| 425 base::Unretained(this))); | |
| 426 | |
| 427 if (rv != OK) { | |
| 428 if (rv == ERR_IO_PENDING) { | |
| 429 next_state_ = STATE_LOAD_QUIC_SERVER_INFO; | |
| 430 } | |
| 431 return rv; | |
|
wtc
2014/02/07 00:54:11
We may want to return OK in this case. We should a
ramant (doing other things)
2014/02/07 20:30:51
Done.
| |
| 432 } | |
| 433 | |
| 434 cached->LoadQuicServerInfo(); | |
| 435 | |
| 436 return rv; | |
| 437 } | |
| 438 | |
| 397 } // namespace net | 439 } // namespace net |
| OLD | NEW |