Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: net/quic/quic_crypto_server_stream.cc

Issue 1139183002: Flag-protected. Add stateless reject support to crypto streams. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@QuicCryptoClientConfig_ProcessRejection_92637704
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_crypto_server_stream.h ('k') | net/quic/quic_crypto_server_stream_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/quic_crypto_server_stream.h" 5 #include "net/quic/quic_crypto_server_stream.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "crypto/secure_hash.h" 8 #include "crypto/secure_hash.h"
9 #include "net/quic/crypto/crypto_protocol.h" 9 #include "net/quic/crypto/crypto_protocol.h"
10 #include "net/quic/crypto/crypto_utils.h" 10 #include "net/quic/crypto/crypto_utils.h"
11 #include "net/quic/crypto/quic_crypto_server_config.h" 11 #include "net/quic/crypto/quic_crypto_server_config.h"
12 #include "net/quic/crypto/quic_random.h"
12 #include "net/quic/proto/cached_network_parameters.pb.h" 13 #include "net/quic/proto/cached_network_parameters.pb.h"
13 #include "net/quic/quic_config.h" 14 #include "net/quic/quic_config.h"
15 #include "net/quic/quic_flags.h"
14 #include "net/quic/quic_protocol.h" 16 #include "net/quic/quic_protocol.h"
15 #include "net/quic/quic_session.h" 17 #include "net/quic/quic_session.h"
16 18
17 using std::string; 19 using std::string;
18 20
19 namespace net { 21 namespace net {
20 22
21 void ServerHelloNotifier::OnAckNotification( 23 void ServerHelloNotifier::OnAckNotification(
22 int num_retransmitted_packets, 24 int num_retransmitted_packets,
23 int num_retransmitted_bytes, 25 int num_retransmitted_bytes,
24 QuicTime::Delta delta_largest_observed) { 26 QuicTime::Delta delta_largest_observed) {
25 server_stream_->OnServerHelloAcked(); 27 server_stream_->OnServerHelloAcked();
26 } 28 }
27 29
28 QuicCryptoServerStream::QuicCryptoServerStream( 30 QuicCryptoServerStream::QuicCryptoServerStream(
29 const QuicCryptoServerConfig* crypto_config, 31 const QuicCryptoServerConfig* crypto_config,
30 QuicSession* session) 32 QuicSession* session)
31 : QuicCryptoStream(session), 33 : QuicCryptoStream(session),
32 crypto_config_(crypto_config), 34 crypto_config_(crypto_config),
33 validate_client_hello_cb_(nullptr), 35 validate_client_hello_cb_(nullptr),
34 num_handshake_messages_(0), 36 num_handshake_messages_(0),
35 num_server_config_update_messages_sent_(0) { 37 num_server_config_update_messages_sent_(0),
38 use_stateless_rejects_if_peer_supported_(false),
39 peer_supports_stateless_rejects_(false) {
36 DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective()); 40 DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
37 } 41 }
38 42
39 QuicCryptoServerStream::~QuicCryptoServerStream() { 43 QuicCryptoServerStream::~QuicCryptoServerStream() {
40 CancelOutstandingCallbacks(); 44 CancelOutstandingCallbacks();
41 } 45 }
42 46
43 void QuicCryptoServerStream::CancelOutstandingCallbacks() { 47 void QuicCryptoServerStream::CancelOutstandingCallbacks() {
44 // Detach from the validation callback. Calling this multiple times is safe. 48 // Detach from the validation callback. Calling this multiple times is safe.
45 if (validate_client_hello_cb_ != nullptr) { 49 if (validate_client_hello_cb_ != nullptr) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 session()->connection()->clock(), validate_client_hello_cb_); 81 session()->connection()->clock(), validate_client_hello_cb_);
78 } 82 }
79 83
80 void QuicCryptoServerStream::FinishProcessingHandshakeMessage( 84 void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
81 const CryptoHandshakeMessage& message, 85 const CryptoHandshakeMessage& message,
82 const ValidateClientHelloResultCallback::Result& result) { 86 const ValidateClientHelloResultCallback::Result& result) {
83 // Clear the callback that got us here. 87 // Clear the callback that got us here.
84 DCHECK(validate_client_hello_cb_ != nullptr); 88 DCHECK(validate_client_hello_cb_ != nullptr);
85 validate_client_hello_cb_ = nullptr; 89 validate_client_hello_cb_ = nullptr;
86 90
91 if (FLAGS_enable_quic_stateless_reject_support) {
92 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message);
93 }
94
95 CryptoHandshakeMessage reply;
87 string error_details; 96 string error_details;
88 CryptoHandshakeMessage reply; 97 QuicErrorCode error =
89 QuicErrorCode error = ProcessClientHello( 98 ProcessClientHello(message, result, &reply, &error_details);
90 message, result, &reply, &error_details);
91 99
92 if (error != QUIC_NO_ERROR) { 100 if (error != QUIC_NO_ERROR) {
93 CloseConnectionWithDetails(error, error_details); 101 CloseConnectionWithDetails(error, error_details);
94 return; 102 return;
95 } 103 }
96 104
97 if (reply.tag() != kSHLO) { 105 if (reply.tag() != kSHLO) {
98 SendHandshakeMessage(reply); 106 SendHandshakeMessage(reply);
99 return; 107 return;
100 } 108 }
101 109
102 // If we are returning a SHLO then we accepted the handshake. 110 // If we are returning a SHLO then we accepted the handshake. Now
111 // process the negotiated configuration options as part of the
112 // session config.
103 QuicConfig* config = session()->config(); 113 QuicConfig* config = session()->config();
104 OverrideQuicConfigDefaults(config); 114 OverrideQuicConfigDefaults(config);
105 error = config->ProcessPeerHello(message, CLIENT, &error_details); 115 error = config->ProcessPeerHello(message, CLIENT, &error_details);
106 if (error != QUIC_NO_ERROR) { 116 if (error != QUIC_NO_ERROR) {
107 CloseConnectionWithDetails(error, error_details); 117 CloseConnectionWithDetails(error, error_details);
108 return; 118 return;
109 } 119 }
120
110 session()->OnConfigNegotiated(); 121 session()->OnConfigNegotiated();
111 122
112 config->ToHandshakeMessage(&reply); 123 config->ToHandshakeMessage(&reply);
113 124
114 // Receiving a full CHLO implies the client is prepared to decrypt with 125 // Receiving a full CHLO implies the client is prepared to decrypt with
115 // the new server write key. We can start to encrypt with the new server 126 // the new server write key. We can start to encrypt with the new server
116 // write key. 127 // write key.
117 // 128 //
118 // NOTE: the SHLO will be encrypted with the new server write key. 129 // NOTE: the SHLO will be encrypted with the new server write key.
119 session()->connection()->SetEncrypter( 130 session()->connection()->SetEncrypter(
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 const ValidateClientHelloResultCallback::Result& result, 227 const ValidateClientHelloResultCallback::Result& result,
217 CryptoHandshakeMessage* reply, 228 CryptoHandshakeMessage* reply,
218 string* error_details) { 229 string* error_details) {
219 // Store the bandwidth estimate from the client. 230 // Store the bandwidth estimate from the client.
220 if (result.cached_network_params.bandwidth_estimate_bytes_per_second() > 0) { 231 if (result.cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
221 previous_cached_network_params_.reset( 232 previous_cached_network_params_.reset(
222 new CachedNetworkParameters(result.cached_network_params)); 233 new CachedNetworkParameters(result.cached_network_params));
223 } 234 }
224 previous_source_address_tokens_ = result.info.source_address_tokens; 235 previous_source_address_tokens_ = result.info.source_address_tokens;
225 236
237 const bool use_stateless_rejects_in_crypto_config =
238 FLAGS_enable_quic_stateless_reject_support &&
239 use_stateless_rejects_if_peer_supported_ &&
240 peer_supports_stateless_rejects_;
226 QuicConnection* connection = session()->connection(); 241 QuicConnection* connection = session()->connection();
242 const QuicConnectionId server_designated_connection_id =
243 use_stateless_rejects_in_crypto_config
244 ? GenerateConnectionIdForReject(connection->connection_id())
245 : 0;
227 return crypto_config_->ProcessClientHello( 246 return crypto_config_->ProcessClientHello(
228 result, connection->connection_id(), connection->self_address().address(), 247 result, connection->connection_id(), connection->self_address().address(),
229 connection->peer_address(), version(), connection->supported_versions(), 248 connection->peer_address(), version(), connection->supported_versions(),
230 /* use_stateless_rejects= */ false, 249 use_stateless_rejects_in_crypto_config, server_designated_connection_id,
231 /* server_designated_connection_id= */ 0, connection->clock(), 250 connection->clock(), connection->random_generator(),
232 connection->random_generator(), &crypto_negotiated_params_, reply, 251 &crypto_negotiated_params_, reply, error_details);
233 error_details);
234 } 252 }
235 253
236 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) { 254 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {
237 } 255 }
238 256
239 const CachedNetworkParameters* 257 const CachedNetworkParameters*
240 QuicCryptoServerStream::previous_cached_network_params() const { 258 QuicCryptoServerStream::previous_cached_network_params() const {
241 return previous_cached_network_params_.get(); 259 return previous_cached_network_params_.get();
242 } 260 }
243 261
244 QuicCryptoServerStream::ValidateCallback::ValidateCallback( 262 QuicCryptoServerStream::ValidateCallback::ValidateCallback(
245 QuicCryptoServerStream* parent) : parent_(parent) { 263 QuicCryptoServerStream* parent) : parent_(parent) {
246 } 264 }
247 265
248 void QuicCryptoServerStream::ValidateCallback::Cancel() { parent_ = nullptr; } 266 void QuicCryptoServerStream::ValidateCallback::Cancel() { parent_ = nullptr; }
249 267
250 void QuicCryptoServerStream::ValidateCallback::RunImpl( 268 void QuicCryptoServerStream::ValidateCallback::RunImpl(
251 const CryptoHandshakeMessage& client_hello, 269 const CryptoHandshakeMessage& client_hello,
252 const Result& result) { 270 const Result& result) {
253 if (parent_ != nullptr) { 271 if (parent_ != nullptr) {
254 parent_->FinishProcessingHandshakeMessage(client_hello, result); 272 parent_->FinishProcessingHandshakeMessage(client_hello, result);
255 } 273 }
256 } 274 }
257 275
276 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject(
277 QuicConnectionId connection_id) {
278 return session()->connection()->random_generator()->RandUint64();
279 }
280
281 // TODO(jokulik): Once stateless rejects support is inherent in the version
282 // number, this function will likely go away entirely.
283 // static
284 bool QuicCryptoServerStream::DoesPeerSupportStatelessRejects(
285 const CryptoHandshakeMessage& message) {
286 const QuicTag* received_tags;
287 size_t received_tags_length;
288 QuicErrorCode error =
289 message.GetTaglist(kCOPT, &received_tags, &received_tags_length);
290 if (error != QUIC_NO_ERROR) {
291 return false;
292 }
293 for (size_t i = 0; i < received_tags_length; ++i) {
294 if (received_tags[i] == kSREJ) {
295 return true;
296 }
297 }
298 return false;
299 }
300
258 } // namespace net 301 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_crypto_server_stream.h ('k') | net/quic/quic_crypto_server_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698