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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_crypto_client_stream.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_crypto_client_stream.cc
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc
index 40e4d45901c531d6fd711e3d1067a3b4cda7d953..94a7c14402ad8c9e98d08a1f4f9925edec9a6fc6 100644
--- a/net/quic/quic_crypto_client_stream.cc
+++ b/net/quic/quic_crypto_client_stream.cc
@@ -156,6 +156,13 @@ void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
error, "Server config update invalid: " + error_details);
return;
}
+
+ DCHECK(handshake_confirmed());
+ if (proof_verify_callback_) {
+ proof_verify_callback_->Cancel();
+ }
+ next_state_ = STATE_INITIALIZE_SCUP;
+ DoProofVeifyLoop();
}
// kMaxClientHellos is the maximum number of times that we'll send a client
@@ -308,57 +315,17 @@ void QuicCryptoClientStream::DoHandshakeLoop(
next_state_ = STATE_GET_CHANNEL_ID;
break;
case STATE_VERIFY_PROOF: {
- ProofVerifier* verifier = crypto_config_->proof_verifier();
- DCHECK(verifier);
- next_state_ = STATE_VERIFY_PROOF_COMPLETE;
- generation_counter_ = cached->generation_counter();
-
- ProofVerifierCallbackImpl* proof_verify_callback =
- new ProofVerifierCallbackImpl(this);
-
- verify_ok_ = false;
-
- QuicAsyncStatus status = verifier->VerifyProof(
- server_id_.host(),
- cached->server_config(),
- cached->certs(),
- cached->signature(),
- verify_context_.get(),
- &verify_error_details_,
- &verify_details_,
- proof_verify_callback);
-
- switch (status) {
- case QUIC_PENDING:
- proof_verify_callback_ = proof_verify_callback;
- DVLOG(1) << "Doing VerifyProof";
- return;
- case QUIC_FAILURE:
- delete proof_verify_callback;
- break;
- case QUIC_SUCCESS:
- delete proof_verify_callback;
- verify_ok_ = true;
- break;
+ DCHECK(!handshake_confirmed());
+ if (QUIC_PENDING == DoVerifyProof(cached)) {
+ return;
}
break;
}
case STATE_VERIFY_PROOF_COMPLETE:
- if (!verify_ok_) {
- client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
- CloseConnectionWithDetails(
- QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
+ DCHECK(!handshake_confirmed());
+ if (QUIC_NO_ERROR != DoVerifyProofComplete(cached)) {
return;
}
- // Check if generation_counter has changed between STATE_VERIFY_PROOF
- // and STATE_VERIFY_PROOF_COMPLETE state changes.
- if (generation_counter_ != cached->generation_counter()) {
- next_state_ = STATE_VERIFY_PROOF;
- } else {
- SetCachedProofValid(cached);
- cached->SetProofVerifyDetails(verify_details_.release());
- next_state_ = STATE_GET_CHANNEL_ID;
- }
break;
case STATE_GET_CHANNEL_ID: {
next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
@@ -471,8 +438,129 @@ void QuicCryptoClientStream::DoHandshakeLoop(
// This means that the peer sent us a message that we weren't expecting.
CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
return;
+ case STATE_INITIALIZE_SCUP:
+ case STATE_VERIFY_PROOF_SCUP:
+ case STATE_VERIFY_PROOF_COMPLETE_SCUP:
+ NOTREACHED();
+ return;
+ }
+ }
+}
+
+void QuicCryptoClientStream::DoProofVeifyLoop() {
+ QuicCryptoClientConfig::CachedState* cached =
+ crypto_config_->LookupOrCreate(server_id_);
+ for (;;) {
+ const State state = next_state_;
+ next_state_ = STATE_IDLE;
+ switch (state) {
+ case STATE_INITIALIZE_SCUP: {
+ if (!server_id_.is_https()) {
+ // We don't check the certificates for insecure QUIC connections.
+ SetCachedProofValid(cached);
+ } else {
+ if (!cached->IsEmpty() && !cached->signature().empty()) {
+ // Note that we verify the proof even if the cached proof is valid.
+ // This allows us to respond to CA trust changes or certificate
+ // expiration because it may have been a while since we last
+ // verified the proof.
+ DCHECK(crypto_config_->proof_verifier());
+ // If the cached state needs to be verified, do it now.
+ next_state_ = STATE_VERIFY_PROOF_SCUP;
+ }
+ }
+ break;
+ }
+ case STATE_VERIFY_PROOF_SCUP: {
+ if (QUIC_PENDING == DoVerifyProof(cached)) {
+ return;
+ }
+ break;
+ }
+ case STATE_VERIFY_PROOF_COMPLETE_SCUP: {
+ if (QUIC_NO_ERROR != DoVerifyProofComplete(cached)) {
+ return;
+ }
+ break;
+ }
+ case STATE_IDLE:
+ return; // We are done.
+ default:
+ NOTREACHED();
+ return;
+
+ }
+ }
+}
+
+QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
+ QuicCryptoClientConfig::CachedState* cached) {
+ ProofVerifier* verifier = crypto_config_->proof_verifier();
+ DCHECK(verifier);
+ if (handshake_confirmed()) {
+ next_state_ = STATE_VERIFY_PROOF_COMPLETE_SCUP;
+ } else {
+ 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.
+ }
+ generation_counter_ = cached->generation_counter();
+
+ ProofVerifierCallbackImpl* proof_verify_callback =
+ new ProofVerifierCallbackImpl(this);
+
+ verify_ok_ = false;
+
+ QuicAsyncStatus status = verifier->VerifyProof(
+ server_id_.host(),
+ cached->server_config(),
+ cached->certs(),
+ cached->signature(),
+ verify_context_.get(),
+ &verify_error_details_,
+ &verify_details_,
+ proof_verify_callback);
+
+ switch (status) {
+ case QUIC_PENDING:
+ proof_verify_callback_ = proof_verify_callback;
+ DVLOG(1) << "Doing VerifyProof";
+ break;
+ case QUIC_FAILURE:
+ delete proof_verify_callback;
+ break;
+ case QUIC_SUCCESS:
+ delete proof_verify_callback;
+ verify_ok_ = true;
+ break;
+ }
+ return status;
+}
+
+QuicErrorCode QuicCryptoClientStream::DoVerifyProofComplete(
+ QuicCryptoClientConfig::CachedState* cached) {
+ if (!verify_ok_) {
+ client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
+ CloseConnectionWithDetails(
+ QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
+ 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.
+ }
+
+ // Check if generation_counter has changed between STATE_VERIFY_PROOF (or
+ // STATE_VERIFY_PROOF_SCUP) and STATE_VERIFY_PROOF_COMPLETE (or
+ // STATE_VERIFY_PROOF_COMPLETE_SCUP) state changes.
+ if (generation_counter_ != cached->generation_counter()) {
+ if (handshake_confirmed()) {
+ next_state_ = STATE_VERIFY_PROOF_SCUP;
+ } else {
+ next_state_ = STATE_VERIFY_PROOF;
+ }
+ } else {
+ SetCachedProofValid(cached);
+ cached->SetProofVerifyDetails(verify_details_.release());
+ if (!handshake_confirmed()) {
+ next_state_ = STATE_GET_CHANNEL_ID;
}
}
+ return QUIC_NO_ERROR;
}
void QuicCryptoClientStream::SetCachedProofValid(
« 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