summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorrtenneti <rtenneti@chromium.org>2014-09-18 15:18:35 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-18 22:19:39 +0000
commitc584fb92ddd78cb2c2a36b90f0d7be30227d3cff (patch)
treed9591bc420358946011d093460e02c6a61a423ed /net
parentf4cc5195cd3708c709dfe06f037010d82548f9d1 (diff)
downloadchromium_src-c584fb92ddd78cb2c2a36b90f0d7be30227d3cff.zip
chromium_src-c584fb92ddd78cb2c2a36b90f0d7be30227d3cff.tar.gz
chromium_src-c584fb92ddd78cb2c2a36b90f0d7be30227d3cff.tar.bz2
Persist the server config that is received via kSCUP.
R=rjshade@chromium.org, rch@chromium.org, asvitkine@chromium.org, rvargas@chromium.org Review URL: https://codereview.chromium.org/427313002 Cr-Commit-Position: refs/heads/master@{#295582}
Diffstat (limited to 'net')
-rw-r--r--net/http/disk_cache_based_quic_server_info.cc11
-rw-r--r--net/quic/quic_crypto_client_stream.cc141
-rw-r--r--net/quic/quic_crypto_client_stream.h17
3 files changed, 121 insertions, 48 deletions
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc
index 51fba21..13c53b7 100644
--- a/net/http/disk_cache_based_quic_server_info.cc
+++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -213,7 +213,9 @@ int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) {
}
int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) {
- state_ = SET_DONE;
+ // Keep the entry open for future writes.
+ new_data_.clear();
+ state_ = NONE;
return OK;
}
@@ -221,7 +223,8 @@ int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) {
if (rv != OK) {
state_ = SET_DONE;
} else {
- entry_ = data_shim_->entry;
+ if (!entry_)
+ entry_ = data_shim_->entry;
state_ = WRITE;
}
return OK;
@@ -264,8 +267,10 @@ int DiskCacheBasedQuicServerInfo::DoWrite() {
}
int DiskCacheBasedQuicServerInfo::DoCreateOrOpen() {
- DCHECK(entry_ == NULL);
state_ = CREATE_OR_OPEN_COMPLETE;
+ if (entry_)
+ return OK;
+
if (found_entry_) {
return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_);
}
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc
index 40e4d45..4d9d032 100644
--- a/net/quic/quic_crypto_client_stream.cc
+++ b/net/quic/quic_crypto_client_stream.cc
@@ -4,6 +4,7 @@
#include "net/quic/quic_crypto_client_stream.h"
+#include "base/metrics/histogram.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/null_encrypter.h"
@@ -156,6 +157,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;
+ DoHandshakeLoop(NULL);
}
// kMaxClientHellos is the maximum number of times that we'll send a client
@@ -308,57 +316,15 @@ 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;
+ 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_);
+ if (QUIC_PROOF_INVALID == 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 +437,93 @@ 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:
+ DoInitializeServerConfigUpdate(cached);
+ break;
+ case STATE_VERIFY_PROOF_DONE:
+ return; // We are done.
+ }
+ }
+}
+
+void QuicCryptoClientStream::DoInitializeServerConfigUpdate(
+ QuicCryptoClientConfig::CachedState* cached) {
+ if (!server_id_.is_https()) {
+ // We don't check the certificates for insecure QUIC connections.
+ SetCachedProofValid(cached);
+ next_state_ = STATE_VERIFY_PROOF_DONE;
+ return;
+ }
+ if (!cached->IsEmpty() && !cached->signature().empty()) {
+ // Note that we verify the proof even if the cached proof is valid.
+ DCHECK(crypto_config_->proof_verifier());
+ next_state_ = STATE_VERIFY_PROOF;
+ }
+}
+
+QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
+ QuicCryptoClientConfig::CachedState* cached) {
+ 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";
+ 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_);
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
+ handshake_confirmed());
+ CloseConnectionWithDetails(
+ QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
+ return QUIC_PROOF_INVALID;
+ }
+
+ // 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());
+ if (!handshake_confirmed()) {
+ next_state_ = STATE_GET_CHANNEL_ID;
+ } else {
+ next_state_ = STATE_VERIFY_PROOF_DONE;
}
}
+ return QUIC_NO_ERROR;
}
void QuicCryptoClientStream::SetCachedProofValid(
diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h
index 3be89ab..768e38a 100644
--- a/net/quic/quic_crypto_client_stream.h
+++ b/net/quic/quic_crypto_client_stream.h
@@ -106,6 +106,8 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
STATE_GET_CHANNEL_ID,
STATE_GET_CHANNEL_ID_COMPLETE,
STATE_RECV_SHLO,
+ STATE_INITIALIZE_SCUP,
+ STATE_VERIFY_PROOF_DONE,
};
// Handles new server config and optional source-address token provided by the
@@ -117,6 +119,21 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
// |in| may be NULL if the call did not result from a received message.
void DoHandshakeLoop(const CryptoHandshakeMessage* in);
+ // Start the proof verification if |server_id_| is https and |cached| has
+ // signature.
+ void DoInitializeServerConfigUpdate(
+ QuicCryptoClientConfig::CachedState* cached);
+
+ // Starts the proof verification. Returns the QuicAsyncStatus returned by the
+ // ProofVerifier's VerifyProof.
+ QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
+
+ // If proof is valid then it sets the proof as valid (which persists the
+ // server config) and returns QUIC_NO_ERROR. If not, it closes the connection
+ // and returns QUIC_PROOF_INVALID.
+ QuicErrorCode DoVerifyProofComplete(
+ QuicCryptoClientConfig::CachedState* cached);
+
// Called to set the proof of |cached| valid. Also invokes the session's
// OnProofValid() method.
void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);