| 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 <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
| 11 #include "base/strings/stringprintf.h" |
| 11 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
| 12 #include "net/quic/crypto/crypto_utils.h" | 13 #include "net/quic/crypto/crypto_utils.h" |
| 13 #include "net/quic/crypto/null_encrypter.h" | 14 #include "net/quic/crypto/null_encrypter.h" |
| 14 #include "net/quic/quic_client_session_base.h" | 15 #include "net/quic/quic_client_session_base.h" |
| 15 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
| 16 #include "net/quic/quic_protocol.h" | 17 #include "net/quic/quic_protocol.h" |
| 17 #include "net/quic/quic_session.h" | 18 #include "net/quic/quic_session.h" |
| 18 | 19 |
| 19 using std::string; | 20 using std::string; |
| 20 using std::vector; | 21 using std::vector; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 proof_verify_callback_->Cancel(); | 129 proof_verify_callback_->Cancel(); |
| 129 } | 130 } |
| 130 } | 131 } |
| 131 | 132 |
| 132 void QuicCryptoClientStream::OnHandshakeMessage( | 133 void QuicCryptoClientStream::OnHandshakeMessage( |
| 133 const CryptoHandshakeMessage& message) { | 134 const CryptoHandshakeMessage& message) { |
| 134 QuicCryptoClientStreamBase::OnHandshakeMessage(message); | 135 QuicCryptoClientStreamBase::OnHandshakeMessage(message); |
| 135 | 136 |
| 136 if (message.tag() == kSCUP) { | 137 if (message.tag() == kSCUP) { |
| 137 if (!handshake_confirmed()) { | 138 if (!handshake_confirmed()) { |
| 138 CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE); | 139 CloseConnectionWithDetails(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, |
| 140 "Early SCUP disallowed"); |
| 139 return; | 141 return; |
| 140 } | 142 } |
| 141 | 143 |
| 142 // |message| is an update from the server, so we treat it differently from a | 144 // |message| is an update from the server, so we treat it differently from a |
| 143 // handshake message. | 145 // handshake message. |
| 144 HandleServerConfigUpdateMessage(message); | 146 HandleServerConfigUpdateMessage(message); |
| 145 return; | 147 return; |
| 146 } | 148 } |
| 147 | 149 |
| 148 // Do not process handshake messages after the handshake is confirmed. | 150 // Do not process handshake messages after the handshake is confirmed. |
| 149 if (handshake_confirmed()) { | 151 if (handshake_confirmed()) { |
| 150 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); | 152 CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, |
| 153 "Unexpected handshake message"); |
| 151 return; | 154 return; |
| 152 } | 155 } |
| 153 | 156 |
| 154 DoHandshakeLoop(&message); | 157 DoHandshakeLoop(&message); |
| 155 } | 158 } |
| 156 | 159 |
| 157 void QuicCryptoClientStream::CryptoConnect() { | 160 void QuicCryptoClientStream::CryptoConnect() { |
| 158 next_state_ = STATE_INITIALIZE; | 161 next_state_ = STATE_INITIALIZE; |
| 159 DoHandshakeLoop(nullptr); | 162 DoHandshakeLoop(nullptr); |
| 160 } | 163 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 rv = DoGetChannelID(cached); | 230 rv = DoGetChannelID(cached); |
| 228 break; | 231 break; |
| 229 case STATE_GET_CHANNEL_ID_COMPLETE: | 232 case STATE_GET_CHANNEL_ID_COMPLETE: |
| 230 DoGetChannelIDComplete(); | 233 DoGetChannelIDComplete(); |
| 231 break; | 234 break; |
| 232 case STATE_RECV_SHLO: | 235 case STATE_RECV_SHLO: |
| 233 DoReceiveSHLO(in, cached); | 236 DoReceiveSHLO(in, cached); |
| 234 break; | 237 break; |
| 235 case STATE_IDLE: | 238 case STATE_IDLE: |
| 236 // This means that the peer sent us a message that we weren't expecting. | 239 // This means that the peer sent us a message that we weren't expecting. |
| 237 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 240 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 241 "Handshake in idle state"); |
| 238 return; | 242 return; |
| 239 case STATE_INITIALIZE_SCUP: | 243 case STATE_INITIALIZE_SCUP: |
| 240 DoInitializeServerConfigUpdate(cached); | 244 DoInitializeServerConfigUpdate(cached); |
| 241 break; | 245 break; |
| 242 case STATE_NONE: | 246 case STATE_NONE: |
| 243 NOTREACHED(); | 247 NOTREACHED(); |
| 244 return; // We are done. | 248 return; // We are done. |
| 245 } | 249 } |
| 246 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); | 250 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); |
| 247 } | 251 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 273 session()->connection()->CloseConnection( | 277 session()->connection()->CloseConnection( |
| 274 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, false); | 278 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, false); |
| 275 } | 279 } |
| 276 return; | 280 return; |
| 277 } | 281 } |
| 278 | 282 |
| 279 // Send the client hello in plaintext. | 283 // Send the client hello in plaintext. |
| 280 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 284 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
| 281 encryption_established_ = false; | 285 encryption_established_ = false; |
| 282 if (num_client_hellos_ > kMaxClientHellos) { | 286 if (num_client_hellos_ > kMaxClientHellos) { |
| 283 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 287 CloseConnectionWithDetails( |
| 288 QUIC_CRYPTO_TOO_MANY_REJECTS, |
| 289 base::StringPrintf("More than %u rejects", kMaxClientHellos).c_str()); |
| 284 return; | 290 return; |
| 285 } | 291 } |
| 286 num_client_hellos_++; | 292 num_client_hellos_++; |
| 287 | 293 |
| 288 CryptoHandshakeMessage out; | 294 CryptoHandshakeMessage out; |
| 289 DCHECK(session() != nullptr); | 295 DCHECK(session() != nullptr); |
| 290 DCHECK(session()->config() != nullptr); | 296 DCHECK(session()->config() != nullptr); |
| 291 // Send all the options, regardless of whether we're sending an | 297 // Send all the options, regardless of whether we're sending an |
| 292 // inchoate or subsequent hello. | 298 // inchoate or subsequent hello. |
| 293 session()->config()->ToHandshakeMessage(&out); | 299 session()->config()->ToHandshakeMessage(&out); |
| 294 | 300 |
| 295 // This block and function should be removed after removing QUIC_VERSION_25. | 301 // This block and function should be removed after removing QUIC_VERSION_25. |
| 296 if (FLAGS_quic_require_fix) { | 302 if (FLAGS_quic_require_fix) { |
| 297 AppendFixed(&out); | 303 AppendFixed(&out); |
| 298 } | 304 } |
| 299 | 305 |
| 300 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 306 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
| 301 crypto_config_->FillInchoateClientHello( | 307 crypto_config_->FillInchoateClientHello( |
| 302 server_id_, session()->connection()->supported_versions().front(), | 308 server_id_, session()->connection()->supported_versions().front(), |
| 303 cached, &crypto_negotiated_params_, &out); | 309 cached, &crypto_negotiated_params_, &out); |
| 304 // Pad the inchoate client hello to fill up a packet. | 310 // Pad the inchoate client hello to fill up a packet. |
| 305 const QuicByteCount kFramingOverhead = 50; // A rough estimate. | 311 const QuicByteCount kFramingOverhead = 50; // A rough estimate. |
| 306 const QuicByteCount max_packet_size = | 312 const QuicByteCount max_packet_size = |
| 307 session()->connection()->max_packet_length(); | 313 session()->connection()->max_packet_length(); |
| 308 if (max_packet_size <= kFramingOverhead) { | 314 if (max_packet_size <= kFramingOverhead) { |
| 309 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 315 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
| 310 << ") has no room for framing overhead."; | 316 << ") has no room for framing overhead."; |
| 311 CloseConnection(QUIC_INTERNAL_ERROR); | 317 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, |
| 318 "max_packet_size too smalll"); |
| 312 return; | 319 return; |
| 313 } | 320 } |
| 314 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { | 321 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { |
| 315 DLOG(DFATAL) << "Client hello won't fit in a single packet."; | 322 DLOG(DFATAL) << "Client hello won't fit in a single packet."; |
| 316 CloseConnection(QUIC_INTERNAL_ERROR); | 323 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large"); |
| 317 return; | 324 return; |
| 318 } | 325 } |
| 319 out.set_minimum_size( | 326 out.set_minimum_size( |
| 320 static_cast<size_t>(max_packet_size - kFramingOverhead)); | 327 static_cast<size_t>(max_packet_size - kFramingOverhead)); |
| 321 next_state_ = STATE_RECV_REJ; | 328 next_state_ = STATE_RECV_REJ; |
| 322 SendHandshakeMessage(out); | 329 SendHandshakeMessage(out); |
| 323 return; | 330 return; |
| 324 } | 331 } |
| 325 | 332 |
| 326 // If the server nonce is empty, copy over the server nonce from a previous | 333 // If the server nonce is empty, copy over the server nonce from a previous |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 670 } |
| 664 } | 671 } |
| 665 return false; | 672 return false; |
| 666 } | 673 } |
| 667 | 674 |
| 668 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 675 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
| 669 return reinterpret_cast<QuicClientSessionBase*>(session()); | 676 return reinterpret_cast<QuicClientSessionBase*>(session()); |
| 670 } | 677 } |
| 671 | 678 |
| 672 } // namespace net | 679 } // namespace net |
| OLD | NEW |