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

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

Issue 427313002: Persist the server config that is received via kSCUP. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added histogram and minor cleanup per comments Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_crypto_client_stream.h ('k') | tools/metrics/histograms/histograms.xml » ('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_client_stream.h" 5 #include "net/quic/quic_crypto_client_stream.h"
6 6
7 #include "base/metrics/histogram.h"
7 #include "net/quic/crypto/crypto_protocol.h" 8 #include "net/quic/crypto/crypto_protocol.h"
8 #include "net/quic/crypto/crypto_utils.h" 9 #include "net/quic/crypto/crypto_utils.h"
9 #include "net/quic/crypto/null_encrypter.h" 10 #include "net/quic/crypto/null_encrypter.h"
10 #include "net/quic/quic_client_session_base.h" 11 #include "net/quic/quic_client_session_base.h"
11 #include "net/quic/quic_protocol.h" 12 #include "net/quic/quic_protocol.h"
12 #include "net/quic/quic_session.h" 13 #include "net/quic/quic_session.h"
13 14
14 namespace net { 15 namespace net {
15 16
16 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: 17 QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 session()->connection()->clock()->WallNow(), 150 session()->connection()->clock()->WallNow(),
150 cached, 151 cached,
151 &crypto_negotiated_params_, 152 &crypto_negotiated_params_,
152 &error_details); 153 &error_details);
153 154
154 if (error != QUIC_NO_ERROR) { 155 if (error != QUIC_NO_ERROR) {
155 CloseConnectionWithDetails( 156 CloseConnectionWithDetails(
156 error, "Server config update invalid: " + error_details); 157 error, "Server config update invalid: " + error_details);
157 return; 158 return;
158 } 159 }
160
161 DCHECK(handshake_confirmed());
162 if (proof_verify_callback_) {
163 proof_verify_callback_->Cancel();
164 }
165 next_state_ = STATE_INITIALIZE_SCUP;
166 DoHandshakeLoop(NULL);
159 } 167 }
160 168
161 // kMaxClientHellos is the maximum number of times that we'll send a client 169 // kMaxClientHellos is the maximum number of times that we'll send a client
162 // hello. The value 3 accounts for: 170 // hello. The value 3 accounts for:
163 // * One failure due to an incorrect or missing source-address token. 171 // * One failure due to an incorrect or missing source-address token.
164 // * One failure due the server's certificate chain being unavailible and the 172 // * One failure due the server's certificate chain being unavailible and the
165 // server being unwilling to send it without a valid source-address token. 173 // server being unwilling to send it without a valid source-address token.
166 static const int kMaxClientHellos = 3; 174 static const int kMaxClientHellos = 3;
167 175
168 void QuicCryptoClientStream::DoHandshakeLoop( 176 void QuicCryptoClientStream::DoHandshakeLoop(
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 // just added the server config to the cache and verified the proof, 309 // just added the server config to the cache and verified the proof,
302 // so we can assume no CA trust changes or certificate expiration 310 // so we can assume no CA trust changes or certificate expiration
303 // has happened since then. 311 // has happened since then.
304 next_state_ = STATE_VERIFY_PROOF; 312 next_state_ = STATE_VERIFY_PROOF;
305 break; 313 break;
306 } 314 }
307 } 315 }
308 next_state_ = STATE_GET_CHANNEL_ID; 316 next_state_ = STATE_GET_CHANNEL_ID;
309 break; 317 break;
310 case STATE_VERIFY_PROOF: { 318 case STATE_VERIFY_PROOF: {
311 ProofVerifier* verifier = crypto_config_->proof_verifier(); 319 DCHECK(!handshake_confirmed());
312 DCHECK(verifier); 320 if (QUIC_PENDING == DoVerifyProof(cached)) {
313 next_state_ = STATE_VERIFY_PROOF_COMPLETE; 321 return;
314 generation_counter_ = cached->generation_counter();
315
316 ProofVerifierCallbackImpl* proof_verify_callback =
317 new ProofVerifierCallbackImpl(this);
318
319 verify_ok_ = false;
320
321 QuicAsyncStatus status = verifier->VerifyProof(
322 server_id_.host(),
323 cached->server_config(),
324 cached->certs(),
325 cached->signature(),
326 verify_context_.get(),
327 &verify_error_details_,
328 &verify_details_,
329 proof_verify_callback);
330
331 switch (status) {
332 case QUIC_PENDING:
333 proof_verify_callback_ = proof_verify_callback;
334 DVLOG(1) << "Doing VerifyProof";
335 return;
336 case QUIC_FAILURE:
337 delete proof_verify_callback;
338 break;
339 case QUIC_SUCCESS:
340 delete proof_verify_callback;
341 verify_ok_ = true;
342 break;
343 } 322 }
344 break; 323 break;
345 } 324 }
346 case STATE_VERIFY_PROOF_COMPLETE: 325 case STATE_VERIFY_PROOF_COMPLETE:
347 if (!verify_ok_) { 326 DCHECK(!handshake_confirmed());
348 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); 327 if (QUIC_PROOF_INVALID == DoVerifyProofComplete(cached)) {
349 CloseConnectionWithDetails(
350 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
351 return; 328 return;
352 } 329 }
353 // Check if generation_counter has changed between STATE_VERIFY_PROOF
354 // and STATE_VERIFY_PROOF_COMPLETE state changes.
355 if (generation_counter_ != cached->generation_counter()) {
356 next_state_ = STATE_VERIFY_PROOF;
357 } else {
358 SetCachedProofValid(cached);
359 cached->SetProofVerifyDetails(verify_details_.release());
360 next_state_ = STATE_GET_CHANNEL_ID;
361 }
362 break; 330 break;
363 case STATE_GET_CHANNEL_ID: { 331 case STATE_GET_CHANNEL_ID: {
364 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE; 332 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
365 channel_id_key_.reset(); 333 channel_id_key_.reset();
366 if (!RequiresChannelID(cached)) { 334 if (!RequiresChannelID(cached)) {
367 next_state_ = STATE_SEND_CHLO; 335 next_state_ = STATE_SEND_CHLO;
368 break; 336 break;
369 } 337 }
370 338
371 ChannelIDSourceCallbackImpl* channel_id_source_callback = 339 ChannelIDSourceCallbackImpl* channel_id_source_callback =
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 432
465 handshake_confirmed_ = true; 433 handshake_confirmed_ = true;
466 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 434 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
467 session()->connection()->OnHandshakeComplete(); 435 session()->connection()->OnHandshakeComplete();
468 return; 436 return;
469 } 437 }
470 case STATE_IDLE: 438 case STATE_IDLE:
471 // This means that the peer sent us a message that we weren't expecting. 439 // This means that the peer sent us a message that we weren't expecting.
472 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 440 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
473 return; 441 return;
442 case STATE_INITIALIZE_SCUP: {
443 if (!server_id_.is_https()) {
444 // We don't check the certificates for insecure QUIC connections.
445 SetCachedProofValid(cached);
446 } else {
447 if (!cached->IsEmpty() && !cached->signature().empty()) {
448 // Note that we verify the proof even if the cached proof is valid.
449 DCHECK(crypto_config_->proof_verifier());
450 next_state_ = STATE_VERIFY_PROOF_SCUP;
451 }
452 }
453 break;
454 }
455 case STATE_VERIFY_PROOF_SCUP: {
456 DCHECK(handshake_confirmed());
457 if (QUIC_PENDING == DoVerifyProof(cached)) {
458 return;
459 }
460 break;
461 }
462 case STATE_VERIFY_PROOF_COMPLETE_SCUP: {
463 DCHECK(handshake_confirmed());
464 if (QUIC_PROOF_INVALID == DoVerifyProofComplete(cached)) {
465 return;
466 }
467 break;
Ryan Hamilton 2014/09/17 15:52:41 Since the implementation of these two states are b
ramant (doing other things) 2014/09/17 22:13:04 Done.
468 }
469 case STATE_VERIFY_PROOF_DONE: {
470 return; // We are done.
471 }
474 } 472 }
475 } 473 }
476 } 474 }
477 475
476 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
477 QuicCryptoClientConfig::CachedState* cached) {
478 ProofVerifier* verifier = crypto_config_->proof_verifier();
479 DCHECK(verifier);
480 if (handshake_confirmed()) {
481 next_state_ = STATE_VERIFY_PROOF_COMPLETE_SCUP;
482 } else {
483 next_state_ = STATE_VERIFY_PROOF_COMPLETE;
484 }
485 generation_counter_ = cached->generation_counter();
486
487 ProofVerifierCallbackImpl* proof_verify_callback =
488 new ProofVerifierCallbackImpl(this);
489
490 verify_ok_ = false;
491
492 QuicAsyncStatus status = verifier->VerifyProof(
493 server_id_.host(),
494 cached->server_config(),
495 cached->certs(),
496 cached->signature(),
497 verify_context_.get(),
498 &verify_error_details_,
499 &verify_details_,
500 proof_verify_callback);
501
502 switch (status) {
503 case QUIC_PENDING:
504 proof_verify_callback_ = proof_verify_callback;
505 DVLOG(1) << "Doing VerifyProof";
506 break;
507 case QUIC_FAILURE:
508 delete proof_verify_callback;
509 break;
510 case QUIC_SUCCESS:
511 delete proof_verify_callback;
512 verify_ok_ = true;
513 break;
514 }
515 return status;
516 }
517
518 QuicErrorCode QuicCryptoClientStream::DoVerifyProofComplete(
519 QuicCryptoClientConfig::CachedState* cached) {
520 if (!verify_ok_) {
521 client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
522 UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
523 handshake_confirmed());
524 CloseConnectionWithDetails(
525 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
526 return QUIC_PROOF_INVALID;
527 }
528
529 // Check if generation_counter has changed between STATE_VERIFY_PROOF (or
530 // STATE_VERIFY_PROOF_SCUP) and STATE_VERIFY_PROOF_COMPLETE (or
531 // STATE_VERIFY_PROOF_COMPLETE_SCUP) state changes.
532 if (generation_counter_ != cached->generation_counter()) {
533 if (handshake_confirmed()) {
534 next_state_ = STATE_VERIFY_PROOF_SCUP;
535 } else {
536 next_state_ = STATE_VERIFY_PROOF;
537 }
538 } else {
539 SetCachedProofValid(cached);
540 cached->SetProofVerifyDetails(verify_details_.release());
541 if (!handshake_confirmed()) {
542 next_state_ = STATE_GET_CHANNEL_ID;
543 } else {
544 next_state_ = STATE_VERIFY_PROOF_DONE;
545 }
546 }
547 return QUIC_NO_ERROR;
548 }
549
478 void QuicCryptoClientStream::SetCachedProofValid( 550 void QuicCryptoClientStream::SetCachedProofValid(
479 QuicCryptoClientConfig::CachedState* cached) { 551 QuicCryptoClientConfig::CachedState* cached) {
480 cached->SetProofValid(); 552 cached->SetProofValid();
481 client_session()->OnProofValid(*cached); 553 client_session()->OnProofValid(*cached);
482 } 554 }
483 555
484 bool QuicCryptoClientStream::RequiresChannelID( 556 bool QuicCryptoClientStream::RequiresChannelID(
485 QuicCryptoClientConfig::CachedState* cached) { 557 QuicCryptoClientConfig::CachedState* cached) {
486 if (!server_id_.is_https() || 558 if (!server_id_.is_https() ||
487 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED || 559 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
(...skipping 16 matching lines...) Expand all
504 } 576 }
505 } 577 }
506 return false; 578 return false;
507 } 579 }
508 580
509 QuicClientSessionBase* QuicCryptoClientStream::client_session() { 581 QuicClientSessionBase* QuicCryptoClientStream::client_session() {
510 return reinterpret_cast<QuicClientSessionBase*>(session()); 582 return reinterpret_cast<QuicClientSessionBase*>(session());
511 } 583 }
512 584
513 } // namespace net 585 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_crypto_client_stream.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698