| 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/quic/crypto/crypto_protocol.h" | 7 #include "net/quic/crypto/crypto_protocol.h" |
| 8 #include "net/quic/crypto/crypto_utils.h" | 8 #include "net/quic/crypto/crypto_utils.h" |
| 9 #include "net/quic/crypto/null_encrypter.h" | 9 #include "net/quic/crypto/null_encrypter.h" |
| 10 #include "net/quic/crypto/proof_verifier.h" | 10 #include "net/quic/crypto/proof_verifier.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::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( | 17 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( |
| 18 QuicCryptoClientStream* stream) | 18 QuicCryptoClientStream* stream) |
| 19 : stream_(stream) {} | 19 : stream_(stream) { |
| 20 } |
| 20 | 21 |
| 21 QuicCryptoClientStream::ProofVerifierCallbackImpl:: | 22 QuicCryptoClientStream::ProofVerifierCallbackImpl:: |
| 22 ~ProofVerifierCallbackImpl() {} | 23 ~ProofVerifierCallbackImpl() { |
| 24 } |
| 23 | 25 |
| 24 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( | 26 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( |
| 25 bool ok, | 27 bool ok, |
| 26 const string& error_details, | 28 const string& error_details, |
| 27 scoped_ptr<ProofVerifyDetails>* details) { | 29 scoped_ptr<ProofVerifyDetails>* details) { |
| 28 if (stream_ == NULL) { | 30 if (stream_ == NULL) { |
| 29 return; | 31 return; |
| 30 } | 32 } |
| 31 | 33 |
| 32 stream_->verify_ok_ = ok; | 34 stream_->verify_ok_ = ok; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 return num_client_hellos_; | 83 return num_client_hellos_; |
| 82 } | 84 } |
| 83 | 85 |
| 84 // kMaxClientHellos is the maximum number of times that we'll send a client | 86 // kMaxClientHellos is the maximum number of times that we'll send a client |
| 85 // hello. The value 3 accounts for: | 87 // hello. The value 3 accounts for: |
| 86 // * One failure due to an incorrect or missing source-address token. | 88 // * One failure due to an incorrect or missing source-address token. |
| 87 // * One failure due the server's certificate chain being unavailible and the | 89 // * One failure due the server's certificate chain being unavailible and the |
| 88 // server being unwilling to send it without a valid source-address token. | 90 // server being unwilling to send it without a valid source-address token. |
| 89 static const int kMaxClientHellos = 3; | 91 static const int kMaxClientHellos = 3; |
| 90 | 92 |
| 91 void QuicCryptoClientStream::DoHandshakeLoop( | 93 void QuicCryptoClientStream::DoHandshakeLoop(const CryptoHandshakeMessage* in) { |
| 92 const CryptoHandshakeMessage* in) { | |
| 93 CryptoHandshakeMessage out; | 94 CryptoHandshakeMessage out; |
| 94 QuicErrorCode error; | 95 QuicErrorCode error; |
| 95 string error_details; | 96 string error_details; |
| 96 QuicCryptoClientConfig::CachedState* cached = | 97 QuicCryptoClientConfig::CachedState* cached = |
| 97 crypto_config_->LookupOrCreate(server_id_); | 98 crypto_config_->LookupOrCreate(server_id_); |
| 98 | 99 |
| 99 if (in != NULL) { | 100 if (in != NULL) { |
| 100 DVLOG(1) << "Client: Received " << in->DebugString(); | 101 DVLOG(1) << "Client: Received " << in->DebugString(); |
| 101 } | 102 } |
| 102 | 103 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 121 if (num_client_hellos_ > kMaxClientHellos) { | 122 if (num_client_hellos_ > kMaxClientHellos) { |
| 122 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); | 123 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); |
| 123 return; | 124 return; |
| 124 } | 125 } |
| 125 num_client_hellos_++; | 126 num_client_hellos_++; |
| 126 | 127 |
| 127 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { | 128 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { |
| 128 crypto_config_->FillInchoateClientHello( | 129 crypto_config_->FillInchoateClientHello( |
| 129 server_id_, | 130 server_id_, |
| 130 session()->connection()->supported_versions().front(), | 131 session()->connection()->supported_versions().front(), |
| 131 cached, &crypto_negotiated_params_, &out); | 132 cached, |
| 133 &crypto_negotiated_params_, |
| 134 &out); |
| 132 // Pad the inchoate client hello to fill up a packet. | 135 // Pad the inchoate client hello to fill up a packet. |
| 133 const size_t kFramingOverhead = 50; // A rough estimate. | 136 const size_t kFramingOverhead = 50; // A rough estimate. |
| 134 const size_t max_packet_size = | 137 const size_t max_packet_size = |
| 135 session()->connection()->options()->max_packet_length; | 138 session()->connection()->options()->max_packet_length; |
| 136 if (max_packet_size <= kFramingOverhead) { | 139 if (max_packet_size <= kFramingOverhead) { |
| 137 DLOG(DFATAL) << "max_packet_length (" << max_packet_size | 140 DLOG(DFATAL) << "max_packet_length (" << max_packet_size |
| 138 << ") has no room for framing overhead."; | 141 << ") has no room for framing overhead."; |
| 139 CloseConnection(QUIC_INTERNAL_ERROR); | 142 CloseConnection(QUIC_INTERNAL_ERROR); |
| 140 return; | 143 return; |
| 141 } | 144 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 // Be prepared to decrypt with the new server write key. | 182 // Be prepared to decrypt with the new server write key. |
| 180 session()->connection()->SetAlternativeDecrypter( | 183 session()->connection()->SetAlternativeDecrypter( |
| 181 crypto_negotiated_params_.initial_crypters.decrypter.release(), | 184 crypto_negotiated_params_.initial_crypters.decrypter.release(), |
| 182 ENCRYPTION_INITIAL, | 185 ENCRYPTION_INITIAL, |
| 183 true /* latch once used */); | 186 true /* latch once used */); |
| 184 // Send subsequent packets under encryption on the assumption that the | 187 // Send subsequent packets under encryption on the assumption that the |
| 185 // server will accept the handshake. | 188 // server will accept the handshake. |
| 186 session()->connection()->SetEncrypter( | 189 session()->connection()->SetEncrypter( |
| 187 ENCRYPTION_INITIAL, | 190 ENCRYPTION_INITIAL, |
| 188 crypto_negotiated_params_.initial_crypters.encrypter.release()); | 191 crypto_negotiated_params_.initial_crypters.encrypter.release()); |
| 189 session()->connection()->SetDefaultEncryptionLevel( | 192 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); |
| 190 ENCRYPTION_INITIAL); | |
| 191 if (!encryption_established_) { | 193 if (!encryption_established_) { |
| 192 encryption_established_ = true; | 194 encryption_established_ = true; |
| 193 session()->OnCryptoHandshakeEvent( | 195 session()->OnCryptoHandshakeEvent( |
| 194 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); | 196 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); |
| 195 } else { | 197 } else { |
| 196 session()->OnCryptoHandshakeEvent( | 198 session()->OnCryptoHandshakeEvent( |
| 197 QuicSession::ENCRYPTION_REESTABLISHED); | 199 QuicSession::ENCRYPTION_REESTABLISHED); |
| 198 } | 200 } |
| 199 return; | 201 return; |
| 200 } | 202 } |
| 201 case STATE_RECV_REJ: | 203 case STATE_RECV_REJ: |
| 202 // We sent a dummy CHLO because we didn't have enough information to | 204 // We sent a dummy CHLO because we didn't have enough information to |
| 203 // perform a handshake, or we sent a full hello that the server | 205 // perform a handshake, or we sent a full hello that the server |
| 204 // rejected. Here we hope to have a REJ that contains the information | 206 // rejected. Here we hope to have a REJ that contains the information |
| 205 // that we need. | 207 // that we need. |
| 206 if (in->tag() != kREJ) { | 208 if (in->tag() != kREJ) { |
| 207 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, | 209 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, |
| 208 "Expected REJ"); | 210 "Expected REJ"); |
| 209 return; | 211 return; |
| 210 } | 212 } |
| 211 error = crypto_config_->ProcessRejection( | 213 error = crypto_config_->ProcessRejection( |
| 212 *in, session()->connection()->clock()->WallNow(), cached, | 214 *in, |
| 213 &crypto_negotiated_params_, &error_details); | 215 session()->connection()->clock()->WallNow(), |
| 216 cached, |
| 217 &crypto_negotiated_params_, |
| 218 &error_details); |
| 214 if (error != QUIC_NO_ERROR) { | 219 if (error != QUIC_NO_ERROR) { |
| 215 CloseConnectionWithDetails(error, error_details); | 220 CloseConnectionWithDetails(error, error_details); |
| 216 return; | 221 return; |
| 217 } | 222 } |
| 218 if (!cached->proof_valid()) { | 223 if (!cached->proof_valid()) { |
| 219 if (!server_id_.is_https()) { | 224 if (!server_id_.is_https()) { |
| 220 // We don't check the certificates for insecure QUIC connections. | 225 // We don't check the certificates for insecure QUIC connections. |
| 221 SetCachedProofValid(cached); | 226 SetCachedProofValid(cached); |
| 222 } else if (!cached->signature().empty()) { | 227 } else if (!cached->signature().empty()) { |
| 223 next_state_ = STATE_VERIFY_PROOF; | 228 next_state_ = STATE_VERIFY_PROOF; |
| 224 break; | 229 break; |
| 225 } | 230 } |
| 226 } | 231 } |
| 227 next_state_ = STATE_SEND_CHLO; | 232 next_state_ = STATE_SEND_CHLO; |
| 228 break; | 233 break; |
| 229 case STATE_VERIFY_PROOF: { | 234 case STATE_VERIFY_PROOF: { |
| 230 ProofVerifier* verifier = crypto_config_->proof_verifier(); | 235 ProofVerifier* verifier = crypto_config_->proof_verifier(); |
| 231 DCHECK(verifier); | 236 DCHECK(verifier); |
| 232 next_state_ = STATE_VERIFY_PROOF_COMPLETE; | 237 next_state_ = STATE_VERIFY_PROOF_COMPLETE; |
| 233 generation_counter_ = cached->generation_counter(); | 238 generation_counter_ = cached->generation_counter(); |
| 234 | 239 |
| 235 ProofVerifierCallbackImpl* proof_verify_callback = | 240 ProofVerifierCallbackImpl* proof_verify_callback = |
| 236 new ProofVerifierCallbackImpl(this); | 241 new ProofVerifierCallbackImpl(this); |
| 237 | 242 |
| 238 verify_ok_ = false; | 243 verify_ok_ = false; |
| 239 | 244 |
| 240 ProofVerifier::Status status = verifier->VerifyProof( | 245 ProofVerifier::Status status = |
| 241 server_id_.host(), | 246 verifier->VerifyProof(server_id_.host(), |
| 242 cached->server_config(), | 247 cached->server_config(), |
| 243 cached->certs(), | 248 cached->certs(), |
| 244 cached->signature(), | 249 cached->signature(), |
| 245 verify_context_.get(), | 250 verify_context_.get(), |
| 246 &verify_error_details_, | 251 &verify_error_details_, |
| 247 &verify_details_, | 252 &verify_details_, |
| 248 proof_verify_callback); | 253 proof_verify_callback); |
| 249 | 254 |
| 250 switch (status) { | 255 switch (status) { |
| 251 case ProofVerifier::PENDING: | 256 case ProofVerifier::PENDING: |
| 252 proof_verify_callback_ = proof_verify_callback; | 257 proof_verify_callback_ = proof_verify_callback; |
| 253 DVLOG(1) << "Doing VerifyProof"; | 258 DVLOG(1) << "Doing VerifyProof"; |
| 254 return; | 259 return; |
| 255 case ProofVerifier::FAILURE: | 260 case ProofVerifier::FAILURE: |
| 256 delete proof_verify_callback; | 261 delete proof_verify_callback; |
| 257 break; | 262 break; |
| 258 case ProofVerifier::SUCCESS: | 263 case ProofVerifier::SUCCESS: |
| 259 delete proof_verify_callback; | 264 delete proof_verify_callback; |
| 260 verify_ok_ = true; | 265 verify_ok_ = true; |
| 261 break; | 266 break; |
| 262 } | 267 } |
| 263 break; | 268 break; |
| 264 } | 269 } |
| 265 case STATE_VERIFY_PROOF_COMPLETE: | 270 case STATE_VERIFY_PROOF_COMPLETE: |
| 266 if (!verify_ok_) { | 271 if (!verify_ok_) { |
| 267 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); | 272 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); |
| 268 CloseConnectionWithDetails( | 273 CloseConnectionWithDetails(QUIC_PROOF_INVALID, |
| 269 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); | 274 "Proof invalid: " + verify_error_details_); |
| 270 return; | 275 return; |
| 271 } | 276 } |
| 272 // Check if generation_counter has changed between STATE_VERIFY_PROOF | 277 // Check if generation_counter has changed between STATE_VERIFY_PROOF |
| 273 // and STATE_VERIFY_PROOF_COMPLETE state changes. | 278 // and STATE_VERIFY_PROOF_COMPLETE state changes. |
| 274 if (generation_counter_ != cached->generation_counter()) { | 279 if (generation_counter_ != cached->generation_counter()) { |
| 275 next_state_ = STATE_VERIFY_PROOF; | 280 next_state_ = STATE_VERIFY_PROOF; |
| 276 } else { | 281 } else { |
| 277 SetCachedProofValid(cached); | 282 SetCachedProofValid(cached); |
| 278 cached->SetProofVerifyDetails(verify_details_.release()); | 283 cached->SetProofVerifyDetails(verify_details_.release()); |
| 279 next_state_ = STATE_SEND_CHLO; | 284 next_state_ = STATE_SEND_CHLO; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 303 // alternative_decrypter will be NULL if the original alternative | 308 // alternative_decrypter will be NULL if the original alternative |
| 304 // decrypter latched and became the primary decrypter. That happens | 309 // decrypter latched and became the primary decrypter. That happens |
| 305 // if we received a message encrypted with the INITIAL key. | 310 // if we received a message encrypted with the INITIAL key. |
| 306 if (session()->connection()->alternative_decrypter() != NULL) { | 311 if (session()->connection()->alternative_decrypter() != NULL) { |
| 307 // The server hello was sent without encryption. | 312 // The server hello was sent without encryption. |
| 308 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, | 313 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, |
| 309 "unencrypted SHLO message"); | 314 "unencrypted SHLO message"); |
| 310 return; | 315 return; |
| 311 } | 316 } |
| 312 error = crypto_config_->ProcessServerHello( | 317 error = crypto_config_->ProcessServerHello( |
| 313 *in, session()->connection()->connection_id(), | 318 *in, |
| 319 session()->connection()->connection_id(), |
| 314 session()->connection()->server_supported_versions(), | 320 session()->connection()->server_supported_versions(), |
| 315 cached, &crypto_negotiated_params_, &error_details); | 321 cached, |
| 322 &crypto_negotiated_params_, |
| 323 &error_details); |
| 316 | 324 |
| 317 if (error != QUIC_NO_ERROR) { | 325 if (error != QUIC_NO_ERROR) { |
| 318 CloseConnectionWithDetails( | 326 CloseConnectionWithDetails(error, |
| 319 error, "Server hello invalid: " + error_details); | 327 "Server hello invalid: " + error_details); |
| 320 return; | 328 return; |
| 321 } | 329 } |
| 322 error = | 330 error = |
| 323 session()->config()->ProcessPeerHello(*in, SERVER, &error_details); | 331 session()->config()->ProcessPeerHello(*in, SERVER, &error_details); |
| 324 if (error != QUIC_NO_ERROR) { | 332 if (error != QUIC_NO_ERROR) { |
| 325 CloseConnectionWithDetails( | 333 CloseConnectionWithDetails(error, |
| 326 error, "Server hello invalid: " + error_details); | 334 "Server hello invalid: " + error_details); |
| 327 return; | 335 return; |
| 328 } | 336 } |
| 329 session()->OnConfigNegotiated(); | 337 session()->OnConfigNegotiated(); |
| 330 | 338 |
| 331 CrypterPair* crypters = | 339 CrypterPair* crypters = |
| 332 &crypto_negotiated_params_.forward_secure_crypters; | 340 &crypto_negotiated_params_.forward_secure_crypters; |
| 333 // TODO(agl): we don't currently latch this decrypter because the idea | 341 // TODO(agl): we don't currently latch this decrypter because the idea |
| 334 // has been floated that the server shouldn't send packets encrypted | 342 // has been floated that the server shouldn't send packets encrypted |
| 335 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE | 343 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE |
| 336 // packet from the client. | 344 // packet from the client. |
| 337 session()->connection()->SetAlternativeDecrypter( | 345 session()->connection()->SetAlternativeDecrypter( |
| 338 crypters->decrypter.release(), ENCRYPTION_FORWARD_SECURE, | 346 crypters->decrypter.release(), |
| 347 ENCRYPTION_FORWARD_SECURE, |
| 339 false /* don't latch */); | 348 false /* don't latch */); |
| 340 session()->connection()->SetEncrypter( | 349 session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE, |
| 341 ENCRYPTION_FORWARD_SECURE, crypters->encrypter.release()); | 350 crypters->encrypter.release()); |
| 342 session()->connection()->SetDefaultEncryptionLevel( | 351 session()->connection()->SetDefaultEncryptionLevel( |
| 343 ENCRYPTION_FORWARD_SECURE); | 352 ENCRYPTION_FORWARD_SECURE); |
| 344 | 353 |
| 345 handshake_confirmed_ = true; | 354 handshake_confirmed_ = true; |
| 346 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 355 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
| 347 return; | 356 return; |
| 348 } | 357 } |
| 349 case STATE_IDLE: | 358 case STATE_IDLE: |
| 350 // This means that the peer sent us a message that we weren't expecting. | 359 // This means that the peer sent us a message that we weren't expecting. |
| 351 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); | 360 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); |
| 352 return; | 361 return; |
| 353 } | 362 } |
| 354 } | 363 } |
| 355 } | 364 } |
| 356 | 365 |
| 357 void QuicCryptoClientStream::SetCachedProofValid( | 366 void QuicCryptoClientStream::SetCachedProofValid( |
| 358 QuicCryptoClientConfig::CachedState* cached) { | 367 QuicCryptoClientConfig::CachedState* cached) { |
| 359 cached->SetProofValid(); | 368 cached->SetProofValid(); |
| 360 client_session()->OnProofValid(*cached); | 369 client_session()->OnProofValid(*cached); |
| 361 } | 370 } |
| 362 | 371 |
| 363 QuicClientSessionBase* QuicCryptoClientStream::client_session() { | 372 QuicClientSessionBase* QuicCryptoClientStream::client_session() { |
| 364 return reinterpret_cast<QuicClientSessionBase*>(session()); | 373 return reinterpret_cast<QuicClientSessionBase*>(session()); |
| 365 } | 374 } |
| 366 | 375 |
| 367 } // namespace net | 376 } // namespace net |
| OLD | NEW |