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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 rv = DoGetChannelID(cached); | 231 rv = DoGetChannelID(cached); |
229 break; | 232 break; |
230 case STATE_GET_CHANNEL_ID_COMPLETE: | 233 case STATE_GET_CHANNEL_ID_COMPLETE: |
231 DoGetChannelIDComplete(); | 234 DoGetChannelIDComplete(); |
232 break; | 235 break; |
233 case STATE_RECV_SHLO: | 236 case STATE_RECV_SHLO: |
234 DoReceiveSHLO(in, cached); | 237 DoReceiveSHLO(in, cached); |
235 break; | 238 break; |
236 case STATE_IDLE: | 239 case STATE_IDLE: |
237 // This means that the peer sent us a message that we weren't expecting. | 240 // This means that the peer sent us a message that we weren't expecting. |
238 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 241 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 242 "Handshake in idle state"); |
239 return; | 243 return; |
240 case STATE_INITIALIZE_SCUP: | 244 case STATE_INITIALIZE_SCUP: |
241 DoInitializeServerConfigUpdate(cached); | 245 DoInitializeServerConfigUpdate(cached); |
242 break; | 246 break; |
243 case STATE_NONE: | 247 case STATE_NONE: |
244 NOTREACHED(); | 248 NOTREACHED(); |
245 return; // We are done. | 249 return; // We are done. |
246 } | 250 } |
247 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); | 251 } while (rv != QUIC_PENDING && next_state_ != STATE_NONE); |
248 } | 252 } |
(...skipping 25 matching lines...) Expand all Loading... |
274 session()->connection()->CloseConnection( | 278 session()->connection()->CloseConnection( |
275 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, false); | 279 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, false); |
276 } | 280 } |
277 return; | 281 return; |
278 } | 282 } |
279 | 283 |
280 // Send the client hello in plaintext. | 284 // Send the client hello in plaintext. |
281 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 285 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
282 encryption_established_ = false; | 286 encryption_established_ = false; |
283 if (num_client_hellos_ > kMaxClientHellos) { | 287 if (num_client_hellos_ > kMaxClientHellos) { |
284 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 288 CloseConnectionWithDetails( |
| 289 QUIC_CRYPTO_TOO_MANY_REJECTS, |
| 290 base::StringPrintf("More than %u rejects", kMaxClientHellos).c_str()); |
285 return; | 291 return; |
286 } | 292 } |
287 num_client_hellos_++; | 293 num_client_hellos_++; |
288 | 294 |
289 CryptoHandshakeMessage out; | 295 CryptoHandshakeMessage out; |
290 DCHECK(session() != nullptr); | 296 DCHECK(session() != nullptr); |
291 DCHECK(session()->config() != nullptr); | 297 DCHECK(session()->config() != nullptr); |
292 // Send all the options, regardless of whether we're sending an | 298 // Send all the options, regardless of whether we're sending an |
293 // inchoate or subsequent hello. | 299 // inchoate or subsequent hello. |
294 session()->config()->ToHandshakeMessage(&out); | 300 session()->config()->ToHandshakeMessage(&out); |
295 | 301 |
296 // This block and function should be removed after removing QUIC_VERSION_25. | 302 // This block and function should be removed after removing QUIC_VERSION_25. |
297 if (FLAGS_quic_require_fix) { | 303 if (FLAGS_quic_require_fix) { |
298 AppendFixed(&out); | 304 AppendFixed(&out); |
299 } | 305 } |
300 | 306 |
301 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 307 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
302 crypto_config_->FillInchoateClientHello( | 308 crypto_config_->FillInchoateClientHello( |
303 server_id_, | 309 server_id_, |
304 session()->connection()->supported_versions().front(), | 310 session()->connection()->supported_versions().front(), |
305 cached, &crypto_negotiated_params_, &out); | 311 cached, &crypto_negotiated_params_, &out); |
306 // Pad the inchoate client hello to fill up a packet. | 312 // Pad the inchoate client hello to fill up a packet. |
307 const QuicByteCount kFramingOverhead = 50; // A rough estimate. | 313 const QuicByteCount kFramingOverhead = 50; // A rough estimate. |
308 const QuicByteCount max_packet_size = | 314 const QuicByteCount max_packet_size = |
309 session()->connection()->max_packet_length(); | 315 session()->connection()->max_packet_length(); |
310 if (max_packet_size <= kFramingOverhead) { | 316 if (max_packet_size <= kFramingOverhead) { |
311 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 317 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
312 << ") has no room for framing overhead."; | 318 << ") has no room for framing overhead."; |
313 CloseConnection(QUIC_INTERNAL_ERROR); | 319 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, |
| 320 "max_packet_size too smalll"); |
314 return; | 321 return; |
315 } | 322 } |
316 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { | 323 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { |
317 DLOG(DFATAL) << "Client hello won't fit in a single packet."; | 324 DLOG(DFATAL) << "Client hello won't fit in a single packet."; |
318 CloseConnection(QUIC_INTERNAL_ERROR); | 325 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large"); |
319 return; | 326 return; |
320 } | 327 } |
321 out.set_minimum_size( | 328 out.set_minimum_size( |
322 static_cast<size_t>(max_packet_size - kFramingOverhead)); | 329 static_cast<size_t>(max_packet_size - kFramingOverhead)); |
323 next_state_ = STATE_RECV_REJ; | 330 next_state_ = STATE_RECV_REJ; |
324 SendHandshakeMessage(out); | 331 SendHandshakeMessage(out); |
325 return; | 332 return; |
326 } | 333 } |
327 | 334 |
328 // If the server nonce is empty, copy over the server nonce from a previous | 335 // If the server nonce is empty, copy over the server nonce from a previous |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 } | 682 } |
676 } | 683 } |
677 return false; | 684 return false; |
678 } | 685 } |
679 | 686 |
680 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 687 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
681 return reinterpret_cast<QuicClientSessionBase*>(session()); | 688 return reinterpret_cast<QuicClientSessionBase*>(session()); |
682 } | 689 } |
683 | 690 |
684 } // namespace net | 691 } // namespace net |
OLD | NEW |