| OLD | NEW |
| 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 "base/metrics/histogram.h" |
| 8 #include "net/quic/crypto/crypto_protocol.h" | 8 #include "net/quic/crypto/crypto_protocol.h" |
| 9 #include "net/quic/crypto/crypto_utils.h" | 9 #include "net/quic/crypto/crypto_utils.h" |
| 10 #include "net/quic/crypto/null_encrypter.h" | 10 #include "net/quic/crypto/null_encrypter.h" |
| 11 #include "net/quic/quic_client_session_base.h" | 11 #include "net/quic/quic_client_session_base.h" |
| 12 #include "net/quic/quic_protocol.h" | 12 #include "net/quic/quic_protocol.h" |
| 13 #include "net/quic/quic_session.h" | 13 #include "net/quic/quic_session.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: | 17 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: |
| 18 ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream) | 18 ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream) |
| 19 : stream_(stream) {} | 19 : stream_(stream) {} |
| 20 | 20 |
| 21 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: | 21 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: |
| 22 ~ChannelIDSourceCallbackImpl() {} | 22 ~ChannelIDSourceCallbackImpl() {} |
| 23 | 23 |
| 24 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run( | 24 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run( |
| 25 scoped_ptr<ChannelIDKey>* channel_id_key) { | 25 scoped_ptr<ChannelIDKey>* channel_id_key) { |
| 26 if (stream_ == NULL) { | 26 if (stream_ == nullptr) { |
| 27 return; | 27 return; |
| 28 } | 28 } |
| 29 | 29 |
| 30 stream_->channel_id_key_.reset(channel_id_key->release()); | 30 stream_->channel_id_key_.reset(channel_id_key->release()); |
| 31 stream_->channel_id_source_callback_run_ = true; | 31 stream_->channel_id_source_callback_run_ = true; |
| 32 stream_->channel_id_source_callback_ = NULL; | 32 stream_->channel_id_source_callback_ = nullptr; |
| 33 stream_->DoHandshakeLoop(NULL); | 33 stream_->DoHandshakeLoop(nullptr); |
| 34 | 34 |
| 35 // The ChannelIDSource owns this object and will delete it when this method | 35 // The ChannelIDSource owns this object and will delete it when this method |
| 36 // returns. | 36 // returns. |
| 37 } | 37 } |
| 38 | 38 |
| 39 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() { | 39 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() { |
| 40 stream_ = NULL; | 40 stream_ = nullptr; |
| 41 } | 41 } |
| 42 | 42 |
| 43 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( | 43 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( |
| 44 QuicCryptoClientStream* stream) | 44 QuicCryptoClientStream* stream) |
| 45 : stream_(stream) {} | 45 : stream_(stream) {} |
| 46 | 46 |
| 47 QuicCryptoClientStream::ProofVerifierCallbackImpl:: | 47 QuicCryptoClientStream::ProofVerifierCallbackImpl:: |
| 48 ~ProofVerifierCallbackImpl() {} | 48 ~ProofVerifierCallbackImpl() {} |
| 49 | 49 |
| 50 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( | 50 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( |
| 51 bool ok, | 51 bool ok, |
| 52 const string& error_details, | 52 const string& error_details, |
| 53 scoped_ptr<ProofVerifyDetails>* details) { | 53 scoped_ptr<ProofVerifyDetails>* details) { |
| 54 if (stream_ == NULL) { | 54 if (stream_ == nullptr) { |
| 55 return; | 55 return; |
| 56 } | 56 } |
| 57 | 57 |
| 58 stream_->verify_ok_ = ok; | 58 stream_->verify_ok_ = ok; |
| 59 stream_->verify_error_details_ = error_details; | 59 stream_->verify_error_details_ = error_details; |
| 60 stream_->verify_details_.reset(details->release()); | 60 stream_->verify_details_.reset(details->release()); |
| 61 stream_->proof_verify_callback_ = NULL; | 61 stream_->proof_verify_callback_ = nullptr; |
| 62 stream_->DoHandshakeLoop(NULL); | 62 stream_->DoHandshakeLoop(nullptr); |
| 63 | 63 |
| 64 // The ProofVerifier owns this object and will delete it when this method | 64 // The ProofVerifier owns this object and will delete it when this method |
| 65 // returns. | 65 // returns. |
| 66 } | 66 } |
| 67 | 67 |
| 68 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { | 68 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { |
| 69 stream_ = NULL; | 69 stream_ = nullptr; |
| 70 } | 70 } |
| 71 | 71 |
| 72 QuicCryptoClientStream::QuicCryptoClientStream( | 72 QuicCryptoClientStream::QuicCryptoClientStream( |
| 73 const QuicServerId& server_id, | 73 const QuicServerId& server_id, |
| 74 QuicClientSessionBase* session, | 74 QuicClientSessionBase* session, |
| 75 ProofVerifyContext* verify_context, | 75 ProofVerifyContext* verify_context, |
| 76 QuicCryptoClientConfig* crypto_config) | 76 QuicCryptoClientConfig* crypto_config) |
| 77 : QuicCryptoStream(session), | 77 : QuicCryptoStream(session), |
| 78 next_state_(STATE_IDLE), | 78 next_state_(STATE_IDLE), |
| 79 num_client_hellos_(0), | 79 num_client_hellos_(0), |
| 80 crypto_config_(crypto_config), | 80 crypto_config_(crypto_config), |
| 81 server_id_(server_id), | 81 server_id_(server_id), |
| 82 generation_counter_(0), | 82 generation_counter_(0), |
| 83 channel_id_sent_(false), | 83 channel_id_sent_(false), |
| 84 channel_id_source_callback_run_(false), | 84 channel_id_source_callback_run_(false), |
| 85 channel_id_source_callback_(NULL), | 85 channel_id_source_callback_(nullptr), |
| 86 verify_context_(verify_context), | 86 verify_context_(verify_context), |
| 87 proof_verify_callback_(NULL) { | 87 proof_verify_callback_(nullptr) {} |
| 88 } | |
| 89 | 88 |
| 90 QuicCryptoClientStream::~QuicCryptoClientStream() { | 89 QuicCryptoClientStream::~QuicCryptoClientStream() { |
| 91 if (channel_id_source_callback_) { | 90 if (channel_id_source_callback_) { |
| 92 channel_id_source_callback_->Cancel(); | 91 channel_id_source_callback_->Cancel(); |
| 93 } | 92 } |
| 94 if (proof_verify_callback_) { | 93 if (proof_verify_callback_) { |
| 95 proof_verify_callback_->Cancel(); | 94 proof_verify_callback_->Cancel(); |
| 96 } | 95 } |
| 97 } | 96 } |
| 98 | 97 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 116 if (handshake_confirmed()) { | 115 if (handshake_confirmed()) { |
| 117 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); | 116 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); |
| 118 return; | 117 return; |
| 119 } | 118 } |
| 120 | 119 |
| 121 DoHandshakeLoop(&message); | 120 DoHandshakeLoop(&message); |
| 122 } | 121 } |
| 123 | 122 |
| 124 bool QuicCryptoClientStream::CryptoConnect() { | 123 bool QuicCryptoClientStream::CryptoConnect() { |
| 125 next_state_ = STATE_INITIALIZE; | 124 next_state_ = STATE_INITIALIZE; |
| 126 DoHandshakeLoop(NULL); | 125 DoHandshakeLoop(nullptr); |
| 127 return true; | 126 return true; |
| 128 } | 127 } |
| 129 | 128 |
| 130 int QuicCryptoClientStream::num_sent_client_hellos() const { | 129 int QuicCryptoClientStream::num_sent_client_hellos() const { |
| 131 return num_client_hellos_; | 130 return num_client_hellos_; |
| 132 } | 131 } |
| 133 | 132 |
| 134 bool QuicCryptoClientStream::WasChannelIDSent() const { | 133 bool QuicCryptoClientStream::WasChannelIDSent() const { |
| 135 return channel_id_sent_; | 134 return channel_id_sent_; |
| 136 } | 135 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 156 CloseConnectionWithDetails( | 155 CloseConnectionWithDetails( |
| 157 error, "Server config update invalid: " + error_details); | 156 error, "Server config update invalid: " + error_details); |
| 158 return; | 157 return; |
| 159 } | 158 } |
| 160 | 159 |
| 161 DCHECK(handshake_confirmed()); | 160 DCHECK(handshake_confirmed()); |
| 162 if (proof_verify_callback_) { | 161 if (proof_verify_callback_) { |
| 163 proof_verify_callback_->Cancel(); | 162 proof_verify_callback_->Cancel(); |
| 164 } | 163 } |
| 165 next_state_ = STATE_INITIALIZE_SCUP; | 164 next_state_ = STATE_INITIALIZE_SCUP; |
| 166 DoHandshakeLoop(NULL); | 165 DoHandshakeLoop(nullptr); |
| 167 } | 166 } |
| 168 | 167 |
| 169 // 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 |
| 170 // hello. The value 3 accounts for: | 169 // hello. The value 3 accounts for: |
| 171 // * One failure due to an incorrect or missing source-address token. | 170 // * One failure due to an incorrect or missing source-address token. |
| 172 // * 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 |
| 173 // 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. |
| 174 static const int kMaxClientHellos = 3; | 173 static const int kMaxClientHellos = 3; |
| 175 | 174 |
| 176 void QuicCryptoClientStream::DoHandshakeLoop( | 175 void QuicCryptoClientStream::DoHandshakeLoop( |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 &crypto_negotiated_params_, | 289 &crypto_negotiated_params_, |
| 291 &out, | 290 &out, |
| 292 &error_details); | 291 &error_details); |
| 293 if (error != QUIC_NO_ERROR) { | 292 if (error != QUIC_NO_ERROR) { |
| 294 // Flush the cached config so that, if it's bad, the server has a | 293 // Flush the cached config so that, if it's bad, the server has a |
| 295 // chance to send us another in the future. | 294 // chance to send us another in the future. |
| 296 cached->InvalidateServerConfig(); | 295 cached->InvalidateServerConfig(); |
| 297 CloseConnectionWithDetails(error, error_details); | 296 CloseConnectionWithDetails(error, error_details); |
| 298 return; | 297 return; |
| 299 } | 298 } |
| 300 channel_id_sent_ = (channel_id_key_.get() != NULL); | 299 channel_id_sent_ = (channel_id_key_.get() != nullptr); |
| 301 if (cached->proof_verify_details()) { | 300 if (cached->proof_verify_details()) { |
| 302 client_session()->OnProofVerifyDetailsAvailable( | 301 client_session()->OnProofVerifyDetailsAvailable( |
| 303 *cached->proof_verify_details()); | 302 *cached->proof_verify_details()); |
| 304 } | 303 } |
| 305 next_state_ = STATE_RECV_SHLO; | 304 next_state_ = STATE_RECV_SHLO; |
| 306 SendHandshakeMessage(out); | 305 SendHandshakeMessage(out); |
| 307 // Be prepared to decrypt with the new server write key. | 306 // Be prepared to decrypt with the new server write key. |
| 308 session()->connection()->SetAlternativeDecrypter( | 307 session()->connection()->SetAlternativeDecrypter( |
| 309 crypto_negotiated_params_.initial_crypters.decrypter.release(), | 308 crypto_negotiated_params_.initial_crypters.decrypter.release(), |
| 310 ENCRYPTION_INITIAL, | 309 ENCRYPTION_INITIAL, |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 next_state_ = STATE_SEND_CHLO; | 473 next_state_ = STATE_SEND_CHLO; |
| 475 } | 474 } |
| 476 | 475 |
| 477 void QuicCryptoClientStream::DoReceiveSHLO( | 476 void QuicCryptoClientStream::DoReceiveSHLO( |
| 478 const CryptoHandshakeMessage* in, | 477 const CryptoHandshakeMessage* in, |
| 479 QuicCryptoClientConfig::CachedState* cached) { | 478 QuicCryptoClientConfig::CachedState* cached) { |
| 480 next_state_ = STATE_NONE; | 479 next_state_ = STATE_NONE; |
| 481 // We sent a CHLO that we expected to be accepted and now we're hoping | 480 // We sent a CHLO that we expected to be accepted and now we're hoping |
| 482 // for a SHLO from the server to confirm that. | 481 // for a SHLO from the server to confirm that. |
| 483 if (in->tag() == kREJ) { | 482 if (in->tag() == kREJ) { |
| 484 // alternative_decrypter will be NULL if the original alternative | 483 // alternative_decrypter will be nullptr if the original alternative |
| 485 // decrypter latched and became the primary decrypter. That happens | 484 // decrypter latched and became the primary decrypter. That happens |
| 486 // if we received a message encrypted with the INITIAL key. | 485 // if we received a message encrypted with the INITIAL key. |
| 487 if (session()->connection()->alternative_decrypter() == NULL) { | 486 if (session()->connection()->alternative_decrypter() == nullptr) { |
| 488 // The rejection was sent encrypted! | 487 // The rejection was sent encrypted! |
| 489 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 488 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
| 490 "encrypted REJ message"); | 489 "encrypted REJ message"); |
| 491 return; | 490 return; |
| 492 } | 491 } |
| 493 next_state_ = STATE_RECV_REJ; | 492 next_state_ = STATE_RECV_REJ; |
| 494 return; | 493 return; |
| 495 } | 494 } |
| 496 | 495 |
| 497 if (in->tag() != kSHLO) { | 496 if (in->tag() != kSHLO) { |
| 498 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, | 497 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 499 "Expected SHLO or REJ"); | 498 "Expected SHLO or REJ"); |
| 500 return; | 499 return; |
| 501 } | 500 } |
| 502 | 501 |
| 503 // alternative_decrypter will be NULL if the original alternative | 502 // alternative_decrypter will be nullptr if the original alternative |
| 504 // decrypter latched and became the primary decrypter. That happens | 503 // decrypter latched and became the primary decrypter. That happens |
| 505 // if we received a message encrypted with the INITIAL key. | 504 // if we received a message encrypted with the INITIAL key. |
| 506 if (session()->connection()->alternative_decrypter() != NULL) { | 505 if (session()->connection()->alternative_decrypter() != nullptr) { |
| 507 // The server hello was sent without encryption. | 506 // The server hello was sent without encryption. |
| 508 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 507 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
| 509 "unencrypted SHLO message"); | 508 "unencrypted SHLO message"); |
| 510 return; | 509 return; |
| 511 } | 510 } |
| 512 | 511 |
| 513 string error_details; | 512 string error_details; |
| 514 QuicErrorCode error = crypto_config_->ProcessServerHello( | 513 QuicErrorCode error = crypto_config_->ProcessServerHello( |
| 515 *in, session()->connection()->connection_id(), | 514 *in, session()->connection()->connection_id(), |
| 516 session()->connection()->server_supported_versions(), | 515 session()->connection()->server_supported_versions(), |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 } | 592 } |
| 594 } | 593 } |
| 595 return false; | 594 return false; |
| 596 } | 595 } |
| 597 | 596 |
| 598 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 597 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
| 599 return reinterpret_cast<QuicClientSessionBase*>(session()); | 598 return reinterpret_cast<QuicClientSessionBase*>(session()); |
| 600 } | 599 } |
| 601 | 600 |
| 602 } // namespace net | 601 } // namespace net |
| OLD | NEW |