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

Unified Diff: net/quic/quic_crypto_client_stream.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 5 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') | net/quic/quic_crypto_client_stream_factory.h » ('j') | 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
deleted file mode 100644
index 9300bc5007c36551d03869bdf355d8223fc18583..0000000000000000000000000000000000000000
--- a/net/quic/quic_crypto_client_stream.cc
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/quic/quic_crypto_client_stream.h"
-
-#include <memory>
-#include <vector>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/strings/stringprintf.h"
-#include "net/quic/crypto/crypto_protocol.h"
-#include "net/quic/crypto/crypto_utils.h"
-#include "net/quic/crypto/null_encrypter.h"
-#include "net/quic/quic_flags.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_session.h"
-#include "net/quic/quic_utils.h"
-
-using std::string;
-using std::vector;
-
-namespace net {
-
-namespace {
-
-void AppendFixed(CryptoHandshakeMessage* message) {
- if (FLAGS_quic_deprecate_kfixd) {
- return;
- }
- vector<QuicTag> tags;
- tags.push_back(kFIXD);
-
- const QuicTag* received_tags;
- size_t received_tags_length;
- QuicErrorCode error =
- message->GetTaglist(kCOPT, &received_tags, &received_tags_length);
- if (error == QUIC_NO_ERROR) {
- for (size_t i = 0; i < received_tags_length; ++i) {
- tags.push_back(received_tags[i]);
- }
- }
- message->SetVector(kCOPT, tags);
-}
-
-} // namespace
-
-QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
- : QuicCryptoStream(session) {}
-
-QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
- ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream)
- : stream_(stream) {}
-
-QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
- ~ChannelIDSourceCallbackImpl() {}
-
-void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run(
- std::unique_ptr<ChannelIDKey>* channel_id_key) {
- if (stream_ == nullptr) {
- return;
- }
-
- stream_->channel_id_key_.reset(channel_id_key->release());
- stream_->channel_id_source_callback_run_ = true;
- stream_->channel_id_source_callback_ = nullptr;
- stream_->DoHandshakeLoop(nullptr);
-
- // The ChannelIDSource owns this object and will delete it when this method
- // returns.
-}
-
-void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() {
- stream_ = nullptr;
-}
-
-QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
- QuicCryptoClientStream* stream)
- : stream_(stream) {}
-
-QuicCryptoClientStream::ProofVerifierCallbackImpl::
- ~ProofVerifierCallbackImpl() {}
-
-void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run(
- bool ok,
- const string& error_details,
- std::unique_ptr<ProofVerifyDetails>* details) {
- if (stream_ == nullptr) {
- return;
- }
-
- stream_->verify_ok_ = ok;
- stream_->verify_error_details_ = error_details;
- stream_->verify_details_.reset(details->release());
- stream_->proof_verify_callback_ = nullptr;
- stream_->DoHandshakeLoop(nullptr);
-
- // The ProofVerifier owns this object and will delete it when this method
- // returns.
-}
-
-void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() {
- stream_ = nullptr;
-}
-
-QuicCryptoClientStream::QuicCryptoClientStream(
- const QuicServerId& server_id,
- QuicSession* session,
- ProofVerifyContext* verify_context,
- QuicCryptoClientConfig* crypto_config,
- ProofHandler* proof_handler)
- : QuicCryptoClientStreamBase(session),
- next_state_(STATE_IDLE),
- num_client_hellos_(0),
- crypto_config_(crypto_config),
- server_id_(server_id),
- generation_counter_(0),
- channel_id_sent_(false),
- channel_id_source_callback_run_(false),
- channel_id_source_callback_(nullptr),
- verify_context_(verify_context),
- proof_verify_callback_(nullptr),
- proof_handler_(proof_handler),
- stateless_reject_received_(false),
- num_scup_messages_received_(0) {
- DCHECK_EQ(Perspective::IS_CLIENT, session->connection()->perspective());
-}
-
-QuicCryptoClientStream::~QuicCryptoClientStream() {
- if (channel_id_source_callback_) {
- channel_id_source_callback_->Cancel();
- }
- if (proof_verify_callback_) {
- proof_verify_callback_->Cancel();
- }
-}
-
-void QuicCryptoClientStream::OnHandshakeMessage(
- const CryptoHandshakeMessage& message) {
- QuicCryptoClientStreamBase::OnHandshakeMessage(message);
-
- if (message.tag() == kSCUP) {
- if (!handshake_confirmed()) {
- CloseConnectionWithDetails(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
- "Early SCUP disallowed");
- return;
- }
-
- // |message| is an update from the server, so we treat it differently from a
- // handshake message.
- HandleServerConfigUpdateMessage(message);
- num_scup_messages_received_++;
- return;
- }
-
- // Do not process handshake messages after the handshake is confirmed.
- if (handshake_confirmed()) {
- CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
- "Unexpected handshake message");
- return;
- }
-
- DoHandshakeLoop(&message);
-}
-
-void QuicCryptoClientStream::CryptoConnect() {
- next_state_ = STATE_INITIALIZE;
- DoHandshakeLoop(nullptr);
-}
-
-int QuicCryptoClientStream::num_sent_client_hellos() const {
- return num_client_hellos_;
-}
-
-int QuicCryptoClientStream::num_scup_messages_received() const {
- return num_scup_messages_received_;
-}
-
-// Used in Chromium, but not in the server.
-bool QuicCryptoClientStream::WasChannelIDSent() const {
- return channel_id_sent_;
-}
-
-bool QuicCryptoClientStream::WasChannelIDSourceCallbackRun() const {
- return channel_id_source_callback_run_;
-}
-
-void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
- const CryptoHandshakeMessage& server_config_update) {
- DCHECK(server_config_update.tag() == kSCUP);
- string error_details;
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_->LookupOrCreate(server_id_);
- QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
- server_config_update, session()->connection()->clock()->WallNow(),
- session()->connection()->version(), cached->chlo_hash(), cached,
- &crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- CloseConnectionWithDetails(
- 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(nullptr);
-}
-
-void QuicCryptoClientStream::DoHandshakeLoop(const CryptoHandshakeMessage* in) {
- QuicCryptoClientConfig::CachedState* cached =
- crypto_config_->LookupOrCreate(server_id_);
-
- QuicAsyncStatus rv = QUIC_SUCCESS;
- do {
- CHECK_NE(STATE_NONE, next_state_);
- const State state = next_state_;
- next_state_ = STATE_IDLE;
- rv = QUIC_SUCCESS;
- switch (state) {
- case STATE_INITIALIZE:
- DoInitialize(cached);
- break;
- case STATE_SEND_CHLO:
- DoSendCHLO(cached);
- return; // return waiting to hear from server.
- case STATE_RECV_REJ:
- DoReceiveREJ(in, cached);
- break;
- case STATE_VERIFY_PROOF:
- rv = DoVerifyProof(cached);
- break;
- case STATE_VERIFY_PROOF_COMPLETE:
- DoVerifyProofComplete(cached);
- break;
- case STATE_GET_CHANNEL_ID:
- rv = DoGetChannelID(cached);
- break;
- case STATE_GET_CHANNEL_ID_COMPLETE:
- DoGetChannelIDComplete();
- break;
- case STATE_RECV_SHLO:
- DoReceiveSHLO(in, cached);
- break;
- case STATE_IDLE:
- // This means that the peer sent us a message that we weren't expecting.
- CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Handshake in idle state");
- return;
- case STATE_INITIALIZE_SCUP:
- DoInitializeServerConfigUpdate(cached);
- break;
- case STATE_NONE:
- NOTREACHED();
- return; // We are done.
- }
- } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
-}
-
-void QuicCryptoClientStream::DoInitialize(
- QuicCryptoClientConfig::CachedState* cached) {
- 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());
- // Track proof verification time when cached server config is used.
- proof_verify_start_time_ = base::TimeTicks::Now();
- chlo_hash_ = cached->chlo_hash();
- // If the cached state needs to be verified, do it now.
- next_state_ = STATE_VERIFY_PROOF;
- } else {
- next_state_ = STATE_GET_CHANNEL_ID;
- }
-}
-
-void QuicCryptoClientStream::DoSendCHLO(
- QuicCryptoClientConfig::CachedState* cached) {
- if (stateless_reject_received_) {
- // If we've gotten to this point, we've sent at least one hello
- // and received a stateless reject in response. We cannot
- // continue to send hellos because the server has abandoned state
- // for this connection. Abandon further handshakes.
- next_state_ = STATE_NONE;
- if (session()->connection()->connected()) {
- session()->connection()->CloseConnection(
- QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT, "stateless reject received",
- ConnectionCloseBehavior::SILENT_CLOSE);
- }
- return;
- }
-
- // Send the client hello in plaintext.
- session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE);
- encryption_established_ = false;
- if (num_client_hellos_ > kMaxClientHellos) {
- CloseConnectionWithDetails(
- QUIC_CRYPTO_TOO_MANY_REJECTS,
- base::StringPrintf("More than %u rejects", kMaxClientHellos).c_str());
- return;
- }
- num_client_hellos_++;
-
- CryptoHandshakeMessage out;
- DCHECK(session() != nullptr);
- DCHECK(session()->config() != nullptr);
- // Send all the options, regardless of whether we're sending an
- // inchoate or subsequent hello.
- session()->config()->ToHandshakeMessage(&out);
-
- // This call and function should be removed when
- // FLAGS_quic_deprecate_kfixd is removed.
- AppendFixed(&out);
-
- // Send a local timestamp to the server.
- out.SetValue(kCTIM,
- session()->connection()->clock()->WallNow().ToUNIXSeconds());
-
- if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
- crypto_config_->FillInchoateClientHello(
- server_id_, session()->connection()->supported_versions().front(),
- cached, session()->connection()->random_generator(),
- /* demand_x509_proof= */ true, &crypto_negotiated_params_, &out);
- // Pad the inchoate client hello to fill up a packet.
- const QuicByteCount kFramingOverhead = 50; // A rough estimate.
- const QuicByteCount max_packet_size =
- session()->connection()->max_packet_length();
- if (max_packet_size <= kFramingOverhead) {
- DLOG(DFATAL) << "max_packet_length (" << max_packet_size
- << ") has no room for framing overhead.";
- CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
- "max_packet_size too smalll");
- return;
- }
- if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
- DLOG(DFATAL) << "Client hello won't fit in a single packet.";
- CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large");
- return;
- }
- out.set_minimum_size(
- static_cast<size_t>(max_packet_size - kFramingOverhead));
- next_state_ = STATE_RECV_REJ;
- CryptoUtils::HashHandshakeMessage(out, &chlo_hash_);
- SendHandshakeMessage(out);
- return;
- }
-
- // If the server nonce is empty, copy over the server nonce from a previous
- // SREJ, if there is one.
- if (FLAGS_enable_quic_stateless_reject_support &&
- crypto_negotiated_params_.server_nonce.empty() &&
- cached->has_server_nonce()) {
- crypto_negotiated_params_.server_nonce = cached->GetNextServerNonce();
- DCHECK(!crypto_negotiated_params_.server_nonce.empty());
- }
-
- string error_details;
- QuicErrorCode error = crypto_config_->FillClientHello(
- server_id_, session()->connection()->connection_id(),
- session()->connection()->version(),
- session()->connection()->supported_versions().front(), cached,
- session()->connection()->clock()->WallNow(),
- session()->connection()->random_generator(), channel_id_key_.get(),
- &crypto_negotiated_params_, &out, &error_details);
- if (error != QUIC_NO_ERROR) {
- // Flush the cached config so that, if it's bad, the server has a
- // chance to send us another in the future.
- cached->InvalidateServerConfig();
- CloseConnectionWithDetails(error, error_details);
- return;
- }
- CryptoUtils::HashHandshakeMessage(out, &chlo_hash_);
- channel_id_sent_ = (channel_id_key_.get() != nullptr);
- if (cached->proof_verify_details()) {
- proof_handler_->OnProofVerifyDetailsAvailable(
- *cached->proof_verify_details());
- }
- next_state_ = STATE_RECV_SHLO;
- SendHandshakeMessage(out);
- // Be prepared to decrypt with the new server write key.
- session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_INITIAL,
- crypto_negotiated_params_.initial_crypters.decrypter.release(),
- true /* latch once used */);
- // Send subsequent packets under encryption on the assumption that the
- // server will accept the handshake.
- session()->connection()->SetEncrypter(
- ENCRYPTION_INITIAL,
- crypto_negotiated_params_.initial_crypters.encrypter.release());
- session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
-
- // TODO(ianswett): Merge ENCRYPTION_REESTABLISHED and
- // ENCRYPTION_FIRST_ESTABLSIHED
- encryption_established_ = true;
- session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_REESTABLISHED);
-}
-
-void QuicCryptoClientStream::DoReceiveREJ(
- const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached) {
- // We sent a dummy CHLO because we didn't have enough information to
- // perform a handshake, or we sent a full hello that the server
- // rejected. Here we hope to have a REJ that contains the information
- // that we need.
- if ((in->tag() != kREJ) && (in->tag() != kSREJ)) {
- next_state_ = STATE_NONE;
- CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Expected REJ");
- return;
- }
-
- const uint32_t* reject_reasons;
- size_t num_reject_reasons;
- static_assert(sizeof(QuicTag) == sizeof(uint32_t), "header out of sync");
- if (in->GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons) ==
- QUIC_NO_ERROR) {
- uint32_t packed_error = 0;
- for (size_t i = 0; i < num_reject_reasons; ++i) {
- // HANDSHAKE_OK is 0 and don't report that as error.
- if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) {
- continue;
- }
- HandshakeFailureReason reason =
- static_cast<HandshakeFailureReason>(reject_reasons[i]);
- packed_error |= 1 << (reason - 1);
- }
- DVLOG(1) << "Reasons for rejection: " << packed_error;
- if (num_client_hellos_ == kMaxClientHellos) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.TooMany",
- packed_error);
- }
- UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure",
- packed_error);
- }
-
- stateless_reject_received_ = in->tag() == kSREJ;
- string error_details;
- QuicErrorCode error = crypto_config_->ProcessRejection(
- *in, session()->connection()->clock()->WallNow(),
- session()->connection()->version(), chlo_hash_, cached,
- &crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- next_state_ = STATE_NONE;
- CloseConnectionWithDetails(error, error_details);
- return;
- }
- if (!cached->proof_valid()) {
- if (!cached->signature().empty()) {
- // Note that we only verify the proof if the cached proof is not
- // valid. If the cached proof is valid here, someone else must have
- // just added the server config to the cache and verified the proof,
- // so we can assume no CA trust changes or certificate expiration
- // has happened since then.
- next_state_ = STATE_VERIFY_PROOF;
- return;
- }
- }
- next_state_ = STATE_GET_CHANNEL_ID;
-}
-
-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(), server_id_.port(), cached->server_config(),
- session()->connection()->version(), chlo_hash_, cached->certs(),
- cached->cert_sct(), cached->signature(), verify_context_.get(),
- &verify_error_details_, &verify_details_,
- std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
-
- switch (status) {
- case QUIC_PENDING:
- proof_verify_callback_ = proof_verify_callback;
- DVLOG(1) << "Doing VerifyProof";
- break;
- case QUIC_FAILURE:
- break;
- case QUIC_SUCCESS:
- verify_ok_ = true;
- break;
- }
- return status;
-}
-
-void QuicCryptoClientStream::DoVerifyProofComplete(
- QuicCryptoClientConfig::CachedState* cached) {
- if (!proof_verify_start_time_.is_null()) {
- UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.CachedServerConfig",
- base::TimeTicks::Now() - proof_verify_start_time_);
- }
- if (!verify_ok_) {
- if (verify_details_.get()) {
- proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
- }
- if (num_client_hellos_ == 0) {
- cached->Clear();
- next_state_ = STATE_INITIALIZE;
- return;
- }
- next_state_ = STATE_NONE;
- UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
- handshake_confirmed());
- CloseConnectionWithDetails(QUIC_PROOF_INVALID,
- "Proof invalid: " + verify_error_details_);
- 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());
- if (!handshake_confirmed()) {
- next_state_ = STATE_GET_CHANNEL_ID;
- } else {
- // TODO: Enable Expect-Staple. https://crbug.com/631101
- next_state_ = STATE_NONE;
- }
- }
-}
-
-QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID(
- QuicCryptoClientConfig::CachedState* cached) {
- next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
- channel_id_key_.reset();
- if (!RequiresChannelID(cached)) {
- next_state_ = STATE_SEND_CHLO;
- return QUIC_SUCCESS;
- }
-
- ChannelIDSourceCallbackImpl* channel_id_source_callback =
- new ChannelIDSourceCallbackImpl(this);
- QuicAsyncStatus status = crypto_config_->channel_id_source()->GetChannelIDKey(
- server_id_.host(), &channel_id_key_, channel_id_source_callback);
-
- switch (status) {
- case QUIC_PENDING:
- channel_id_source_callback_ = channel_id_source_callback;
- DVLOG(1) << "Looking up channel ID";
- break;
- case QUIC_FAILURE:
- next_state_ = STATE_NONE;
- delete channel_id_source_callback;
- CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
- "Channel ID lookup failed");
- break;
- case QUIC_SUCCESS:
- delete channel_id_source_callback;
- break;
- }
- return status;
-}
-
-void QuicCryptoClientStream::DoGetChannelIDComplete() {
- if (!channel_id_key_.get()) {
- next_state_ = STATE_NONE;
- CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
- "Channel ID lookup failed");
- return;
- }
- next_state_ = STATE_SEND_CHLO;
-}
-
-void QuicCryptoClientStream::DoReceiveSHLO(
- const CryptoHandshakeMessage* in,
- QuicCryptoClientConfig::CachedState* cached) {
- next_state_ = STATE_NONE;
- // We sent a CHLO that we expected to be accepted and now we're
- // hoping for a SHLO from the server to confirm that. First check
- // to see whether the response was a reject, and if so, move on to
- // the reject-processing state.
- if ((in->tag() == kREJ) || (in->tag() == kSREJ)) {
- // alternative_decrypter will be nullptr if the original alternative
- // decrypter latched and became the primary decrypter. That happens
- // if we received a message encrypted with the INITIAL key.
- if (session()->connection()->alternative_decrypter() == nullptr) {
- // The rejection was sent encrypted!
- CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
- "encrypted REJ message");
- return;
- }
- next_state_ = STATE_RECV_REJ;
- return;
- }
-
- if (in->tag() != kSHLO) {
- CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
- "Expected SHLO or REJ");
- return;
- }
-
- // alternative_decrypter will be nullptr if the original alternative
- // decrypter latched and became the primary decrypter. That happens
- // if we received a message encrypted with the INITIAL key.
- if (session()->connection()->alternative_decrypter() != nullptr) {
- // The server hello was sent without encryption.
- CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
- "unencrypted SHLO message");
- return;
- }
-
- string error_details;
- QuicErrorCode error = crypto_config_->ProcessServerHello(
- *in, session()->connection()->connection_id(),
- session()->connection()->version(),
- session()->connection()->server_supported_versions(), cached,
- &crypto_negotiated_params_, &error_details);
-
- if (error != QUIC_NO_ERROR) {
- CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
- return;
- }
- error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
- if (error != QUIC_NO_ERROR) {
- CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
- return;
- }
- session()->OnConfigNegotiated();
-
- CrypterPair* crypters = &crypto_negotiated_params_.forward_secure_crypters;
- // TODO(agl): we don't currently latch this decrypter because the idea
- // has been floated that the server shouldn't send packets encrypted
- // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
- // packet from the client.
- session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_FORWARD_SECURE, crypters->decrypter.release(),
- false /* don't latch */);
- session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
- crypters->encrypter.release());
- session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
-
- handshake_confirmed_ = true;
- session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
- session()->connection()->OnHandshakeComplete();
-}
-
-void QuicCryptoClientStream::DoInitializeServerConfigUpdate(
- QuicCryptoClientConfig::CachedState* cached) {
- bool update_ignored = false;
- 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;
- } else {
- update_ignored = true;
- next_state_ = STATE_NONE;
- }
- UMA_HISTOGRAM_COUNTS("Net.QuicNumServerConfig.UpdateMessagesIgnored",
- update_ignored);
-}
-
-void QuicCryptoClientStream::SetCachedProofValid(
- QuicCryptoClientConfig::CachedState* cached) {
- cached->SetProofValid();
- proof_handler_->OnProofValid(*cached);
-}
-
-bool QuicCryptoClientStream::RequiresChannelID(
- QuicCryptoClientConfig::CachedState* cached) {
- if (server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
- !crypto_config_->channel_id_source()) {
- return false;
- }
- const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
- if (!scfg) { // scfg may be null then we send an inchoate CHLO.
- return false;
- }
- const QuicTag* their_proof_demands;
- size_t num_their_proof_demands;
- if (scfg->GetTaglist(kPDMD, &their_proof_demands, &num_their_proof_demands) !=
- QUIC_NO_ERROR) {
- return false;
- }
- for (size_t i = 0; i < num_their_proof_demands; i++) {
- if (their_proof_demands[i] == kCHID) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace net
« no previous file with comments | « net/quic/quic_crypto_client_stream.h ('k') | net/quic/quic_crypto_client_stream_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698