| 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 |