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 |