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

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

Issue 2397513002: Conversion of a QUIC method to an async signature and resulting fallout. No functional change inten… (Closed)
Patch Set: Add NET_EXPORT_PRIVATE Created 4 years, 2 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
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/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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 const CryptoHandshakeMessage& message = result->client_hello; 129 const CryptoHandshakeMessage& message = result->client_hello;
130 130
131 // Clear the callback that got us here. 131 // Clear the callback that got us here.
132 DCHECK(validate_client_hello_cb_ != nullptr); 132 DCHECK(validate_client_hello_cb_ != nullptr);
133 validate_client_hello_cb_ = nullptr; 133 validate_client_hello_cb_ = nullptr;
134 134
135 if (use_stateless_rejects_if_peer_supported_) { 135 if (use_stateless_rejects_if_peer_supported_) {
136 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message); 136 peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message);
137 } 137 }
138 138
139 CryptoHandshakeMessage reply;
140 DiversificationNonce diversification_nonce;
141 string error_details; 139 string error_details;
140 std::unique_ptr<CryptoHandshakeMessage> reply(new CryptoHandshakeMessage);
141 std::unique_ptr<DiversificationNonce> diversification_nonce(
142 new DiversificationNonce);
142 QuicErrorCode error = 143 QuicErrorCode error =
143 ProcessClientHello(result, std::move(details), &reply, 144 ProcessClientHello(result, std::move(details), reply.get(),
144 &diversification_nonce, &error_details); 145 diversification_nonce.get(), &error_details);
145 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 }
153
154 void QuicCryptoServerStream::
155 FinishProcessingHandshakeMessageAfterProcessClientHello(
156 const ValidateClientHelloResultCallback::Result& result,
157 QuicErrorCode error,
158 const string& error_details,
159 std::unique_ptr<CryptoHandshakeMessage> reply,
160 std::unique_ptr<DiversificationNonce> diversification_nonce) {
161 const CryptoHandshakeMessage& message = result.client_hello;
146 if (error != QUIC_NO_ERROR) { 162 if (error != QUIC_NO_ERROR) {
147 CloseConnectionWithDetails(error, error_details); 163 CloseConnectionWithDetails(error, error_details);
148 return; 164 return;
149 } 165 }
150 166
151 if (reply.tag() != kSHLO) { 167 if (reply->tag() != kSHLO) {
152 if (reply.tag() == kSREJ) { 168 if (reply->tag() == kSREJ) {
153 DCHECK(use_stateless_rejects_if_peer_supported_); 169 DCHECK(use_stateless_rejects_if_peer_supported_);
154 DCHECK(peer_supports_stateless_rejects_); 170 DCHECK(peer_supports_stateless_rejects_);
155 // Before sending the SREJ, cause the connection to save crypto packets 171 // Before sending the SREJ, cause the connection to save crypto packets
156 // so that they can be added to the time wait list manager and 172 // so that they can be added to the time wait list manager and
157 // retransmitted. 173 // retransmitted.
158 session()->connection()->EnableSavingCryptoPackets(); 174 session()->connection()->EnableSavingCryptoPackets();
159 } 175 }
160 SendHandshakeMessage(reply); 176 SendHandshakeMessage(*reply);
161 177
162 if (reply.tag() == kSREJ) { 178 if (reply->tag() == kSREJ) {
163 DCHECK(use_stateless_rejects_if_peer_supported_); 179 DCHECK(use_stateless_rejects_if_peer_supported_);
164 DCHECK(peer_supports_stateless_rejects_); 180 DCHECK(peer_supports_stateless_rejects_);
165 DCHECK(!handshake_confirmed()); 181 DCHECK(!handshake_confirmed());
166 DVLOG(1) << "Closing connection " 182 DVLOG(1) << "Closing connection "
167 << session()->connection()->connection_id() 183 << session()->connection()->connection_id()
168 << " because of a stateless reject."; 184 << " because of a stateless reject.";
169 session()->connection()->CloseConnection( 185 session()->connection()->CloseConnection(
170 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject", 186 QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject",
171 ConnectionCloseBehavior::SILENT_CLOSE); 187 ConnectionCloseBehavior::SILENT_CLOSE);
172 } 188 }
173 return; 189 return;
174 } 190 }
175 191
176 // If we are returning a SHLO then we accepted the handshake. Now 192 // If we are returning a SHLO then we accepted the handshake. Now
177 // process the negotiated configuration options as part of the 193 // process the negotiated configuration options as part of the
178 // session config. 194 // session config.
179 QuicConfig* config = session()->config(); 195 QuicConfig* config = session()->config();
180 OverrideQuicConfigDefaults(config); 196 OverrideQuicConfigDefaults(config);
181 error = config->ProcessPeerHello(message, CLIENT, &error_details); 197 string process_error_details;
182 if (error != QUIC_NO_ERROR) { 198 const QuicErrorCode process_error =
183 CloseConnectionWithDetails(error, error_details); 199 config->ProcessPeerHello(message, CLIENT, &process_error_details);
200 if (process_error != QUIC_NO_ERROR) {
201 CloseConnectionWithDetails(process_error, process_error_details);
184 return; 202 return;
185 } 203 }
186 204
187 session()->OnConfigNegotiated(); 205 session()->OnConfigNegotiated();
188 206
189 config->ToHandshakeMessage(&reply); 207 config->ToHandshakeMessage(reply.get());
190 208
191 // Receiving a full CHLO implies the client is prepared to decrypt with 209 // Receiving a full CHLO implies the client is prepared to decrypt with
192 // the new server write key. We can start to encrypt with the new server 210 // the new server write key. We can start to encrypt with the new server
193 // write key. 211 // write key.
194 // 212 //
195 // NOTE: the SHLO will be encrypted with the new server write key. 213 // NOTE: the SHLO will be encrypted with the new server write key.
196 session()->connection()->SetEncrypter( 214 session()->connection()->SetEncrypter(
197 ENCRYPTION_INITIAL, 215 ENCRYPTION_INITIAL,
198 crypto_negotiated_params_.initial_crypters.encrypter.release()); 216 crypto_negotiated_params_.initial_crypters.encrypter.release());
199 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); 217 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
200 // Set the decrypter immediately so that we no longer accept unencrypted 218 // Set the decrypter immediately so that we no longer accept unencrypted
201 // packets. 219 // packets.
202 session()->connection()->SetDecrypter( 220 session()->connection()->SetDecrypter(
203 ENCRYPTION_INITIAL, 221 ENCRYPTION_INITIAL,
204 crypto_negotiated_params_.initial_crypters.decrypter.release()); 222 crypto_negotiated_params_.initial_crypters.decrypter.release());
205 if (version() > QUIC_VERSION_32) { 223 if (version() > QUIC_VERSION_32) {
206 session()->connection()->SetDiversificationNonce(diversification_nonce); 224 session()->connection()->SetDiversificationNonce(*diversification_nonce);
207 } 225 }
208 226
209 SendHandshakeMessage(reply); 227 SendHandshakeMessage(*reply);
210 228
211 session()->connection()->SetEncrypter( 229 session()->connection()->SetEncrypter(
212 ENCRYPTION_FORWARD_SECURE, 230 ENCRYPTION_FORWARD_SECURE,
213 crypto_negotiated_params_.forward_secure_crypters.encrypter.release()); 231 crypto_negotiated_params_.forward_secure_crypters.encrypter.release());
214 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE); 232 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
215 233
216 session()->connection()->SetAlternativeDecrypter( 234 session()->connection()->SetAlternativeDecrypter(
217 ENCRYPTION_FORWARD_SECURE, 235 ENCRYPTION_FORWARD_SECURE,
218 crypto_negotiated_params_.forward_secure_crypters.decrypter.release(), 236 crypto_negotiated_params_.forward_secure_crypters.decrypter.release(),
219 false /* don't latch */); 237 false /* don't latch */);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 len--; 390 len--;
373 if ((*output)[len - 1] == '=') { 391 if ((*output)[len - 1] == '=') {
374 len--; 392 len--;
375 } 393 }
376 output->resize(len); 394 output->resize(len);
377 } 395 }
378 } 396 }
379 return true; 397 return true;
380 } 398 }
381 399
400 class QuicCryptoServerStream::ProcessClientHelloCallback
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
382 QuicErrorCode QuicCryptoServerStream::ProcessClientHello( 437 QuicErrorCode QuicCryptoServerStream::ProcessClientHello(
383 scoped_refptr<ValidateClientHelloResultCallback::Result> result, 438 scoped_refptr<ValidateClientHelloResultCallback::Result> result,
384 std::unique_ptr<ProofSource::Details> proof_source_details, 439 std::unique_ptr<ProofSource::Details> proof_source_details,
385 CryptoHandshakeMessage* reply, 440 CryptoHandshakeMessage* reply,
386 DiversificationNonce* out_diversification_nonce, 441 DiversificationNonce* out_diversification_nonce,
387 string* error_details) { 442 string* error_details) {
388 const CryptoHandshakeMessage& message = result->client_hello; 443 const CryptoHandshakeMessage& message = result->client_hello;
389 if (!helper_->CanAcceptClientHello( 444 if (!helper_->CanAcceptClientHello(
390 message, session()->connection()->self_address(), error_details)) { 445 message, session()->connection()->self_address(), error_details)) {
391 return QUIC_HANDSHAKE_FAILED; 446 return QUIC_HANDSHAKE_FAILED;
392 } 447 }
393 448
394 if (!result->info.server_nonce.empty()) { 449 if (!result->info.server_nonce.empty()) {
395 ++num_handshake_messages_with_server_nonces_; 450 ++num_handshake_messages_with_server_nonces_;
396 } 451 }
397 // Store the bandwidth estimate from the client. 452 // Store the bandwidth estimate from the client.
398 if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) { 453 if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
399 previous_cached_network_params_.reset( 454 previous_cached_network_params_.reset(
400 new CachedNetworkParameters(result->cached_network_params)); 455 new CachedNetworkParameters(result->cached_network_params));
401 } 456 }
402 previous_source_address_tokens_ = result->info.source_address_tokens; 457 previous_source_address_tokens_ = result->info.source_address_tokens;
403 458
404 const bool use_stateless_rejects_in_crypto_config = 459 const bool use_stateless_rejects_in_crypto_config =
405 use_stateless_rejects_if_peer_supported_ && 460 use_stateless_rejects_if_peer_supported_ &&
406 peer_supports_stateless_rejects_; 461 peer_supports_stateless_rejects_;
407 QuicConnection* connection = session()->connection(); 462 QuicConnection* connection = session()->connection();
408 const QuicConnectionId server_designated_connection_id = 463 const QuicConnectionId server_designated_connection_id =
409 GenerateConnectionIdForReject(use_stateless_rejects_in_crypto_config); 464 GenerateConnectionIdForReject(use_stateless_rejects_in_crypto_config);
410 return crypto_config_->ProcessClientHello( 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(
411 result, /*reject_only=*/false, connection->connection_id(), 470 result, /*reject_only=*/false, connection->connection_id(),
412 connection->self_address().address(), connection->peer_address(), 471 connection->self_address().address(), connection->peer_address(),
413 version(), connection->supported_versions(), 472 version(), connection->supported_versions(),
414 use_stateless_rejects_in_crypto_config, server_designated_connection_id, 473 use_stateless_rejects_in_crypto_config, server_designated_connection_id,
415 connection->clock(), connection->random_generator(), 474 connection->clock(), connection->random_generator(),
416 compressed_certs_cache_, &crypto_negotiated_params_, &crypto_proof_, 475 compressed_certs_cache_, &crypto_negotiated_params_, &crypto_proof_,
417 QuicCryptoStream::CryptoMessageFramingOverhead(version()), 476 QuicCryptoStream::CryptoMessageFramingOverhead(version()),
418 chlo_packet_size_, reply, out_diversification_nonce, error_details); 477 chlo_packet_size_, std::move(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;
419 } 484 }
420 485
421 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {} 486 void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {}
422 487
423 QuicCryptoServerStream::ValidateCallback::ValidateCallback( 488 QuicCryptoServerStream::ValidateCallback::ValidateCallback(
424 QuicCryptoServerStream* parent) 489 QuicCryptoServerStream* parent)
425 : parent_(parent) {} 490 : parent_(parent) {}
426 491
427 void QuicCryptoServerStream::ValidateCallback::Cancel() { 492 void QuicCryptoServerStream::ValidateCallback::Cancel() {
428 parent_ = nullptr; 493 parent_ = nullptr;
(...skipping 11 matching lines...) Expand all
440 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject( 505 QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject(
441 bool use_stateless_rejects) { 506 bool use_stateless_rejects) {
442 if (!use_stateless_rejects) { 507 if (!use_stateless_rejects) {
443 return 0; 508 return 0;
444 } 509 }
445 return helper_->GenerateConnectionIdForReject( 510 return helper_->GenerateConnectionIdForReject(
446 session()->connection()->connection_id()); 511 session()->connection()->connection_id());
447 } 512 }
448 513
449 } // namespace net 514 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/quic_crypto_server_stream.h ('k') | net/quic/core/quic_crypto_server_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698