| 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_server_stream.h" | 5 #include "net/quic/core/quic_crypto_server_stream.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "crypto/secure_hash.h" | 10 #include "crypto/secure_hash.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 CryptoUtils::HashHandshakeMessage(message, &chlo_hash_); | 116 CryptoUtils::HashHandshakeMessage(message, &chlo_hash_); |
| 117 | 117 |
| 118 std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this)); | 118 std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this)); |
| 119 validate_client_hello_cb_ = cb.get(); | 119 validate_client_hello_cb_ = cb.get(); |
| 120 crypto_config_->ValidateClientHello( | 120 crypto_config_->ValidateClientHello( |
| 121 message, session()->connection()->peer_address().address(), | 121 message, session()->connection()->peer_address().address(), |
| 122 session()->connection()->self_address().address(), version(), | 122 session()->connection()->self_address().address(), version(), |
| 123 session()->connection()->clock(), &crypto_proof_, std::move(cb)); | 123 session()->connection()->clock(), &crypto_proof_, std::move(cb)); |
| 124 } | 124 } |
| 125 | 125 |
| 126 class QuicCryptoServerStream::ProcessClientHelloCallback |
| 127 : public ProcessClientHelloResultCallback { |
| 128 public: |
| 129 ProcessClientHelloCallback( |
| 130 QuicCryptoServerStream* stream, |
| 131 const scoped_refptr<ValidateClientHelloResultCallback::Result>& result) |
| 132 : stream_(stream), result_(result) {} |
| 133 |
| 134 void Run( |
| 135 QuicErrorCode error, |
| 136 const string& error_details, |
| 137 std::unique_ptr<CryptoHandshakeMessage> message, |
| 138 std::unique_ptr<DiversificationNonce> diversification_nonce) override { |
| 139 stream_->FinishProcessingHandshakeMessageAfterProcessClientHello( |
| 140 *result_, error, error_details, std::move(message), |
| 141 std::move(diversification_nonce)); |
| 142 } |
| 143 |
| 144 private: |
| 145 QuicCryptoServerStream* stream_; |
| 146 scoped_refptr<ValidateClientHelloResultCallback::Result> result_; |
| 147 }; |
| 148 |
| 126 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( | 149 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( |
| 127 scoped_refptr<ValidateClientHelloResultCallback::Result> result, | 150 scoped_refptr<ValidateClientHelloResultCallback::Result> result, |
| 128 std::unique_ptr<ProofSource::Details> details) { | 151 std::unique_ptr<ProofSource::Details> details) { |
| 129 const CryptoHandshakeMessage& message = result->client_hello; | 152 const CryptoHandshakeMessage& message = result->client_hello; |
| 130 | 153 |
| 131 // Clear the callback that got us here. | 154 // Clear the callback that got us here. |
| 132 DCHECK(validate_client_hello_cb_ != nullptr); | 155 DCHECK(validate_client_hello_cb_ != nullptr); |
| 133 validate_client_hello_cb_ = nullptr; | 156 validate_client_hello_cb_ = nullptr; |
| 134 | 157 |
| 135 if (use_stateless_rejects_if_peer_supported_) { | 158 if (use_stateless_rejects_if_peer_supported_) { |
| 136 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message); | 159 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message); |
| 137 } | 160 } |
| 138 | 161 |
| 139 string error_details; | 162 std::unique_ptr<ProcessClientHelloCallback> cb( |
| 140 std::unique_ptr<CryptoHandshakeMessage> reply(new CryptoHandshakeMessage); | 163 new ProcessClientHelloCallback(this, result)); |
| 141 std::unique_ptr<DiversificationNonce> diversification_nonce( | 164 ProcessClientHello(result, std::move(details), std::move(cb)); |
| 142 new DiversificationNonce); | |
| 143 QuicErrorCode error = | |
| 144 ProcessClientHello(result, std::move(details), reply.get(), | |
| 145 diversification_nonce.get(), &error_details); | |
| 146 | |
| 147 // Note: this split exists to facilitate a future conversion of | |
| 148 // ProcessClientHello to an async signature. | |
| 149 FinishProcessingHandshakeMessageAfterProcessClientHello( | |
| 150 *result, error, error_details, std::move(reply), | |
| 151 std::move(diversification_nonce)); | |
| 152 } | 165 } |
| 153 | 166 |
| 154 void QuicCryptoServerStream:: | 167 void QuicCryptoServerStream:: |
| 155 FinishProcessingHandshakeMessageAfterProcessClientHello( | 168 FinishProcessingHandshakeMessageAfterProcessClientHello( |
| 156 const ValidateClientHelloResultCallback::Result& result, | 169 const ValidateClientHelloResultCallback::Result& result, |
| 157 QuicErrorCode error, | 170 QuicErrorCode error, |
| 158 const string& error_details, | 171 const string& error_details, |
| 159 std::unique_ptr<CryptoHandshakeMessage> reply, | 172 std::unique_ptr<CryptoHandshakeMessage> reply, |
| 160 std::unique_ptr<DiversificationNonce> diversification_nonce) { | 173 std::unique_ptr<DiversificationNonce> diversification_nonce) { |
| 161 const CryptoHandshakeMessage& message = result.client_hello; | 174 const CryptoHandshakeMessage& message = result.client_hello; |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 len--; | 403 len--; |
| 391 if ((*output)[len - 1] == '=') { | 404 if ((*output)[len - 1] == '=') { |
| 392 len--; | 405 len--; |
| 393 } | 406 } |
| 394 output->resize(len); | 407 output->resize(len); |
| 395 } | 408 } |
| 396 } | 409 } |
| 397 return true; | 410 return true; |
| 398 } | 411 } |
| 399 | 412 |
| 400 class QuicCryptoServerStream::ProcessClientHelloCallback | 413 void QuicCryptoServerStream::ProcessClientHello( |
| 401 : public ProcessClientHelloResultCallback { | |
| 402 public: | |
| 403 ProcessClientHelloCallback(QuicErrorCode* error, | |
| 404 string* error_details, | |
| 405 CryptoHandshakeMessage* message, | |
| 406 DiversificationNonce* diversification_nonce) | |
| 407 : error_(error), | |
| 408 error_details_(error_details), | |
| 409 message_(message), | |
| 410 diversification_nonce_(diversification_nonce) {} | |
| 411 | |
| 412 void Run( | |
| 413 QuicErrorCode error, | |
| 414 const string& error_details, | |
| 415 std::unique_ptr<CryptoHandshakeMessage> message, | |
| 416 std::unique_ptr<DiversificationNonce> diversification_nonce) override { | |
| 417 *error_ = error; | |
| 418 *error_details_ = error_details; | |
| 419 if (message != nullptr) { | |
| 420 *message_ = *message; | |
| 421 } | |
| 422 if (diversification_nonce != nullptr) { | |
| 423 *diversification_nonce_ = *diversification_nonce; | |
| 424 } | |
| 425 // NOTE: copies the message, nonce, and error details. This is a temporary | |
| 426 // condition until this codepath is fully asynchronized. | |
| 427 // TODO(gredner): Fix this. | |
| 428 } | |
| 429 | |
| 430 private: | |
| 431 QuicErrorCode* error_; | |
| 432 string* error_details_; | |
| 433 CryptoHandshakeMessage* message_; | |
| 434 DiversificationNonce* diversification_nonce_; | |
| 435 }; | |
| 436 | |
| 437 QuicErrorCode QuicCryptoServerStream::ProcessClientHello( | |
| 438 scoped_refptr<ValidateClientHelloResultCallback::Result> result, | 414 scoped_refptr<ValidateClientHelloResultCallback::Result> result, |
| 439 std::unique_ptr<ProofSource::Details> proof_source_details, | 415 std::unique_ptr<ProofSource::Details> proof_source_details, |
| 440 CryptoHandshakeMessage* reply, | 416 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) { |
| 441 DiversificationNonce* out_diversification_nonce, | |
| 442 string* error_details) { | |
| 443 const CryptoHandshakeMessage& message = result->client_hello; | 417 const CryptoHandshakeMessage& message = result->client_hello; |
| 418 string error_details; |
| 444 if (!helper_->CanAcceptClientHello( | 419 if (!helper_->CanAcceptClientHello( |
| 445 message, session()->connection()->self_address(), error_details)) { | 420 message, session()->connection()->self_address(), &error_details)) { |
| 446 return QUIC_HANDSHAKE_FAILED; | 421 done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr); |
| 422 return; |
| 447 } | 423 } |
| 448 | 424 |
| 449 if (!result->info.server_nonce.empty()) { | 425 if (!result->info.server_nonce.empty()) { |
| 450 ++num_handshake_messages_with_server_nonces_; | 426 ++num_handshake_messages_with_server_nonces_; |
| 451 } | 427 } |
| 452 // Store the bandwidth estimate from the client. | 428 // Store the bandwidth estimate from the client. |
| 453 if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) { | 429 if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) { |
| 454 previous_cached_network_params_.reset( | 430 previous_cached_network_params_.reset( |
| 455 new CachedNetworkParameters(result->cached_network_params)); | 431 new CachedNetworkParameters(result->cached_network_params)); |
| 456 } | 432 } |
| 457 previous_source_address_tokens_ = result->info.source_address_tokens; | 433 previous_source_address_tokens_ = result->info.source_address_tokens; |
| 458 | 434 |
| 459 const bool use_stateless_rejects_in_crypto_config = | 435 const bool use_stateless_rejects_in_crypto_config = |
| 460 use_stateless_rejects_if_peer_supported_ && | 436 use_stateless_rejects_if_peer_supported_ && |
| 461 peer_supports_stateless_rejects_; | 437 peer_supports_stateless_rejects_; |
| 462 QuicConnection* connection = session()->connection(); | 438 QuicConnection* connection = session()->connection(); |
| 463 const QuicConnectionId server_designated_connection_id = | 439 const QuicConnectionId server_designated_connection_id = |
| 464 GenerateConnectionIdForReject(use_stateless_rejects_in_crypto_config); | 440 GenerateConnectionIdForReject(use_stateless_rejects_in_crypto_config); |
| 465 | |
| 466 QuicErrorCode error = QUIC_NO_ERROR; | |
| 467 std::unique_ptr<ProcessClientHelloCallback> cb(new ProcessClientHelloCallback( | |
| 468 &error, error_details, reply, out_diversification_nonce)); | |
| 469 crypto_config_->ProcessClientHello( | 441 crypto_config_->ProcessClientHello( |
| 470 result, /*reject_only=*/false, connection->connection_id(), | 442 result, /*reject_only=*/false, connection->connection_id(), |
| 471 connection->self_address().address(), connection->peer_address(), | 443 connection->self_address().address(), connection->peer_address(), |
| 472 version(), connection->supported_versions(), | 444 version(), connection->supported_versions(), |
| 473 use_stateless_rejects_in_crypto_config, server_designated_connection_id, | 445 use_stateless_rejects_in_crypto_config, server_designated_connection_id, |
| 474 connection->clock(), connection->random_generator(), | 446 connection->clock(), connection->random_generator(), |
| 475 compressed_certs_cache_, &crypto_negotiated_params_, &crypto_proof_, | 447 compressed_certs_cache_, &crypto_negotiated_params_, &crypto_proof_, |
| 476 QuicCryptoStream::CryptoMessageFramingOverhead(version()), | 448 QuicCryptoStream::CryptoMessageFramingOverhead(version()), |
| 477 chlo_packet_size_, std::move(cb)); | 449 chlo_packet_size_, std::move(done_cb)); |
| 478 // NOTE: assumes that ProcessClientHello invokes the callback synchronously. | |
| 479 // This is a temporary condition until these codepaths are fully | |
| 480 // asynchronized. | |
| 481 // TODO(gredner): fix this. | |
| 482 | |
| 483 return error; | |
| 484 } | 450 } |
| 485 | 451 |
| 486 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {} | 452 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {} |
| 487 | 453 |
| 488 QuicCryptoServerStream::ValidateCallback::ValidateCallback( | 454 QuicCryptoServerStream::ValidateCallback::ValidateCallback( |
| 489 QuicCryptoServerStream* parent) | 455 QuicCryptoServerStream* parent) |
| 490 : parent_(parent) {} | 456 : parent_(parent) {} |
| 491 | 457 |
| 492 void QuicCryptoServerStream::ValidateCallback::Cancel() { | 458 void QuicCryptoServerStream::ValidateCallback::Cancel() { |
| 493 parent_ = nullptr; | 459 parent_ = nullptr; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 505 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject( | 471 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject( |
| 506 bool use_stateless_rejects) { | 472 bool use_stateless_rejects) { |
| 507 if (!use_stateless_rejects) { | 473 if (!use_stateless_rejects) { |
| 508 return 0; | 474 return 0; |
| 509 } | 475 } |
| 510 return helper_->GenerateConnectionIdForReject( | 476 return helper_->GenerateConnectionIdForReject( |
| 511 session()->connection()->connection_id()); | 477 session()->connection()->connection_id()); |
| 512 } | 478 } |
| 513 | 479 |
| 514 } // namespace net | 480 } // namespace net |
| OLD | NEW |