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/core/quic_crypto_client_stream.h" | 5 #include "net/quic/core/quic_crypto_client_stream.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 165 |
166 void QuicCryptoClientStream::HandleServerConfigUpdateMessage( | 166 void QuicCryptoClientStream::HandleServerConfigUpdateMessage( |
167 const CryptoHandshakeMessage& server_config_update) { | 167 const CryptoHandshakeMessage& server_config_update) { |
168 DCHECK(server_config_update.tag() == kSCUP); | 168 DCHECK(server_config_update.tag() == kSCUP); |
169 string error_details; | 169 string error_details; |
170 QuicCryptoClientConfig::CachedState* cached = | 170 QuicCryptoClientConfig::CachedState* cached = |
171 crypto_config_->LookupOrCreate(server_id_); | 171 crypto_config_->LookupOrCreate(server_id_); |
172 QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate( | 172 QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate( |
173 server_config_update, session()->connection()->clock()->WallNow(), | 173 server_config_update, session()->connection()->clock()->WallNow(), |
174 session()->connection()->version(), cached->chlo_hash(), cached, | 174 session()->connection()->version(), cached->chlo_hash(), cached, |
175 &crypto_negotiated_params_, &error_details); | 175 crypto_negotiated_params_, &error_details); |
176 | 176 |
177 if (error != QUIC_NO_ERROR) { | 177 if (error != QUIC_NO_ERROR) { |
178 CloseConnectionWithDetails( | 178 CloseConnectionWithDetails( |
179 error, "Server config update invalid: " + error_details); | 179 error, "Server config update invalid: " + error_details); |
180 return; | 180 return; |
181 } | 181 } |
182 | 182 |
183 DCHECK(handshake_confirmed()); | 183 DCHECK(handshake_confirmed()); |
184 if (proof_verify_callback_) { | 184 if (proof_verify_callback_) { |
185 proof_verify_callback_->Cancel(); | 185 proof_verify_callback_->Cancel(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 session()->config()->ToHandshakeMessage(&out); | 291 session()->config()->ToHandshakeMessage(&out); |
292 | 292 |
293 // Send a local timestamp to the server. | 293 // Send a local timestamp to the server. |
294 out.SetValue(kCTIM, | 294 out.SetValue(kCTIM, |
295 session()->connection()->clock()->WallNow().ToUNIXSeconds()); | 295 session()->connection()->clock()->WallNow().ToUNIXSeconds()); |
296 | 296 |
297 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 297 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
298 crypto_config_->FillInchoateClientHello( | 298 crypto_config_->FillInchoateClientHello( |
299 server_id_, session()->connection()->supported_versions().front(), | 299 server_id_, session()->connection()->supported_versions().front(), |
300 cached, session()->connection()->random_generator(), | 300 cached, session()->connection()->random_generator(), |
301 /* demand_x509_proof= */ true, &crypto_negotiated_params_, &out); | 301 /* demand_x509_proof= */ true, crypto_negotiated_params_, &out); |
302 // Pad the inchoate client hello to fill up a packet. | 302 // Pad the inchoate client hello to fill up a packet. |
303 const QuicByteCount kFramingOverhead = 50; // A rough estimate. | 303 const QuicByteCount kFramingOverhead = 50; // A rough estimate. |
304 const QuicByteCount max_packet_size = | 304 const QuicByteCount max_packet_size = |
305 session()->connection()->max_packet_length(); | 305 session()->connection()->max_packet_length(); |
306 if (max_packet_size <= kFramingOverhead) { | 306 if (max_packet_size <= kFramingOverhead) { |
307 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 307 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
308 << ") has no room for framing overhead."; | 308 << ") has no room for framing overhead."; |
309 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, | 309 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, |
310 "max_packet_size too smalll"); | 310 "max_packet_size too smalll"); |
311 return; | 311 return; |
312 } | 312 } |
313 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { | 313 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { |
314 DLOG(DFATAL) << "Client hello won't fit in a single packet."; | 314 DLOG(DFATAL) << "Client hello won't fit in a single packet."; |
315 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large"); | 315 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large"); |
316 return; | 316 return; |
317 } | 317 } |
318 // TODO(rch): Remove this when we remove: | 318 // TODO(rch): Remove this when we remove: |
319 // FLAGS_quic_use_chlo_packet_size | 319 // FLAGS_quic_use_chlo_packet_size |
320 out.set_minimum_size( | 320 out.set_minimum_size( |
321 static_cast<size_t>(max_packet_size - kFramingOverhead)); | 321 static_cast<size_t>(max_packet_size - kFramingOverhead)); |
322 next_state_ = STATE_RECV_REJ; | 322 next_state_ = STATE_RECV_REJ; |
323 CryptoUtils::HashHandshakeMessage(out, &chlo_hash_); | 323 CryptoUtils::HashHandshakeMessage(out, &chlo_hash_); |
324 SendHandshakeMessage(out); | 324 SendHandshakeMessage(out); |
325 return; | 325 return; |
326 } | 326 } |
327 | 327 |
328 // If the server nonce is empty, copy over the server nonce from a previous | 328 // If the server nonce is empty, copy over the server nonce from a previous |
329 // SREJ, if there is one. | 329 // SREJ, if there is one. |
330 if (FLAGS_enable_quic_stateless_reject_support && | 330 if (FLAGS_enable_quic_stateless_reject_support && |
331 crypto_negotiated_params_.server_nonce.empty() && | 331 crypto_negotiated_params_->server_nonce.empty() && |
332 cached->has_server_nonce()) { | 332 cached->has_server_nonce()) { |
333 crypto_negotiated_params_.server_nonce = cached->GetNextServerNonce(); | 333 crypto_negotiated_params_->server_nonce = cached->GetNextServerNonce(); |
334 DCHECK(!crypto_negotiated_params_.server_nonce.empty()); | 334 DCHECK(!crypto_negotiated_params_->server_nonce.empty()); |
335 } | 335 } |
336 | 336 |
337 string error_details; | 337 string error_details; |
338 QuicErrorCode error = crypto_config_->FillClientHello( | 338 QuicErrorCode error = crypto_config_->FillClientHello( |
339 server_id_, session()->connection()->connection_id(), | 339 server_id_, session()->connection()->connection_id(), |
340 session()->connection()->version(), | 340 session()->connection()->version(), |
341 session()->connection()->supported_versions().front(), cached, | 341 session()->connection()->supported_versions().front(), cached, |
342 session()->connection()->clock()->WallNow(), | 342 session()->connection()->clock()->WallNow(), |
343 session()->connection()->random_generator(), channel_id_key_.get(), | 343 session()->connection()->random_generator(), channel_id_key_.get(), |
344 &crypto_negotiated_params_, &out, &error_details); | 344 crypto_negotiated_params_, &out, &error_details); |
345 if (error != QUIC_NO_ERROR) { | 345 if (error != QUIC_NO_ERROR) { |
346 // Flush the cached config so that, if it's bad, the server has a | 346 // Flush the cached config so that, if it's bad, the server has a |
347 // chance to send us another in the future. | 347 // chance to send us another in the future. |
348 cached->InvalidateServerConfig(); | 348 cached->InvalidateServerConfig(); |
349 CloseConnectionWithDetails(error, error_details); | 349 CloseConnectionWithDetails(error, error_details); |
350 return; | 350 return; |
351 } | 351 } |
352 CryptoUtils::HashHandshakeMessage(out, &chlo_hash_); | 352 CryptoUtils::HashHandshakeMessage(out, &chlo_hash_); |
353 channel_id_sent_ = (channel_id_key_.get() != nullptr); | 353 channel_id_sent_ = (channel_id_key_.get() != nullptr); |
354 if (cached->proof_verify_details()) { | 354 if (cached->proof_verify_details()) { |
355 proof_handler_->OnProofVerifyDetailsAvailable( | 355 proof_handler_->OnProofVerifyDetailsAvailable( |
356 *cached->proof_verify_details()); | 356 *cached->proof_verify_details()); |
357 } | 357 } |
358 next_state_ = STATE_RECV_SHLO; | 358 next_state_ = STATE_RECV_SHLO; |
359 SendHandshakeMessage(out); | 359 SendHandshakeMessage(out); |
360 // Be prepared to decrypt with the new server write key. | 360 // Be prepared to decrypt with the new server write key. |
361 session()->connection()->SetAlternativeDecrypter( | 361 session()->connection()->SetAlternativeDecrypter( |
362 ENCRYPTION_INITIAL, | 362 ENCRYPTION_INITIAL, |
363 crypto_negotiated_params_.initial_crypters.decrypter.release(), | 363 crypto_negotiated_params_->initial_crypters.decrypter.release(), |
364 true /* latch once used */); | 364 true /* latch once used */); |
365 // Send subsequent packets under encryption on the assumption that the | 365 // Send subsequent packets under encryption on the assumption that the |
366 // server will accept the handshake. | 366 // server will accept the handshake. |
367 session()->connection()->SetEncrypter( | 367 session()->connection()->SetEncrypter( |
368 ENCRYPTION_INITIAL, | 368 ENCRYPTION_INITIAL, |
369 crypto_negotiated_params_.initial_crypters.encrypter.release()); | 369 crypto_negotiated_params_->initial_crypters.encrypter.release()); |
370 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); | 370 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); |
371 | 371 |
372 // TODO(ianswett): Merge ENCRYPTION_REESTABLISHED and | 372 // TODO(ianswett): Merge ENCRYPTION_REESTABLISHED and |
373 // ENCRYPTION_FIRST_ESTABLSIHED | 373 // ENCRYPTION_FIRST_ESTABLSIHED |
374 encryption_established_ = true; | 374 encryption_established_ = true; |
375 session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_REESTABLISHED); | 375 session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_REESTABLISHED); |
376 } | 376 } |
377 | 377 |
378 void QuicCryptoClientStream::DoReceiveREJ( | 378 void QuicCryptoClientStream::DoReceiveREJ( |
379 const CryptoHandshakeMessage* in, | 379 const CryptoHandshakeMessage* in, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 415 |
416 // Receipt of a REJ message means that the server received the CHLO | 416 // Receipt of a REJ message means that the server received the CHLO |
417 // so we can cancel and retransmissions. | 417 // so we can cancel and retransmissions. |
418 session()->connection()->NeuterUnencryptedPackets(); | 418 session()->connection()->NeuterUnencryptedPackets(); |
419 | 419 |
420 stateless_reject_received_ = in->tag() == kSREJ; | 420 stateless_reject_received_ = in->tag() == kSREJ; |
421 string error_details; | 421 string error_details; |
422 QuicErrorCode error = crypto_config_->ProcessRejection( | 422 QuicErrorCode error = crypto_config_->ProcessRejection( |
423 *in, session()->connection()->clock()->WallNow(), | 423 *in, session()->connection()->clock()->WallNow(), |
424 session()->connection()->version(), chlo_hash_, cached, | 424 session()->connection()->version(), chlo_hash_, cached, |
425 &crypto_negotiated_params_, &error_details); | 425 crypto_negotiated_params_, &error_details); |
426 | 426 |
427 if (error != QUIC_NO_ERROR) { | 427 if (error != QUIC_NO_ERROR) { |
428 next_state_ = STATE_NONE; | 428 next_state_ = STATE_NONE; |
429 CloseConnectionWithDetails(error, error_details); | 429 CloseConnectionWithDetails(error, error_details); |
430 return; | 430 return; |
431 } | 431 } |
432 if (!cached->proof_valid()) { | 432 if (!cached->proof_valid()) { |
433 if (!cached->signature().empty()) { | 433 if (!cached->signature().empty()) { |
434 // Note that we only verify the proof if the cached proof is not | 434 // Note that we only verify the proof if the cached proof is not |
435 // valid. If the cached proof is valid here, someone else must have | 435 // valid. If the cached proof is valid here, someone else must have |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 593 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
594 "unencrypted SHLO message"); | 594 "unencrypted SHLO message"); |
595 return; | 595 return; |
596 } | 596 } |
597 | 597 |
598 string error_details; | 598 string error_details; |
599 QuicErrorCode error = crypto_config_->ProcessServerHello( | 599 QuicErrorCode error = crypto_config_->ProcessServerHello( |
600 *in, session()->connection()->connection_id(), | 600 *in, session()->connection()->connection_id(), |
601 session()->connection()->version(), | 601 session()->connection()->version(), |
602 session()->connection()->server_supported_versions(), cached, | 602 session()->connection()->server_supported_versions(), cached, |
603 &crypto_negotiated_params_, &error_details); | 603 crypto_negotiated_params_, &error_details); |
604 | 604 |
605 if (error != QUIC_NO_ERROR) { | 605 if (error != QUIC_NO_ERROR) { |
606 CloseConnectionWithDetails(error, "Server hello invalid: " + error_details); | 606 CloseConnectionWithDetails(error, "Server hello invalid: " + error_details); |
607 return; | 607 return; |
608 } | 608 } |
609 error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details); | 609 error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details); |
610 if (error != QUIC_NO_ERROR) { | 610 if (error != QUIC_NO_ERROR) { |
611 CloseConnectionWithDetails(error, "Server hello invalid: " + error_details); | 611 CloseConnectionWithDetails(error, "Server hello invalid: " + error_details); |
612 return; | 612 return; |
613 } | 613 } |
614 session()->OnConfigNegotiated(); | 614 session()->OnConfigNegotiated(); |
615 | 615 |
616 CrypterPair* crypters = &crypto_negotiated_params_.forward_secure_crypters; | 616 CrypterPair* crypters = &crypto_negotiated_params_->forward_secure_crypters; |
617 // TODO(agl): we don't currently latch this decrypter because the idea | 617 // TODO(agl): we don't currently latch this decrypter because the idea |
618 // has been floated that the server shouldn't send packets encrypted | 618 // has been floated that the server shouldn't send packets encrypted |
619 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE | 619 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE |
620 // packet from the client. | 620 // packet from the client. |
621 session()->connection()->SetAlternativeDecrypter( | 621 session()->connection()->SetAlternativeDecrypter( |
622 ENCRYPTION_FORWARD_SECURE, crypters->decrypter.release(), | 622 ENCRYPTION_FORWARD_SECURE, crypters->decrypter.release(), |
623 false /* don't latch */); | 623 false /* don't latch */); |
624 session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, | 624 session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, |
625 crypters->encrypter.release()); | 625 crypters->encrypter.release()); |
626 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); | 626 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } | 669 } |
670 for (size_t i = 0; i < num_their_proof_demands; i++) { | 670 for (size_t i = 0; i < num_their_proof_demands; i++) { |
671 if (their_proof_demands[i] == kCHID) { | 671 if (their_proof_demands[i] == kCHID) { |
672 return true; | 672 return true; |
673 } | 673 } |
674 } | 674 } |
675 return false; | 675 return false; |
676 } | 676 } |
677 | 677 |
678 } // namespace net | 678 } // namespace net |
OLD | NEW |