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

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: Verify proof from kSCUP message 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') | no next file » | 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 "net/quic/crypto/crypto_protocol.h" 7 #include "net/quic/crypto/crypto_protocol.h"
8 #include "net/quic/crypto/crypto_utils.h" 8 #include "net/quic/crypto/crypto_utils.h"
9 #include "net/quic/crypto/null_encrypter.h" 9 #include "net/quic/crypto/null_encrypter.h"
10 #include "net/quic/quic_client_session_base.h" 10 #include "net/quic/quic_client_session_base.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 session()->connection()->clock()->WallNow(), 149 session()->connection()->clock()->WallNow(),
150 cached, 150 cached,
151 &crypto_negotiated_params_, 151 &crypto_negotiated_params_,
152 &error_details); 152 &error_details);
153 153
154 if (error != QUIC_NO_ERROR) { 154 if (error != QUIC_NO_ERROR) {
155 CloseConnectionWithDetails( 155 CloseConnectionWithDetails(
156 error, "Server config update invalid: " + error_details); 156 error, "Server config update invalid: " + error_details);
157 return; 157 return;
158 } 158 }
159
160 DCHECK(handshake_confirmed());
161 if (proof_verify_callback_) {
162 proof_verify_callback_->Cancel();
163 }
164 next_state_ = STATE_INITIALIZE_SCUP;
165 DoProofVeifyLoop();
159 } 166 }
160 167
161 // kMaxClientHellos is the maximum number of times that we'll send a client 168 // kMaxClientHellos is the maximum number of times that we'll send a client
162 // hello. The value 3 accounts for: 169 // hello. The value 3 accounts for:
163 // * One failure due to an incorrect or missing source-address token. 170 // * One failure due to an incorrect or missing source-address token.
164 // * One failure due the server's certificate chain being unavailible and the 171 // * 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. 172 // server being unwilling to send it without a valid source-address token.
166 static const int kMaxClientHellos = 3; 173 static const int kMaxClientHellos = 3;
167 174
168 void QuicCryptoClientStream::DoHandshakeLoop( 175 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, 308 // just added the server config to the cache and verified the proof,
302 // so we can assume no CA trust changes or certificate expiration 309 // so we can assume no CA trust changes or certificate expiration
303 // has happened since then. 310 // has happened since then.
304 next_state_ = STATE_VERIFY_PROOF; 311 next_state_ = STATE_VERIFY_PROOF;
305 break; 312 break;
306 } 313 }
307 } 314 }
308 next_state_ = STATE_GET_CHANNEL_ID; 315 next_state_ = STATE_GET_CHANNEL_ID;
309 break; 316 break;
310 case STATE_VERIFY_PROOF: { 317 case STATE_VERIFY_PROOF: {
311 ProofVerifier* verifier = crypto_config_->proof_verifier(); 318 DCHECK(!handshake_confirmed());
312 DCHECK(verifier); 319 if (QUIC_PENDING == DoVerifyProof(cached)) {
313 next_state_ = STATE_VERIFY_PROOF_COMPLETE; 320 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 } 321 }
344 break; 322 break;
345 } 323 }
346 case STATE_VERIFY_PROOF_COMPLETE: 324 case STATE_VERIFY_PROOF_COMPLETE:
347 if (!verify_ok_) { 325 DCHECK(!handshake_confirmed());
348 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); 326 if (QUIC_NO_ERROR != DoVerifyProofComplete(cached)) {
349 CloseConnectionWithDetails(
350 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
351 return; 327 return;
352 } 328 }
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; 329 break;
363 case STATE_GET_CHANNEL_ID: { 330 case STATE_GET_CHANNEL_ID: {
364 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE; 331 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
365 channel_id_key_.reset(); 332 channel_id_key_.reset();
366 if (!RequiresChannelID(cached)) { 333 if (!RequiresChannelID(cached)) {
367 next_state_ = STATE_SEND_CHLO; 334 next_state_ = STATE_SEND_CHLO;
368 break; 335 break;
369 } 336 }
370 337
371 ChannelIDSourceCallbackImpl* channel_id_source_callback = 338 ChannelIDSourceCallbackImpl* channel_id_source_callback =
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 431
465 handshake_confirmed_ = true; 432 handshake_confirmed_ = true;
466 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 433 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
467 session()->connection()->OnHandshakeComplete(); 434 session()->connection()->OnHandshakeComplete();
468 return; 435 return;
469 } 436 }
470 case STATE_IDLE: 437 case STATE_IDLE:
471 // This means that the peer sent us a message that we weren't expecting. 438 // This means that the peer sent us a message that we weren't expecting.
472 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 439 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
473 return; 440 return;
441 case STATE_INITIALIZE_SCUP:
442 case STATE_VERIFY_PROOF_SCUP:
443 case STATE_VERIFY_PROOF_COMPLETE_SCUP:
444 NOTREACHED();
445 return;
474 } 446 }
475 } 447 }
476 } 448 }
477 449
450 void QuicCryptoClientStream::DoProofVeifyLoop() {
451 QuicCryptoClientConfig::CachedState* cached =
452 crypto_config_->LookupOrCreate(server_id_);
453 for (;;) {
454 const State state = next_state_;
455 next_state_ = STATE_IDLE;
456 switch (state) {
457 case STATE_INITIALIZE_SCUP: {
458 if (!server_id_.is_https()) {
459 // We don't check the certificates for insecure QUIC connections.
460 SetCachedProofValid(cached);
461 } else {
462 if (!cached->IsEmpty() && !cached->signature().empty()) {
463 // Note that we verify the proof even if the cached proof is valid.
464 // This allows us to respond to CA trust changes or certificate
465 // expiration because it may have been a while since we last
466 // verified the proof.
467 DCHECK(crypto_config_->proof_verifier());
468 // If the cached state needs to be verified, do it now.
469 next_state_ = STATE_VERIFY_PROOF_SCUP;
470 }
471 }
472 break;
473 }
474 case STATE_VERIFY_PROOF_SCUP: {
475 if (QUIC_PENDING == DoVerifyProof(cached)) {
476 return;
477 }
478 break;
479 }
480 case STATE_VERIFY_PROOF_COMPLETE_SCUP: {
481 if (QUIC_NO_ERROR != DoVerifyProofComplete(cached)) {
482 return;
483 }
484 break;
485 }
486 case STATE_IDLE:
487 return; // We are done.
488 default:
489 NOTREACHED();
490 return;
491
492 }
493 }
494 }
495
496 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
497 QuicCryptoClientConfig::CachedState* cached) {
498 ProofVerifier* verifier = crypto_config_->proof_verifier();
499 DCHECK(verifier);
500 if (handshake_confirmed()) {
501 next_state_ = STATE_VERIFY_PROOF_COMPLETE_SCUP;
502 } else {
503 next_state_ = STATE_VERIFY_PROOF_COMPLETE;
Ryan Hamilton 2014/09/15 22:37:56 Since we have to conditionally set next_state_ in
ramant (doing other things) 2014/09/16 21:06:32 Done.
504 }
505 generation_counter_ = cached->generation_counter();
506
507 ProofVerifierCallbackImpl* proof_verify_callback =
508 new ProofVerifierCallbackImpl(this);
509
510 verify_ok_ = false;
511
512 QuicAsyncStatus status = verifier->VerifyProof(
513 server_id_.host(),
514 cached->server_config(),
515 cached->certs(),
516 cached->signature(),
517 verify_context_.get(),
518 &verify_error_details_,
519 &verify_details_,
520 proof_verify_callback);
521
522 switch (status) {
523 case QUIC_PENDING:
524 proof_verify_callback_ = proof_verify_callback;
525 DVLOG(1) << "Doing VerifyProof";
526 break;
527 case QUIC_FAILURE:
528 delete proof_verify_callback;
529 break;
530 case QUIC_SUCCESS:
531 delete proof_verify_callback;
532 verify_ok_ = true;
533 break;
534 }
535 return status;
536 }
537
538 QuicErrorCode QuicCryptoClientStream::DoVerifyProofComplete(
539 QuicCryptoClientConfig::CachedState* cached) {
540 if (!verify_ok_) {
541 client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
542 CloseConnectionWithDetails(
543 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
544 return QUIC_PROOF_INVALID;
Ryan Hamilton 2014/09/15 22:37:56 possibly add a histogram here when the handshake h
ramant (doing other things) 2014/09/16 21:06:32 Done.
545 }
546
547 // Check if generation_counter has changed between STATE_VERIFY_PROOF (or
548 // STATE_VERIFY_PROOF_SCUP) and STATE_VERIFY_PROOF_COMPLETE (or
549 // STATE_VERIFY_PROOF_COMPLETE_SCUP) state changes.
550 if (generation_counter_ != cached->generation_counter()) {
551 if (handshake_confirmed()) {
552 next_state_ = STATE_VERIFY_PROOF_SCUP;
553 } else {
554 next_state_ = STATE_VERIFY_PROOF;
555 }
556 } else {
557 SetCachedProofValid(cached);
558 cached->SetProofVerifyDetails(verify_details_.release());
559 if (!handshake_confirmed()) {
560 next_state_ = STATE_GET_CHANNEL_ID;
561 }
562 }
563 return QUIC_NO_ERROR;
564 }
565
478 void QuicCryptoClientStream::SetCachedProofValid( 566 void QuicCryptoClientStream::SetCachedProofValid(
479 QuicCryptoClientConfig::CachedState* cached) { 567 QuicCryptoClientConfig::CachedState* cached) {
480 cached->SetProofValid(); 568 cached->SetProofValid();
481 client_session()->OnProofValid(*cached); 569 client_session()->OnProofValid(*cached);
482 } 570 }
483 571
484 bool QuicCryptoClientStream::RequiresChannelID( 572 bool QuicCryptoClientStream::RequiresChannelID(
485 QuicCryptoClientConfig::CachedState* cached) { 573 QuicCryptoClientConfig::CachedState* cached) {
486 if (!server_id_.is_https() || 574 if (!server_id_.is_https() ||
487 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED || 575 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
(...skipping 16 matching lines...) Expand all
504 } 592 }
505 } 593 }
506 return false; 594 return false;
507 } 595 }
508 596
509 QuicClientSessionBase* QuicCryptoClientStream::client_session() { 597 QuicClientSessionBase* QuicCryptoClientStream::client_session() {
510 return reinterpret_cast<QuicClientSessionBase*>(session()); 598 return reinterpret_cast<QuicClientSessionBase*>(session());
511 } 599 }
512 600
513 } // namespace net 601 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_crypto_client_stream.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698