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 |