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 |