| 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 "net/quic/core/crypto/crypto_protocol.h" | 9 #include "net/quic/core/crypto/crypto_protocol.h" |
| 10 #include "net/quic/core/crypto/crypto_utils.h" | 10 #include "net/quic/core/crypto/crypto_utils.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 void Run(QuicErrorCode error, | 36 void Run(QuicErrorCode error, |
| 37 const string& error_details, | 37 const string& error_details, |
| 38 std::unique_ptr<CryptoHandshakeMessage> message, | 38 std::unique_ptr<CryptoHandshakeMessage> message, |
| 39 std::unique_ptr<DiversificationNonce> diversification_nonce, | 39 std::unique_ptr<DiversificationNonce> diversification_nonce, |
| 40 std::unique_ptr<net::ProofSource::Details> proof_source_details) | 40 std::unique_ptr<net::ProofSource::Details> proof_source_details) |
| 41 override { | 41 override { |
| 42 if (stream_ == nullptr) { | 42 if (stream_ == nullptr) { |
| 43 return; | 43 return; |
| 44 } | 44 } |
| 45 | 45 |
| 46 // Note: set the parent's callback to nullptr here because | |
| 47 // FinishProcessingHandshakeMessageAfterProcessClientHello can be invoked | |
| 48 // from either synchronous or asynchronous codepaths. When the synchronous | |
| 49 // codepaths are removed, this assignment should move to | |
| 50 // FinishProcessingHandshakeMessageAfterProcessClientHello. | |
| 51 stream_->process_client_hello_cb_ = nullptr; | |
| 52 | |
| 53 stream_->FinishProcessingHandshakeMessageAfterProcessClientHello( | 46 stream_->FinishProcessingHandshakeMessageAfterProcessClientHello( |
| 54 *result_, error, error_details, std::move(message), | 47 *result_, error, error_details, std::move(message), |
| 55 std::move(diversification_nonce), std::move(proof_source_details)); | 48 std::move(diversification_nonce), std::move(proof_source_details)); |
| 56 } | 49 } |
| 57 | 50 |
| 58 void Cancel() { stream_ = nullptr; } | 51 void Cancel() { stream_ = nullptr; } |
| 59 | 52 |
| 60 private: | 53 private: |
| 61 QuicCryptoServerStream* stream_; | 54 QuicCryptoServerStream* stream_; |
| 62 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 55 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 89 QuicCryptoServerStream::QuicCryptoServerStream( | 82 QuicCryptoServerStream::QuicCryptoServerStream( |
| 90 const QuicCryptoServerConfig* crypto_config, | 83 const QuicCryptoServerConfig* crypto_config, |
| 91 QuicCompressedCertsCache* compressed_certs_cache, | 84 QuicCompressedCertsCache* compressed_certs_cache, |
| 92 bool use_stateless_rejects_if_peer_supported, | 85 bool use_stateless_rejects_if_peer_supported, |
| 93 QuicSession* session, | 86 QuicSession* session, |
| 94 Helper* helper) | 87 Helper* helper) |
| 95 : QuicCryptoServerStreamBase(session), | 88 : QuicCryptoServerStreamBase(session), |
| 96 crypto_config_(crypto_config), | 89 crypto_config_(crypto_config), |
| 97 compressed_certs_cache_(compressed_certs_cache), | 90 compressed_certs_cache_(compressed_certs_cache), |
| 98 signed_config_(new QuicSignedServerConfig), | 91 signed_config_(new QuicSignedServerConfig), |
| 99 validate_client_hello_cb_(nullptr), | |
| 100 helper_(helper), | 92 helper_(helper), |
| 101 num_handshake_messages_(0), | 93 num_handshake_messages_(0), |
| 102 num_handshake_messages_with_server_nonces_(0), | 94 num_handshake_messages_with_server_nonces_(0), |
| 103 send_server_config_update_cb_(nullptr), | 95 send_server_config_update_cb_(nullptr), |
| 104 num_server_config_update_messages_sent_(0), | 96 num_server_config_update_messages_sent_(0), |
| 105 use_stateless_rejects_if_peer_supported_( | 97 use_stateless_rejects_if_peer_supported_( |
| 106 use_stateless_rejects_if_peer_supported), | 98 use_stateless_rejects_if_peer_supported), |
| 107 peer_supports_stateless_rejects_(false), | 99 peer_supports_stateless_rejects_(false), |
| 108 chlo_packet_size_(0), | 100 chlo_packet_size_(0), |
| 101 validate_client_hello_cb_(nullptr), |
| 109 process_client_hello_cb_(nullptr) { | 102 process_client_hello_cb_(nullptr) { |
| 110 DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective()); | 103 DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective()); |
| 111 } | 104 } |
| 112 | 105 |
| 113 QuicCryptoServerStream::~QuicCryptoServerStream() { | 106 QuicCryptoServerStream::~QuicCryptoServerStream() { |
| 114 CancelOutstandingCallbacks(); | 107 CancelOutstandingCallbacks(); |
| 115 } | 108 } |
| 116 | 109 |
| 117 void QuicCryptoServerStream::CancelOutstandingCallbacks() { | 110 void QuicCryptoServerStream::CancelOutstandingCallbacks() { |
| 118 // Detach from the validation callback. Calling this multiple times is safe. | 111 // Detach from the validation callback. Calling this multiple times is safe. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 142 "Unexpected handshake message from client"); | 135 "Unexpected handshake message from client"); |
| 143 return; | 136 return; |
| 144 } | 137 } |
| 145 | 138 |
| 146 if (message.tag() != kCHLO) { | 139 if (message.tag() != kCHLO) { |
| 147 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, | 140 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 148 "Handshake packet not CHLO"); | 141 "Handshake packet not CHLO"); |
| 149 return; | 142 return; |
| 150 } | 143 } |
| 151 | 144 |
| 152 if (validate_client_hello_cb_ != nullptr) { | 145 if (validate_client_hello_cb_ != nullptr || |
| 146 (base::GetFlag(FLAGS_quic_reloadable_flag_fix_quic_callback_crash) && |
| 147 process_client_hello_cb_ != nullptr)) { |
| 153 // Already processing some other handshake message. The protocol | 148 // Already processing some other handshake message. The protocol |
| 154 // does not allow for clients to send multiple handshake messages | 149 // does not allow for clients to send multiple handshake messages |
| 155 // before the server has a chance to respond. | 150 // before the server has a chance to respond. |
| 156 CloseConnectionWithDetails( | 151 CloseConnectionWithDetails( |
| 157 QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO, | 152 QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO, |
| 158 "Unexpected handshake message while processing CHLO"); | 153 "Unexpected handshake message while processing CHLO"); |
| 159 return; | 154 return; |
| 160 } | 155 } |
| 161 | 156 |
| 162 CryptoUtils::HashHandshakeMessage(message, &chlo_hash_); | 157 CryptoUtils::HashHandshakeMessage(message, &chlo_hash_); |
| 163 | 158 |
| 164 std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this)); | 159 std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this)); |
| 160 DCHECK(validate_client_hello_cb_ == nullptr); |
| 161 DCHECK(process_client_hello_cb_ == nullptr); |
| 165 validate_client_hello_cb_ = cb.get(); | 162 validate_client_hello_cb_ = cb.get(); |
| 166 crypto_config_->ValidateClientHello( | 163 crypto_config_->ValidateClientHello( |
| 167 message, session()->connection()->peer_address().host(), | 164 message, session()->connection()->peer_address().host(), |
| 168 session()->connection()->self_address(), version(), | 165 session()->connection()->self_address(), version(), |
| 169 session()->connection()->clock(), signed_config_, std::move(cb)); | 166 session()->connection()->clock(), signed_config_, std::move(cb)); |
| 170 } | 167 } |
| 171 | 168 |
| 172 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( | 169 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( |
| 173 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> | 170 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result> |
| 174 result, | 171 result, |
| 175 std::unique_ptr<ProofSource::Details> details) { | 172 std::unique_ptr<ProofSource::Details> details) { |
| 176 const CryptoHandshakeMessage& message = result->client_hello; | 173 const CryptoHandshakeMessage& message = result->client_hello; |
| 177 | 174 |
| 178 // Clear the callback that got us here. | 175 // Clear the callback that got us here. |
| 179 DCHECK(validate_client_hello_cb_ != nullptr); | 176 DCHECK(validate_client_hello_cb_ != nullptr); |
| 177 DCHECK(process_client_hello_cb_ == nullptr); |
| 180 validate_client_hello_cb_ = nullptr; | 178 validate_client_hello_cb_ = nullptr; |
| 181 | 179 |
| 182 if (use_stateless_rejects_if_peer_supported_) { | 180 if (use_stateless_rejects_if_peer_supported_) { |
| 183 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message); | 181 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message); |
| 184 } | 182 } |
| 185 | 183 |
| 186 std::unique_ptr<ProcessClientHelloCallback> cb( | 184 std::unique_ptr<ProcessClientHelloCallback> cb( |
| 187 new ProcessClientHelloCallback(this, result)); | 185 new ProcessClientHelloCallback(this, result)); |
| 188 process_client_hello_cb_ = cb.get(); | 186 process_client_hello_cb_ = cb.get(); |
| 189 ProcessClientHello(result, std::move(details), std::move(cb)); | 187 ProcessClientHello(result, std::move(details), std::move(cb)); |
| 190 } | 188 } |
| 191 | 189 |
| 192 void QuicCryptoServerStream:: | 190 void QuicCryptoServerStream:: |
| 193 FinishProcessingHandshakeMessageAfterProcessClientHello( | 191 FinishProcessingHandshakeMessageAfterProcessClientHello( |
| 194 const ValidateClientHelloResultCallback::Result& result, | 192 const ValidateClientHelloResultCallback::Result& result, |
| 195 QuicErrorCode error, | 193 QuicErrorCode error, |
| 196 const string& error_details, | 194 const string& error_details, |
| 197 std::unique_ptr<CryptoHandshakeMessage> reply, | 195 std::unique_ptr<CryptoHandshakeMessage> reply, |
| 198 std::unique_ptr<DiversificationNonce> diversification_nonce, | 196 std::unique_ptr<DiversificationNonce> diversification_nonce, |
| 199 std::unique_ptr<ProofSource::Details> proof_source_details) { | 197 std::unique_ptr<ProofSource::Details> proof_source_details) { |
| 198 // Clear the callback that got us here. |
| 199 DCHECK(process_client_hello_cb_ != nullptr); |
| 200 DCHECK(validate_client_hello_cb_ == nullptr); |
| 201 process_client_hello_cb_ = nullptr; |
| 202 |
| 200 const CryptoHandshakeMessage& message = result.client_hello; | 203 const CryptoHandshakeMessage& message = result.client_hello; |
| 201 if (error != QUIC_NO_ERROR) { | 204 if (error != QUIC_NO_ERROR) { |
| 202 CloseConnectionWithDetails(error, error_details); | 205 CloseConnectionWithDetails(error, error_details); |
| 203 return; | 206 return; |
| 204 } | 207 } |
| 205 | 208 |
| 206 if (reply->tag() != kSHLO) { | 209 if (reply->tag() != kSHLO) { |
| 207 if (reply->tag() == kSREJ) { | 210 if (reply->tag() == kSREJ) { |
| 208 DCHECK(use_stateless_rejects_if_peer_supported_); | 211 DCHECK(use_stateless_rejects_if_peer_supported_); |
| 209 DCHECK(peer_supports_stateless_rejects_); | 212 DCHECK(peer_supports_stateless_rejects_); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject( | 464 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject( |
| 462 bool use_stateless_rejects) { | 465 bool use_stateless_rejects) { |
| 463 if (!use_stateless_rejects) { | 466 if (!use_stateless_rejects) { |
| 464 return 0; | 467 return 0; |
| 465 } | 468 } |
| 466 return helper_->GenerateConnectionIdForReject( | 469 return helper_->GenerateConnectionIdForReject( |
| 467 session()->connection()->connection_id()); | 470 session()->connection()->connection_id()); |
| 468 } | 471 } |
| 469 | 472 |
| 470 } // namespace net | 473 } // namespace net |
| OLD | NEW |