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 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_crypto_client_stream.h" 6 7 #include "base/metrics/histogram.h" 8 #include "net/quic/crypto/crypto_protocol.h" 9 #include "net/quic/crypto/crypto_utils.h" 10 #include "net/quic/crypto/null_encrypter.h" 11 #include "net/quic/quic_client_session_base.h" 12 #include "net/quic/quic_protocol.h" 13 #include "net/quic/quic_session.h" 14 15 namespace net { 16 17 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: 18 ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream) 19 : stream_(stream) {} 20 21 QuicCryptoClientStream::ChannelIDSourceCallbackImpl:: 22 ~ChannelIDSourceCallbackImpl() {} 23 24 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run( 25 scoped_ptr<ChannelIDKey>* channel_id_key) { 26 if (stream_ == NULL) { 27 return; 28 } 29 30 stream_->channel_id_key_.reset(channel_id_key->release()); 31 stream_->channel_id_source_callback_run_ = true; 32 stream_->channel_id_source_callback_ = NULL; 33 stream_->DoHandshakeLoop(NULL); 34 35 // The ChannelIDSource owns this object and will delete it when this method 36 // returns. 37 } 38 39 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() { 40 stream_ = NULL; 41 } 42 43 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( 44 QuicCryptoClientStream* stream) 45 : stream_(stream) {} 46 47 QuicCryptoClientStream::ProofVerifierCallbackImpl:: 48 ~ProofVerifierCallbackImpl() {} 49 50 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( 51 bool ok, 52 const string& error_details, 53 scoped_ptr<ProofVerifyDetails>* details) { 54 if (stream_ == NULL) { 55 return; 56 } 57 58 stream_->verify_ok_ = ok; 59 stream_->verify_error_details_ = error_details; 60 stream_->verify_details_.reset(details->release()); 61 stream_->proof_verify_callback_ = NULL; 62 stream_->DoHandshakeLoop(NULL); 63 64 // The ProofVerifier owns this object and will delete it when this method 65 // returns. 66 } 67 68 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { 69 stream_ = NULL; 70 } 71 72 QuicCryptoClientStream::QuicCryptoClientStream( 73 const QuicServerId& server_id, 74 QuicClientSessionBase* session, 75 ProofVerifyContext* verify_context, 76 QuicCryptoClientConfig* crypto_config) 77 : QuicCryptoStream(session), 78 next_state_(STATE_IDLE), 79 num_client_hellos_(0), 80 crypto_config_(crypto_config), 81 server_id_(server_id), 82 generation_counter_(0), 83 channel_id_sent_(false), 84 channel_id_source_callback_run_(false), 85 channel_id_source_callback_(NULL), 86 verify_context_(verify_context), 87 proof_verify_callback_(NULL) { 88 } 89 90 QuicCryptoClientStream::~QuicCryptoClientStream() { 91 if (channel_id_source_callback_) { 92 channel_id_source_callback_->Cancel(); 93 } 94 if (proof_verify_callback_) { 95 proof_verify_callback_->Cancel(); 96 } 97 } 98 99 void QuicCryptoClientStream::OnHandshakeMessage( 100 const CryptoHandshakeMessage& message) { 101 QuicCryptoStream::OnHandshakeMessage(message); 102 103 if (message.tag() == kSCUP) { 104 if (!handshake_confirmed()) { 105 CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE); 106 return; 107 } 108 109 // |message| is an update from the server, so we treat it differently from a 110 // handshake message. 111 HandleServerConfigUpdateMessage(message); 112 return; 113 } 114 115 // Do not process handshake messages after the handshake is confirmed. 116 if (handshake_confirmed()) { 117 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE); 118 return; 119 } 120 121 DoHandshakeLoop(&message); 122 } 123 124 bool QuicCryptoClientStream::CryptoConnect() { 125 next_state_ = STATE_INITIALIZE; 126 DoHandshakeLoop(NULL); 127 return true; 128 } 129 130 int QuicCryptoClientStream::num_sent_client_hellos() const { 131 return num_client_hellos_; 132 } 133 134 bool QuicCryptoClientStream::WasChannelIDSent() const { 135 return channel_id_sent_; 136 } 137 138 bool QuicCryptoClientStream::WasChannelIDSourceCallbackRun() const { 139 return channel_id_source_callback_run_; 140 } 141 142 void QuicCryptoClientStream::HandleServerConfigUpdateMessage( 143 const CryptoHandshakeMessage& server_config_update) { 144 DCHECK(server_config_update.tag() == kSCUP); 145 string error_details; 146 QuicCryptoClientConfig::CachedState* cached = 147 crypto_config_->LookupOrCreate(server_id_); 148 QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate( 149 server_config_update, 150 session()->connection()->clock()->WallNow(), 151 cached, 152 &crypto_negotiated_params_, 153 &error_details); 154 155 if (error != QUIC_NO_ERROR) { 156 CloseConnectionWithDetails( 157 error, "Server config update invalid: " + error_details); 158 return; 159 } 160 161 DCHECK(handshake_confirmed()); 162 if (proof_verify_callback_) { 163 proof_verify_callback_->Cancel(); 164 } 165 next_state_ = STATE_INITIALIZE_SCUP; 166 DoHandshakeLoop(NULL); 167 } 168 169 // kMaxClientHellos is the maximum number of times that we'll send a client 170 // hello. The value 3 accounts for: 171 // * One failure due to an incorrect or missing source-address token. 172 // * 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. 174 static const int kMaxClientHellos = 3; 175 176 void QuicCryptoClientStream::DoHandshakeLoop( 177 const CryptoHandshakeMessage* in) { 178 CryptoHandshakeMessage out; 179 QuicErrorCode error; 180 string error_details; 181 QuicCryptoClientConfig::CachedState* cached = 182 crypto_config_->LookupOrCreate(server_id_); 183 184 for (;;) { 185 const State state = next_state_; 186 next_state_ = STATE_IDLE; 187 switch (state) { 188 case STATE_INITIALIZE: { 189 if (!cached->IsEmpty() && !cached->signature().empty() && 190 server_id_.is_https()) { 191 // Note that we verify the proof even if the cached proof is valid. 192 // This allows us to respond to CA trust changes or certificate 193 // expiration because it may have been a while since we last verified 194 // the proof. 195 DCHECK(crypto_config_->proof_verifier()); 196 // If the cached state needs to be verified, do it now. 197 next_state_ = STATE_VERIFY_PROOF; 198 } else { 199 next_state_ = STATE_GET_CHANNEL_ID; 200 } 201 break; 202 } 203 case STATE_SEND_CHLO: { 204 // Send the client hello in plaintext. 205 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); 206 if (num_client_hellos_ > kMaxClientHellos) { 207 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); 208 return; 209 } 210 num_client_hellos_++; 211 212 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { 213 crypto_config_->FillInchoateClientHello( 214 server_id_, 215 session()->connection()->supported_versions().front(), 216 cached, &crypto_negotiated_params_, &out); 217 // Pad the inchoate client hello to fill up a packet. 218 const size_t kFramingOverhead = 50; // A rough estimate. 219 const size_t max_packet_size = 220 session()->connection()->max_packet_length(); 221 if (max_packet_size <= kFramingOverhead) { 222 DLOG(DFATAL) << "max_packet_length (" << max_packet_size 223 << ") has no room for framing overhead."; 224 CloseConnection(QUIC_INTERNAL_ERROR); 225 return; 226 } 227 if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) { 228 DLOG(DFATAL) << "Client hello won't fit in a single packet."; 229 CloseConnection(QUIC_INTERNAL_ERROR); 230 return; 231 } 232 out.set_minimum_size(max_packet_size - kFramingOverhead); 233 next_state_ = STATE_RECV_REJ; 234 SendHandshakeMessage(out); 235 return; 236 } 237 session()->config()->ToHandshakeMessage(&out); 238 error = crypto_config_->FillClientHello( 239 server_id_, 240 session()->connection()->connection_id(), 241 session()->connection()->supported_versions().front(), 242 cached, 243 session()->connection()->clock()->WallNow(), 244 session()->connection()->random_generator(), 245 channel_id_key_.get(), 246 &crypto_negotiated_params_, 247 &out, 248 &error_details); 249 if (error != QUIC_NO_ERROR) { 250 // Flush the cached config so that, if it's bad, the server has a 251 // chance to send us another in the future. 252 cached->InvalidateServerConfig(); 253 CloseConnectionWithDetails(error, error_details); 254 return; 255 } 256 channel_id_sent_ = (channel_id_key_.get() != NULL); 257 if (cached->proof_verify_details()) { 258 client_session()->OnProofVerifyDetailsAvailable( 259 *cached->proof_verify_details()); 260 } 261 next_state_ = STATE_RECV_SHLO; 262 SendHandshakeMessage(out); 263 // Be prepared to decrypt with the new server write key. 264 session()->connection()->SetAlternativeDecrypter( 265 crypto_negotiated_params_.initial_crypters.decrypter.release(), 266 ENCRYPTION_INITIAL, 267 true /* latch once used */); 268 // Send subsequent packets under encryption on the assumption that the 269 // server will accept the handshake. 270 session()->connection()->SetEncrypter( 271 ENCRYPTION_INITIAL, 272 crypto_negotiated_params_.initial_crypters.encrypter.release()); 273 session()->connection()->SetDefaultEncryptionLevel( 274 ENCRYPTION_INITIAL); 275 if (!encryption_established_) { 276 encryption_established_ = true; 277 session()->OnCryptoHandshakeEvent( 278 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); 279 } else { 280 session()->OnCryptoHandshakeEvent( 281 QuicSession::ENCRYPTION_REESTABLISHED); 282 } 283 return; 284 } 285 case STATE_RECV_REJ: 286 // We sent a dummy CHLO because we didn't have enough information to 287 // perform a handshake, or we sent a full hello that the server 288 // rejected. Here we hope to have a REJ that contains the information 289 // that we need. 290 if (in->tag() != kREJ) { 291 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, 292 "Expected REJ"); 293 return; 294 } 295 error = crypto_config_->ProcessRejection( 296 *in, session()->connection()->clock()->WallNow(), cached, 297 server_id_.is_https(), &crypto_negotiated_params_, &error_details); 298 if (error != QUIC_NO_ERROR) { 299 CloseConnectionWithDetails(error, error_details); 300 return; 301 } 302 if (!cached->proof_valid()) { 303 if (!server_id_.is_https()) { 304 // We don't check the certificates for insecure QUIC connections. 305 SetCachedProofValid(cached); 306 } else if (!cached->signature().empty()) { 307 // Note that we only verify the proof if the cached proof is not 308 // valid. If the cached proof is valid here, someone else must have 309 // just added the server config to the cache and verified the proof, 310 // so we can assume no CA trust changes or certificate expiration 311 // has happened since then. 312 next_state_ = STATE_VERIFY_PROOF; 313 break; 314 } 315 } 316 next_state_ = STATE_GET_CHANNEL_ID; 317 break; 318 case STATE_VERIFY_PROOF: { 319 if (QUIC_PENDING == DoVerifyProof(cached)) { 320 return; 321 } 322 break; 323 } 324 case STATE_VERIFY_PROOF_COMPLETE: 325 if (QUIC_PROOF_INVALID == DoVerifyProofComplete(cached)) { 326 return; 327 } 328 break; 329 case STATE_GET_CHANNEL_ID: { 330 next_state_ = STATE_GET_CHANNEL_ID_COMPLETE; 331 channel_id_key_.reset(); 332 if (!RequiresChannelID(cached)) { 333 next_state_ = STATE_SEND_CHLO; 334 break; 335 } 336 337 ChannelIDSourceCallbackImpl* channel_id_source_callback = 338 new ChannelIDSourceCallbackImpl(this); 339 QuicAsyncStatus status = 340 crypto_config_->channel_id_source()->GetChannelIDKey( 341 server_id_.host(), &channel_id_key_, 342 channel_id_source_callback); 343 344 switch (status) { 345 case QUIC_PENDING: 346 channel_id_source_callback_ = channel_id_source_callback; 347 DVLOG(1) << "Looking up channel ID"; 348 return; 349 case QUIC_FAILURE: 350 delete channel_id_source_callback; 351 CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE, 352 "Channel ID lookup failed"); 353 return; 354 case QUIC_SUCCESS: 355 delete channel_id_source_callback; 356 break; 357 } 358 break; 359 } 360 case STATE_GET_CHANNEL_ID_COMPLETE: 361 if (!channel_id_key_.get()) { 362 CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE, 363 "Channel ID lookup failed"); 364 return; 365 } 366 next_state_ = STATE_SEND_CHLO; 367 break; 368 case STATE_RECV_SHLO: { 369 // We sent a CHLO that we expected to be accepted and now we're hoping 370 // for a SHLO from the server to confirm that. 371 if (in->tag() == kREJ) { 372 // alternative_decrypter will be NULL if the original alternative 373 // decrypter latched and became the primary decrypter. That happens 374 // if we received a message encrypted with the INITIAL key. 375 if (session()->connection()->alternative_decrypter() == NULL) { 376 // The rejection was sent encrypted! 377 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, 378 "encrypted REJ message"); 379 return; 380 } 381 next_state_ = STATE_RECV_REJ; 382 break; 383 } 384 if (in->tag() != kSHLO) { 385 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, 386 "Expected SHLO or REJ"); 387 return; 388 } 389 // alternative_decrypter will be NULL if the original alternative 390 // decrypter latched and became the primary decrypter. That happens 391 // if we received a message encrypted with the INITIAL key. 392 if (session()->connection()->alternative_decrypter() != NULL) { 393 // The server hello was sent without encryption. 394 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, 395 "unencrypted SHLO message"); 396 return; 397 } 398 error = crypto_config_->ProcessServerHello( 399 *in, session()->connection()->connection_id(), 400 session()->connection()->server_supported_versions(), 401 cached, &crypto_negotiated_params_, &error_details); 402 403 if (error != QUIC_NO_ERROR) { 404 CloseConnectionWithDetails( 405 error, "Server hello invalid: " + error_details); 406 return; 407 } 408 error = 409 session()->config()->ProcessPeerHello(*in, SERVER, &error_details); 410 if (error != QUIC_NO_ERROR) { 411 CloseConnectionWithDetails( 412 error, "Server hello invalid: " + error_details); 413 return; 414 } 415 session()->OnConfigNegotiated(); 416 417 CrypterPair* crypters = 418 &crypto_negotiated_params_.forward_secure_crypters; 419 // TODO(agl): we don't currently latch this decrypter because the idea 420 // has been floated that the server shouldn't send packets encrypted 421 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE 422 // packet from the client. 423 session()->connection()->SetAlternativeDecrypter( 424 crypters->decrypter.release(), ENCRYPTION_FORWARD_SECURE, 425 false /* don't latch */); 426 session()->connection()->SetEncrypter( 427 ENCRYPTION_FORWARD_SECURE, crypters->encrypter.release()); 428 session()->connection()->SetDefaultEncryptionLevel( 429 ENCRYPTION_FORWARD_SECURE); 430 431 handshake_confirmed_ = true; 432 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 433 session()->connection()->OnHandshakeComplete(); 434 return; 435 } 436 case STATE_IDLE: 437 // This means that the peer sent us a message that we weren't expecting. 438 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 439 return; 440 case STATE_INITIALIZE_SCUP: 441 DoInitializeServerConfigUpdate(cached); 442 break; 443 case STATE_VERIFY_PROOF_DONE: 444 return; // We are done. 445 } 446 } 447 } 448 449 void QuicCryptoClientStream::DoInitializeServerConfigUpdate( 450 QuicCryptoClientConfig::CachedState* cached) { 451 bool update_ignored = false; 452 if (!server_id_.is_https()) { 453 // We don't check the certificates for insecure QUIC connections. 454 SetCachedProofValid(cached); 455 next_state_ = STATE_VERIFY_PROOF_DONE; 456 } else if (!cached->IsEmpty() && !cached->signature().empty()) { 457 // Note that we verify the proof even if the cached proof is valid. 458 DCHECK(crypto_config_->proof_verifier()); 459 next_state_ = STATE_VERIFY_PROOF; 460 } else { 461 update_ignored = true; 462 next_state_ = STATE_VERIFY_PROOF_DONE; 463 } 464 UMA_HISTOGRAM_BOOLEAN("Net.QuicNumServerConfig.UpdateMessagesIgnored", 465 update_ignored); 466 } 467 468 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof( 469 QuicCryptoClientConfig::CachedState* cached) { 470 ProofVerifier* verifier = crypto_config_->proof_verifier(); 471 DCHECK(verifier); 472 next_state_ = STATE_VERIFY_PROOF_COMPLETE; 473 generation_counter_ = cached->generation_counter(); 474 475 ProofVerifierCallbackImpl* proof_verify_callback = 476 new ProofVerifierCallbackImpl(this); 477 478 verify_ok_ = false; 479 480 QuicAsyncStatus status = verifier->VerifyProof( 481 server_id_.host(), 482 cached->server_config(), 483 cached->certs(), 484 cached->signature(), 485 verify_context_.get(), 486 &verify_error_details_, 487 &verify_details_, 488 proof_verify_callback); 489 490 switch (status) { 491 case QUIC_PENDING: 492 proof_verify_callback_ = proof_verify_callback; 493 DVLOG(1) << "Doing VerifyProof"; 494 break; 495 case QUIC_FAILURE: 496 delete proof_verify_callback; 497 break; 498 case QUIC_SUCCESS: 499 delete proof_verify_callback; 500 verify_ok_ = true; 501 break; 502 } 503 return status; 504 } 505 506 QuicErrorCode QuicCryptoClientStream::DoVerifyProofComplete( 507 QuicCryptoClientConfig::CachedState* cached) { 508 if (!verify_ok_) { 509 client_session()->OnProofVerifyDetailsAvailable(*verify_details_); 510 UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed", 511 handshake_confirmed()); 512 CloseConnectionWithDetails( 513 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); 514 return QUIC_PROOF_INVALID; 515 } 516 517 // Check if generation_counter has changed between STATE_VERIFY_PROOF and 518 // STATE_VERIFY_PROOF_COMPLETE state changes. 519 if (generation_counter_ != cached->generation_counter()) { 520 next_state_ = STATE_VERIFY_PROOF; 521 } else { 522 SetCachedProofValid(cached); 523 cached->SetProofVerifyDetails(verify_details_.release()); 524 if (!handshake_confirmed()) { 525 next_state_ = STATE_GET_CHANNEL_ID; 526 } else { 527 next_state_ = STATE_VERIFY_PROOF_DONE; 528 } 529 } 530 return QUIC_NO_ERROR; 531 } 532 533 void QuicCryptoClientStream::SetCachedProofValid( 534 QuicCryptoClientConfig::CachedState* cached) { 535 cached->SetProofValid(); 536 client_session()->OnProofValid(*cached); 537 } 538 539 bool QuicCryptoClientStream::RequiresChannelID( 540 QuicCryptoClientConfig::CachedState* cached) { 541 if (!server_id_.is_https() || 542 server_id_.privacy_mode() == PRIVACY_MODE_ENABLED || 543 !crypto_config_->channel_id_source()) { 544 return false; 545 } 546 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); 547 if (!scfg) { // scfg may be null when we send an inchoate CHLO. 548 return false; 549 } 550 const QuicTag* their_proof_demands; 551 size_t num_their_proof_demands; 552 if (scfg->GetTaglist(kPDMD, &their_proof_demands, 553 &num_their_proof_demands) != QUIC_NO_ERROR) { 554 return false; 555 } 556 for (size_t i = 0; i < num_their_proof_demands; i++) { 557 if (their_proof_demands[i] == kCHID) { 558 return true; 559 } 560 } 561 return false; 562 } 563 564 QuicClientSessionBase* QuicCryptoClientStream::client_session() { 565 return reinterpret_cast<QuicClientSessionBase*>(session()); 566 } 567 568 } // namespace net 569