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 "net/base/completion_callback.h" | 7 #include "net/base/completion_callback.h" |
8 #include "net/base/net_errors.h" | 8 #include "net/base/net_errors.h" |
9 #include "net/quic/crypto/crypto_protocol.h" | 9 #include "net/quic/crypto/crypto_protocol.h" |
10 #include "net/quic/crypto/crypto_utils.h" | 10 #include "net/quic/crypto/crypto_utils.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 | 64 |
65 if (in != NULL) { | 65 if (in != NULL) { |
66 DVLOG(1) << "Client received: " << in->DebugString(); | 66 DVLOG(1) << "Client received: " << in->DebugString(); |
67 } | 67 } |
68 | 68 |
69 for (;;) { | 69 for (;;) { |
70 const State state = next_state_; | 70 const State state = next_state_; |
71 next_state_ = STATE_IDLE; | 71 next_state_ = STATE_IDLE; |
72 switch (state) { | 72 switch (state) { |
73 case STATE_SEND_CHLO: { | 73 case STATE_SEND_CHLO: { |
74 // Send the subsequent client hello in plaintext. | 74 DCHECK_EQ(OK, result); |
| 75 // Send the client hello in plaintext. |
75 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); | 76 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); |
76 if (num_client_hellos_ > kMaxClientHellos) { | 77 if (num_client_hellos_ > kMaxClientHellos) { |
77 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 78 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
78 return; | 79 return; |
79 } | 80 } |
80 num_client_hellos_++; | 81 num_client_hellos_++; |
81 | 82 |
82 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 83 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
83 crypto_config_->FillInchoateClientHello( | 84 crypto_config_->FillInchoateClientHello( |
84 server_hostname_, cached, &crypto_negotiated_params_, &out); | 85 server_hostname_, cached, &crypto_negotiated_params_, &out); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 CloseConnectionWithDetails(error, error_details); | 147 CloseConnectionWithDetails(error, error_details); |
147 return; | 148 return; |
148 } | 149 } |
149 if (!cached->proof_valid()) { | 150 if (!cached->proof_valid()) { |
150 ProofVerifier* verifier = session()->proof_verifier(); | 151 ProofVerifier* verifier = session()->proof_verifier(); |
151 if (!verifier) { | 152 if (!verifier) { |
152 // If no verifier is set then we don't check the certificates. | 153 // If no verifier is set then we don't check the certificates. |
153 cached->SetProofValid(); | 154 cached->SetProofValid(); |
154 } else if (!cached->signature().empty()) { | 155 } else if (!cached->signature().empty()) { |
155 next_state_ = STATE_VERIFY_PROOF; | 156 next_state_ = STATE_VERIFY_PROOF; |
156 continue; | 157 break; |
157 } | 158 } |
158 } | 159 } |
159 next_state_ = STATE_SEND_CHLO; | 160 next_state_ = STATE_SEND_CHLO; |
160 break; | 161 break; |
161 case STATE_VERIFY_PROOF: { | 162 case STATE_VERIFY_PROOF: { |
162 ProofVerifier* verifier = session()->proof_verifier(); | 163 ProofVerifier* verifier = session()->proof_verifier(); |
163 DCHECK(verifier); | 164 DCHECK(verifier); |
164 next_state_ = STATE_VERIFY_PROOF_COMPLETED; | 165 next_state_ = STATE_VERIFY_PROOF_COMPLETE; |
165 generation_counter_ = cached->generation_counter(); | 166 generation_counter_ = cached->generation_counter(); |
166 result = verifier->VerifyProof( | 167 result = verifier->VerifyProof( |
167 server_hostname_, | 168 server_hostname_, |
168 cached->server_config(), | 169 cached->server_config(), |
169 cached->certs(), | 170 cached->certs(), |
170 cached->signature(), | 171 cached->signature(), |
171 &error_details_, | 172 &error_details_, |
172 base::Bind(&QuicCryptoClientStream::OnVerifyProofComplete, | 173 base::Bind(&QuicCryptoClientStream::OnVerifyProofComplete, |
173 weak_factory_.GetWeakPtr())); | 174 weak_factory_.GetWeakPtr())); |
174 if (result == ERR_IO_PENDING) { | 175 if (result == ERR_IO_PENDING) { |
175 DVLOG(1) << "Doing VerifyProof"; | 176 DVLOG(1) << "Doing VerifyProof"; |
176 return; | 177 return; |
177 } | 178 } |
178 break; | 179 break; |
179 } | 180 } |
180 case STATE_VERIFY_PROOF_COMPLETED: { | 181 case STATE_VERIFY_PROOF_COMPLETE: |
181 if (result != OK) { | 182 if (result != OK) { |
182 CloseConnectionWithDetails( | 183 CloseConnectionWithDetails( |
183 QUIC_PROOF_INVALID, "Proof invalid: " + error_details_); | 184 QUIC_PROOF_INVALID, "Proof invalid: " + error_details_); |
184 return; | 185 return; |
185 } | 186 } |
186 ProofVerifier* verifier = session()->proof_verifier(); | |
187 DCHECK(verifier); | |
188 // Check if generation_counter has changed between STATE_VERIFY_PROOF | 187 // Check if generation_counter has changed between STATE_VERIFY_PROOF |
189 // and STATE_VERIFY_PROOF_COMPLETED state changes. | 188 // and STATE_VERIFY_PROOF_COMPLETE state changes. |
190 if (generation_counter_ != cached->generation_counter()) { | 189 if (generation_counter_ != cached->generation_counter()) { |
191 next_state_ = STATE_VERIFY_PROOF; | 190 next_state_ = STATE_VERIFY_PROOF; |
192 continue; | 191 } else { |
| 192 cached->SetProofValid(); |
| 193 next_state_ = STATE_SEND_CHLO; |
193 } | 194 } |
194 cached->SetProofValid(); | |
195 next_state_ = STATE_SEND_CHLO; | |
196 break; | 195 break; |
197 } | |
198 case STATE_RECV_SHLO: { | 196 case STATE_RECV_SHLO: { |
199 // We sent a CHLO that we expected to be accepted and now we're hoping | 197 // We sent a CHLO that we expected to be accepted and now we're hoping |
200 // for a SHLO from the server to confirm that. | 198 // for a SHLO from the server to confirm that. |
201 if (in->tag() == kREJ) { | 199 if (in->tag() == kREJ) { |
202 // alternative_decrypter will be NULL if the original alternative | 200 // alternative_decrypter will be NULL if the original alternative |
203 // decrypter latched and became the primary decrypter. That happens | 201 // decrypter latched and became the primary decrypter. That happens |
204 // if we received a message encrypted with the INITIAL key. | 202 // if we received a message encrypted with the INITIAL key. |
205 if (session()->connection()->alternative_decrypter() == NULL) { | 203 if (session()->connection()->alternative_decrypter() == NULL) { |
206 // The rejection was sent encrypted! | 204 // The rejection was sent encrypted! |
207 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 205 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 } | 256 } |
259 case STATE_IDLE: | 257 case STATE_IDLE: |
260 // This means that the peer sent us a message that we weren't expecting. | 258 // This means that the peer sent us a message that we weren't expecting. |
261 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 259 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); |
262 return; | 260 return; |
263 } | 261 } |
264 } | 262 } |
265 } | 263 } |
266 | 264 |
267 void QuicCryptoClientStream::OnVerifyProofComplete(int result) { | 265 void QuicCryptoClientStream::OnVerifyProofComplete(int result) { |
268 DCHECK_EQ(STATE_VERIFY_PROOF_COMPLETED, next_state_); | 266 DCHECK_EQ(STATE_VERIFY_PROOF_COMPLETE, next_state_); |
269 DVLOG(1) << "VerifyProof completed: " << result; | 267 DVLOG(1) << "VerifyProof completed: " << result; |
270 DoHandshakeLoop(NULL, result); | 268 DoHandshakeLoop(NULL, result); |
271 } | 269 } |
272 | 270 |
273 } // namespace net | 271 } // namespace net |
OLD | NEW |