| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 | 9 |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 StringPiece client_nonce; | 81 StringPiece client_nonce; |
| 82 StringPiece server_nonce; | 82 StringPiece server_nonce; |
| 83 }; | 83 }; |
| 84 | 84 |
| 85 struct ValidateClientHelloResultCallback::Result { | 85 struct ValidateClientHelloResultCallback::Result { |
| 86 Result(const CryptoHandshakeMessage& in_client_hello, | 86 Result(const CryptoHandshakeMessage& in_client_hello, |
| 87 IPEndPoint in_client_ip, | 87 IPEndPoint in_client_ip, |
| 88 QuicWallTime in_now) | 88 QuicWallTime in_now) |
| 89 : client_hello(in_client_hello), | 89 : client_hello(in_client_hello), |
| 90 info(in_client_ip, in_now), | 90 info(in_client_ip, in_now), |
| 91 error_code(QUIC_NO_ERROR) { | 91 error_code(QUIC_NO_ERROR) {} |
| 92 } | |
| 93 | 92 |
| 94 CryptoHandshakeMessage client_hello; | 93 CryptoHandshakeMessage client_hello; |
| 95 ClientHelloInfo info; | 94 ClientHelloInfo info; |
| 96 QuicErrorCode error_code; | 95 QuicErrorCode error_code; |
| 97 string error_details; | 96 string error_details; |
| 98 }; | 97 }; |
| 99 | 98 |
| 100 class ValidateClientHelloHelper { | 99 class ValidateClientHelloHelper { |
| 101 public: | 100 public: |
| 102 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, | 101 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, |
| 103 ValidateClientHelloResultCallback* done_cb) | 102 ValidateClientHelloResultCallback* done_cb) |
| 104 : result_(result), done_cb_(done_cb) { | 103 : result_(result), done_cb_(done_cb) {} |
| 105 } | |
| 106 | 104 |
| 107 ~ValidateClientHelloHelper() { | 105 ~ValidateClientHelloHelper() { |
| 108 LOG_IF(DFATAL, done_cb_ != NULL) | 106 LOG_IF(DFATAL, done_cb_ != NULL) |
| 109 << "Deleting ValidateClientHelloHelper with a pending callback."; | 107 << "Deleting ValidateClientHelloHelper with a pending callback."; |
| 110 } | 108 } |
| 111 | 109 |
| 112 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { | 110 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { |
| 113 result_->error_code = error_code; | 111 result_->error_code = error_code; |
| 114 result_->error_details = error_details; | 112 result_->error_details = error_details; |
| 115 done_cb_->Run(result_); | 113 done_cb_->Run(result_); |
| 116 DetachCallback(); | 114 DetachCallback(); |
| 117 } | 115 } |
| 118 | 116 |
| 119 void StartedAsyncCallback() { | 117 void StartedAsyncCallback() { DetachCallback(); } |
| 120 DetachCallback(); | |
| 121 } | |
| 122 | 118 |
| 123 private: | 119 private: |
| 124 void DetachCallback() { | 120 void DetachCallback() { |
| 125 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; | 121 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; |
| 126 done_cb_ = NULL; | 122 done_cb_ = NULL; |
| 127 } | 123 } |
| 128 | 124 |
| 129 ValidateClientHelloResultCallback::Result* result_; | 125 ValidateClientHelloResultCallback::Result* result_; |
| 130 ValidateClientHelloResultCallback* done_cb_; | 126 ValidateClientHelloResultCallback* done_cb_; |
| 131 | 127 |
| 132 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); | 128 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); |
| 133 }; | 129 }; |
| 134 | 130 |
| 135 class VerifyNonceIsValidAndUniqueCallback | 131 class VerifyNonceIsValidAndUniqueCallback |
| 136 : public StrikeRegisterClient::ResultCallback { | 132 : public StrikeRegisterClient::ResultCallback { |
| 137 public: | 133 public: |
| 138 VerifyNonceIsValidAndUniqueCallback( | 134 VerifyNonceIsValidAndUniqueCallback( |
| 139 ValidateClientHelloResultCallback::Result* result, | 135 ValidateClientHelloResultCallback::Result* result, |
| 140 ValidateClientHelloResultCallback* done_cb) | 136 ValidateClientHelloResultCallback* done_cb) |
| 141 : result_(result), done_cb_(done_cb) { | 137 : result_(result), done_cb_(done_cb) {} |
| 142 } | |
| 143 | 138 |
| 144 protected: | 139 protected: |
| 145 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { | 140 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { |
| 146 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; | 141 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; |
| 147 result_->info.unique = nonce_is_valid_and_unique; | 142 result_->info.unique = nonce_is_valid_and_unique; |
| 148 done_cb_->Run(result_); | 143 done_cb_->Run(result_); |
| 149 } | 144 } |
| 150 | 145 |
| 151 private: | 146 private: |
| 152 ValidateClientHelloResultCallback::Result* result_; | 147 ValidateClientHelloResultCallback::Result* result_; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 172 | 167 |
| 173 void ValidateClientHelloResultCallback::Run(const Result* result) { | 168 void ValidateClientHelloResultCallback::Run(const Result* result) { |
| 174 RunImpl(result->client_hello, *result); | 169 RunImpl(result->client_hello, *result); |
| 175 delete result; | 170 delete result; |
| 176 delete this; | 171 delete this; |
| 177 } | 172 } |
| 178 | 173 |
| 179 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() | 174 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() |
| 180 : expiry_time(QuicWallTime::Zero()), | 175 : expiry_time(QuicWallTime::Zero()), |
| 181 channel_id_enabled(false), | 176 channel_id_enabled(false), |
| 182 p256(false) {} | 177 p256(false) { |
| 178 } |
| 183 | 179 |
| 184 QuicCryptoServerConfig::QuicCryptoServerConfig( | 180 QuicCryptoServerConfig::QuicCryptoServerConfig( |
| 185 StringPiece source_address_token_secret, | 181 StringPiece source_address_token_secret, |
| 186 QuicRandom* rand) | 182 QuicRandom* rand) |
| 187 : replay_protection_(true), | 183 : replay_protection_(true), |
| 188 configs_lock_(), | 184 configs_lock_(), |
| 189 primary_config_(NULL), | 185 primary_config_(NULL), |
| 190 next_config_promotion_time_(QuicWallTime::Zero()), | 186 next_config_promotion_time_(QuicWallTime::Zero()), |
| 191 server_nonce_strike_register_lock_(), | 187 server_nonce_strike_register_lock_(), |
| 192 strike_register_no_startup_period_(false), | 188 strike_register_no_startup_period_(false), |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 return AddConfig(config.get(), clock->WallNow()); | 358 return AddConfig(config.get(), clock->WallNow()); |
| 363 } | 359 } |
| 364 | 360 |
| 365 bool QuicCryptoServerConfig::SetConfigs( | 361 bool QuicCryptoServerConfig::SetConfigs( |
| 366 const vector<QuicServerConfigProtobuf*>& protobufs, | 362 const vector<QuicServerConfigProtobuf*>& protobufs, |
| 367 const QuicWallTime now) { | 363 const QuicWallTime now) { |
| 368 vector<scoped_refptr<Config> > parsed_configs; | 364 vector<scoped_refptr<Config> > parsed_configs; |
| 369 bool ok = true; | 365 bool ok = true; |
| 370 | 366 |
| 371 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); | 367 for (vector<QuicServerConfigProtobuf*>::const_iterator i = protobufs.begin(); |
| 372 i != protobufs.end(); ++i) { | 368 i != protobufs.end(); |
| 369 ++i) { |
| 373 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); | 370 scoped_refptr<Config> config(ParseConfigProtobuf(*i)); |
| 374 if (!config.get()) { | 371 if (!config.get()) { |
| 375 ok = false; | 372 ok = false; |
| 376 break; | 373 break; |
| 377 } | 374 } |
| 378 | 375 |
| 379 parsed_configs.push_back(config); | 376 parsed_configs.push_back(config); |
| 380 } | 377 } |
| 381 | 378 |
| 382 if (parsed_configs.empty()) { | 379 if (parsed_configs.empty()) { |
| 383 LOG(WARNING) << "New config list is empty."; | 380 LOG(WARNING) << "New config list is empty."; |
| 384 ok = false; | 381 ok = false; |
| 385 } | 382 } |
| 386 | 383 |
| 387 if (!ok) { | 384 if (!ok) { |
| 388 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; | 385 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; |
| 389 } else { | 386 } else { |
| 390 VLOG(1) << "Updating configs:"; | 387 VLOG(1) << "Updating configs:"; |
| 391 | 388 |
| 392 base::AutoLock locked(configs_lock_); | 389 base::AutoLock locked(configs_lock_); |
| 393 ConfigMap new_configs; | 390 ConfigMap new_configs; |
| 394 | 391 |
| 395 for (vector<scoped_refptr<Config> >::const_iterator i = | 392 for (vector<scoped_refptr<Config> >::const_iterator i = |
| 396 parsed_configs.begin(); | 393 parsed_configs.begin(); |
| 397 i != parsed_configs.end(); ++i) { | 394 i != parsed_configs.end(); |
| 395 ++i) { |
| 398 scoped_refptr<Config> config = *i; | 396 scoped_refptr<Config> config = *i; |
| 399 | 397 |
| 400 ConfigMap::iterator it = configs_.find(config->id); | 398 ConfigMap::iterator it = configs_.find(config->id); |
| 401 if (it != configs_.end()) { | 399 if (it != configs_.end()) { |
| 402 VLOG(1) | 400 VLOG(1) << "Keeping scid: " |
| 403 << "Keeping scid: " << base::HexEncode( | 401 << base::HexEncode(config->id.data(), config->id.size()) |
| 404 config->id.data(), config->id.size()) | 402 << " orbit: " |
| 405 << " orbit: " << base::HexEncode( | 403 << base::HexEncode(reinterpret_cast<const char*>(config->orbit), |
| 406 reinterpret_cast<const char *>(config->orbit), kOrbitSize) | 404 kOrbitSize) << " new primary_time " |
| 407 << " new primary_time " << config->primary_time.ToUNIXSeconds() | 405 << config->primary_time.ToUNIXSeconds() << " old primary_time " |
| 408 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() | 406 << it->second->primary_time.ToUNIXSeconds() << " new priority " |
| 409 << " new priority " << config->priority | 407 << config->priority << " old priority " << it->second->priority; |
| 410 << " old priority " << it->second->priority; | |
| 411 // Update primary_time and priority. | 408 // Update primary_time and priority. |
| 412 it->second->primary_time = config->primary_time; | 409 it->second->primary_time = config->primary_time; |
| 413 it->second->priority = config->priority; | 410 it->second->priority = config->priority; |
| 414 new_configs.insert(*it); | 411 new_configs.insert(*it); |
| 415 } else { | 412 } else { |
| 416 VLOG(1) << "Adding scid: " << base::HexEncode( | 413 VLOG(1) << "Adding scid: " |
| 417 config->id.data(), config->id.size()) | 414 << base::HexEncode(config->id.data(), config->id.size()) |
| 418 << " orbit: " << base::HexEncode( | 415 << " orbit: " |
| 419 reinterpret_cast<const char *>(config->orbit), kOrbitSize) | 416 << base::HexEncode(reinterpret_cast<const char*>(config->orbit), |
| 420 << " primary_time " << config->primary_time.ToUNIXSeconds() | 417 kOrbitSize) << " primary_time " |
| 421 << " priority " << config->priority; | 418 << config->primary_time.ToUNIXSeconds() << " priority " |
| 419 << config->priority; |
| 422 new_configs.insert(make_pair(config->id, config)); | 420 new_configs.insert(make_pair(config->id, config)); |
| 423 } | 421 } |
| 424 } | 422 } |
| 425 | 423 |
| 426 configs_.swap(new_configs); | 424 configs_.swap(new_configs); |
| 427 SelectNewPrimaryConfig(now); | 425 SelectNewPrimaryConfig(now); |
| 428 DCHECK(primary_config_); | 426 DCHECK(primary_config_); |
| 429 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 427 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 430 } | 428 } |
| 431 | 429 |
| 432 return ok; | 430 return ok; |
| 433 } | 431 } |
| 434 | 432 |
| 435 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const { | 433 void QuicCryptoServerConfig::GetConfigIds(vector<string>* scids) const { |
| 436 base::AutoLock locked(configs_lock_); | 434 base::AutoLock locked(configs_lock_); |
| 437 for (ConfigMap::const_iterator it = configs_.begin(); | 435 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
| 438 it != configs_.end(); ++it) { | 436 ++it) { |
| 439 scids->push_back(it->first); | 437 scids->push_back(it->first); |
| 440 } | 438 } |
| 441 } | 439 } |
| 442 | 440 |
| 443 void QuicCryptoServerConfig::ValidateClientHello( | 441 void QuicCryptoServerConfig::ValidateClientHello( |
| 444 const CryptoHandshakeMessage& client_hello, | 442 const CryptoHandshakeMessage& client_hello, |
| 445 IPEndPoint client_ip, | 443 IPEndPoint client_ip, |
| 446 const QuicClock* clock, | 444 const QuicClock* clock, |
| 447 ValidateClientHelloResultCallback* done_cb) const { | 445 ValidateClientHelloResultCallback* done_cb) const { |
| 448 const QuicWallTime now(clock->WallNow()); | 446 const QuicWallTime now(clock->WallNow()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 483 |
| 486 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( | 484 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( |
| 487 const ValidateClientHelloResultCallback::Result& validate_chlo_result, | 485 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
| 488 QuicConnectionId connection_id, | 486 QuicConnectionId connection_id, |
| 489 IPEndPoint client_address, | 487 IPEndPoint client_address, |
| 490 QuicVersion version, | 488 QuicVersion version, |
| 491 const QuicVersionVector& supported_versions, | 489 const QuicVersionVector& supported_versions, |
| 492 uint32 initial_flow_control_window_bytes, | 490 uint32 initial_flow_control_window_bytes, |
| 493 const QuicClock* clock, | 491 const QuicClock* clock, |
| 494 QuicRandom* rand, | 492 QuicRandom* rand, |
| 495 QuicCryptoNegotiatedParameters *params, | 493 QuicCryptoNegotiatedParameters* params, |
| 496 CryptoHandshakeMessage* out, | 494 CryptoHandshakeMessage* out, |
| 497 string* error_details) const { | 495 string* error_details) const { |
| 498 DCHECK(error_details); | 496 DCHECK(error_details); |
| 499 | 497 |
| 500 const CryptoHandshakeMessage& client_hello = | 498 const CryptoHandshakeMessage& client_hello = |
| 501 validate_chlo_result.client_hello; | 499 validate_chlo_result.client_hello; |
| 502 const ClientHelloInfo& info = validate_chlo_result.info; | 500 const ClientHelloInfo& info = validate_chlo_result.info; |
| 503 | 501 |
| 504 // If the client's preferred version is not the version we are currently | 502 // If the client's preferred version is not the version we are currently |
| 505 // speaking, then the client went through a version negotiation. In this | 503 // speaking, then the client went through a version negotiation. In this |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 requested_config = GetConfigWithScid(requested_scid); | 550 requested_config = GetConfigWithScid(requested_scid); |
| 553 } | 551 } |
| 554 | 552 |
| 555 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { | 553 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { |
| 556 *error_details = validate_chlo_result.error_details; | 554 *error_details = validate_chlo_result.error_details; |
| 557 return validate_chlo_result.error_code; | 555 return validate_chlo_result.error_code; |
| 558 } | 556 } |
| 559 | 557 |
| 560 out->Clear(); | 558 out->Clear(); |
| 561 | 559 |
| 562 if (!info.valid_source_address_token || | 560 if (!info.valid_source_address_token || !info.client_nonce_well_formed || |
| 563 !info.client_nonce_well_formed || | 561 !info.unique || !requested_config.get()) { |
| 564 !info.unique || | |
| 565 !requested_config.get()) { | |
| 566 BuildRejection(*primary_config, client_hello, info, rand, out); | 562 BuildRejection(*primary_config, client_hello, info, rand, out); |
| 567 return QUIC_NO_ERROR; | 563 return QUIC_NO_ERROR; |
| 568 } | 564 } |
| 569 | 565 |
| 570 const QuicTag* their_aeads; | 566 const QuicTag* their_aeads; |
| 571 const QuicTag* their_key_exchanges; | 567 const QuicTag* their_key_exchanges; |
| 572 size_t num_their_aeads, num_their_key_exchanges; | 568 size_t num_their_aeads, num_their_key_exchanges; |
| 573 if (client_hello.GetTaglist(kAEAD, &their_aeads, | 569 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != |
| 574 &num_their_aeads) != QUIC_NO_ERROR || | 570 QUIC_NO_ERROR || |
| 575 client_hello.GetTaglist(kKEXS, &their_key_exchanges, | 571 client_hello.GetTaglist(kKEXS, |
| 572 &their_key_exchanges, |
| 576 &num_their_key_exchanges) != QUIC_NO_ERROR || | 573 &num_their_key_exchanges) != QUIC_NO_ERROR || |
| 577 num_their_aeads != 1 || | 574 num_their_aeads != 1 || num_their_key_exchanges != 1) { |
| 578 num_their_key_exchanges != 1) { | |
| 579 *error_details = "Missing or invalid AEAD or KEXS"; | 575 *error_details = "Missing or invalid AEAD or KEXS"; |
| 580 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 576 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 581 } | 577 } |
| 582 | 578 |
| 583 size_t key_exchange_index; | 579 size_t key_exchange_index; |
| 584 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, | 580 if (!QuicUtils::FindMutualTag(requested_config->aead, |
| 585 num_their_aeads, QuicUtils::LOCAL_PRIORITY, | 581 their_aeads, |
| 586 ¶ms->aead, NULL) || | 582 num_their_aeads, |
| 587 !QuicUtils::FindMutualTag( | 583 QuicUtils::LOCAL_PRIORITY, |
| 588 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, | 584 ¶ms->aead, |
| 589 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, | 585 NULL) || |
| 590 &key_exchange_index)) { | 586 !QuicUtils::FindMutualTag(requested_config->kexs, |
| 587 their_key_exchanges, |
| 588 num_their_key_exchanges, |
| 589 QuicUtils::LOCAL_PRIORITY, |
| 590 ¶ms->key_exchange, |
| 591 &key_exchange_index)) { |
| 591 *error_details = "Unsupported AEAD or KEXS"; | 592 *error_details = "Unsupported AEAD or KEXS"; |
| 592 return QUIC_CRYPTO_NO_SUPPORT; | 593 return QUIC_CRYPTO_NO_SUPPORT; |
| 593 } | 594 } |
| 594 | 595 |
| 595 StringPiece public_value; | 596 StringPiece public_value; |
| 596 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 597 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
| 597 *error_details = "Missing public value"; | 598 *error_details = "Missing public value"; |
| 598 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 599 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 599 } | 600 } |
| 600 | 601 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 string hkdf_input; | 635 string hkdf_input; |
| 635 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 636 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
| 636 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 637 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
| 637 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 638 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
| 638 sizeof(connection_id)); | 639 sizeof(connection_id)); |
| 639 hkdf_input.append(client_hello_serialized.data(), | 640 hkdf_input.append(client_hello_serialized.data(), |
| 640 client_hello_serialized.length()); | 641 client_hello_serialized.length()); |
| 641 hkdf_input.append(requested_config->serialized); | 642 hkdf_input.append(requested_config->serialized); |
| 642 | 643 |
| 643 CrypterPair crypters; | 644 CrypterPair crypters; |
| 644 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 645 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, |
| 645 info.client_nonce, info.server_nonce, | 646 params->aead, |
| 646 hkdf_input, CryptoUtils::SERVER, &crypters)) { | 647 info.client_nonce, |
| 648 info.server_nonce, |
| 649 hkdf_input, |
| 650 CryptoUtils::SERVER, |
| 651 &crypters)) { |
| 647 *error_details = "Symmetric key setup failed"; | 652 *error_details = "Symmetric key setup failed"; |
| 648 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 653 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
| 649 } | 654 } |
| 650 | 655 |
| 651 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( | 656 scoped_ptr<QuicData> cetv_plaintext( |
| 652 0 /* sequence number */, StringPiece() /* associated data */, | 657 crypters.decrypter->DecryptPacket(0 /* sequence number */, |
| 653 cetv_ciphertext)); | 658 StringPiece() /* associated data */, |
| 659 cetv_ciphertext)); |
| 654 if (!cetv_plaintext.get()) { | 660 if (!cetv_plaintext.get()) { |
| 655 *error_details = "CETV decryption failure"; | 661 *error_details = "CETV decryption failure"; |
| 656 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 662 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 657 } | 663 } |
| 658 | 664 |
| 659 scoped_ptr<CryptoHandshakeMessage> cetv(CryptoFramer::ParseMessage( | 665 scoped_ptr<CryptoHandshakeMessage> cetv( |
| 660 cetv_plaintext->AsStringPiece())); | 666 CryptoFramer::ParseMessage(cetv_plaintext->AsStringPiece())); |
| 661 if (!cetv.get()) { | 667 if (!cetv.get()) { |
| 662 *error_details = "CETV parse error"; | 668 *error_details = "CETV parse error"; |
| 663 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 669 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 664 } | 670 } |
| 665 | 671 |
| 666 StringPiece key, signature; | 672 StringPiece key, signature; |
| 667 if (cetv->GetStringPiece(kCIDK, &key) && | 673 if (cetv->GetStringPiece(kCIDK, &key) && |
| 668 cetv->GetStringPiece(kCIDS, &signature)) { | 674 cetv->GetStringPiece(kCIDS, &signature)) { |
| 669 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { | 675 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { |
| 670 *error_details = "ChannelID signature failure"; | 676 *error_details = "ChannelID signature failure"; |
| 671 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 677 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 672 } | 678 } |
| 673 | 679 |
| 674 params->channel_id = key.as_string(); | 680 params->channel_id = key.as_string(); |
| 675 } | 681 } |
| 676 } | 682 } |
| 677 | 683 |
| 678 string hkdf_input; | 684 string hkdf_input; |
| 679 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 685 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
| 680 hkdf_input.reserve(label_len + hkdf_suffix.size()); | 686 hkdf_input.reserve(label_len + hkdf_suffix.size()); |
| 681 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); | 687 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
| 682 hkdf_input.append(hkdf_suffix); | 688 hkdf_input.append(hkdf_suffix); |
| 683 | 689 |
| 684 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 690 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, |
| 685 info.client_nonce, info.server_nonce, hkdf_input, | 691 params->aead, |
| 692 info.client_nonce, |
| 693 info.server_nonce, |
| 694 hkdf_input, |
| 686 CryptoUtils::SERVER, | 695 CryptoUtils::SERVER, |
| 687 ¶ms->initial_crypters)) { | 696 ¶ms->initial_crypters)) { |
| 688 *error_details = "Symmetric key setup failed"; | 697 *error_details = "Symmetric key setup failed"; |
| 689 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 698 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
| 690 } | 699 } |
| 691 | 700 |
| 692 string forward_secure_public_value; | 701 string forward_secure_public_value; |
| 693 if (ephemeral_key_source_.get()) { | 702 if (ephemeral_key_source_.get()) { |
| 694 params->forward_secure_premaster_secret = | 703 params->forward_secure_premaster_secret = |
| 695 ephemeral_key_source_->CalculateForwardSecureKey( | 704 ephemeral_key_source_->CalculateForwardSecureKey( |
| 696 key_exchange, rand, clock->ApproximateNow(), public_value, | 705 key_exchange, |
| 706 rand, |
| 707 clock->ApproximateNow(), |
| 708 public_value, |
| 697 &forward_secure_public_value); | 709 &forward_secure_public_value); |
| 698 } else { | 710 } else { |
| 699 scoped_ptr<KeyExchange> forward_secure_key_exchange( | 711 scoped_ptr<KeyExchange> forward_secure_key_exchange( |
| 700 key_exchange->NewKeyPair(rand)); | 712 key_exchange->NewKeyPair(rand)); |
| 701 forward_secure_public_value = | 713 forward_secure_public_value = |
| 702 forward_secure_key_exchange->public_value().as_string(); | 714 forward_secure_key_exchange->public_value().as_string(); |
| 703 if (!forward_secure_key_exchange->CalculateSharedKey( | 715 if (!forward_secure_key_exchange->CalculateSharedKey( |
| 704 public_value, ¶ms->forward_secure_premaster_secret)) { | 716 public_value, ¶ms->forward_secure_premaster_secret)) { |
| 705 *error_details = "Invalid public value"; | 717 *error_details = "Invalid public value"; |
| 706 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 718 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 707 } | 719 } |
| 708 } | 720 } |
| 709 | 721 |
| 710 string forward_secure_hkdf_input; | 722 string forward_secure_hkdf_input; |
| 711 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; | 723 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; |
| 712 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); | 724 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); |
| 713 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, | 725 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, |
| 714 label_len); | 726 label_len); |
| 715 forward_secure_hkdf_input.append(hkdf_suffix); | 727 forward_secure_hkdf_input.append(hkdf_suffix); |
| 716 | 728 |
| 717 if (!CryptoUtils::DeriveKeys( | 729 if (!CryptoUtils::DeriveKeys(params->forward_secure_premaster_secret, |
| 718 params->forward_secure_premaster_secret, params->aead, | 730 params->aead, |
| 719 info.client_nonce, info.server_nonce, forward_secure_hkdf_input, | 731 info.client_nonce, |
| 720 CryptoUtils::SERVER, ¶ms->forward_secure_crypters)) { | 732 info.server_nonce, |
| 733 forward_secure_hkdf_input, |
| 734 CryptoUtils::SERVER, |
| 735 ¶ms->forward_secure_crypters)) { |
| 721 *error_details = "Symmetric key setup failed"; | 736 *error_details = "Symmetric key setup failed"; |
| 722 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 737 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
| 723 } | 738 } |
| 724 | 739 |
| 725 out->set_tag(kSHLO); | 740 out->set_tag(kSHLO); |
| 726 QuicTagVector supported_version_tags; | 741 QuicTagVector supported_version_tags; |
| 727 for (size_t i = 0; i < supported_versions.size(); ++i) { | 742 for (size_t i = 0; i < supported_versions.size(); ++i) { |
| 728 supported_version_tags.push_back | 743 supported_version_tags.push_back( |
| 729 (QuicVersionToQuicTag(supported_versions[i])); | 744 QuicVersionToQuicTag(supported_versions[i])); |
| 730 } | 745 } |
| 731 out->SetVector(kVER, supported_version_tags); | 746 out->SetVector(kVER, supported_version_tags); |
| 732 out->SetStringPiece(kSourceAddressTokenTag, | 747 out->SetStringPiece( |
| 733 NewSourceAddressToken( | 748 kSourceAddressTokenTag, |
| 734 *requested_config, | 749 NewSourceAddressToken(*requested_config, client_address, rand, info.now)); |
| 735 client_address, rand, | |
| 736 info.now)); | |
| 737 QuicSocketAddressCoder address_coder(client_address); | 750 QuicSocketAddressCoder address_coder(client_address); |
| 738 out->SetStringPiece(kCADR, address_coder.Encode()); | 751 out->SetStringPiece(kCADR, address_coder.Encode()); |
| 739 out->SetStringPiece(kPUBS, forward_secure_public_value); | 752 out->SetStringPiece(kPUBS, forward_secure_public_value); |
| 740 | 753 |
| 741 // Set initial receive window for flow control. | 754 // Set initial receive window for flow control. |
| 742 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 755 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
| 743 | 756 |
| 744 return QUIC_NO_ERROR; | 757 return QUIC_NO_ERROR; |
| 745 } | 758 } |
| 746 | 759 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 // Primary times and priorities are equal, sort by config id. | 792 // Primary times and priorities are equal, sort by config id. |
| 780 return a->id < b->id; | 793 return a->id < b->id; |
| 781 } | 794 } |
| 782 } | 795 } |
| 783 | 796 |
| 784 void QuicCryptoServerConfig::SelectNewPrimaryConfig( | 797 void QuicCryptoServerConfig::SelectNewPrimaryConfig( |
| 785 const QuicWallTime now) const { | 798 const QuicWallTime now) const { |
| 786 vector<scoped_refptr<Config> > configs; | 799 vector<scoped_refptr<Config> > configs; |
| 787 configs.reserve(configs_.size()); | 800 configs.reserve(configs_.size()); |
| 788 | 801 |
| 789 for (ConfigMap::const_iterator it = configs_.begin(); | 802 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
| 790 it != configs_.end(); ++it) { | 803 ++it) { |
| 791 // TODO(avd) Exclude expired configs? | 804 // TODO(avd) Exclude expired configs? |
| 792 configs.push_back(it->second); | 805 configs.push_back(it->second); |
| 793 } | 806 } |
| 794 | 807 |
| 795 if (configs.empty()) { | 808 if (configs.empty()) { |
| 796 if (primary_config_.get()) { | 809 if (primary_config_.get()) { |
| 797 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; | 810 LOG(DFATAL) << "No valid QUIC server config. Keeping the current config."; |
| 798 } else { | 811 } else { |
| 799 LOG(DFATAL) << "No valid QUIC server config."; | 812 LOG(DFATAL) << "No valid QUIC server config."; |
| 800 } | 813 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 829 next_config_promotion_time_ = config->primary_time; | 842 next_config_promotion_time_ = config->primary_time; |
| 830 } | 843 } |
| 831 | 844 |
| 832 if (primary_config_.get()) { | 845 if (primary_config_.get()) { |
| 833 primary_config_->is_primary = false; | 846 primary_config_->is_primary = false; |
| 834 } | 847 } |
| 835 primary_config_ = new_primary; | 848 primary_config_ = new_primary; |
| 836 new_primary->is_primary = true; | 849 new_primary->is_primary = true; |
| 837 DVLOG(1) << "New primary config. orbit: " | 850 DVLOG(1) << "New primary config. orbit: " |
| 838 << base::HexEncode( | 851 << base::HexEncode( |
| 839 reinterpret_cast<const char*>(primary_config_->orbit), | 852 reinterpret_cast<const char*>(primary_config_->orbit), |
| 840 kOrbitSize); | 853 kOrbitSize); |
| 841 if (primary_config_changed_cb_.get() != NULL) { | 854 if (primary_config_changed_cb_.get() != NULL) { |
| 842 primary_config_changed_cb_->Run(primary_config_->id); | 855 primary_config_changed_cb_->Run(primary_config_->id); |
| 843 } | 856 } |
| 844 | 857 |
| 845 return; | 858 return; |
| 846 } | 859 } |
| 847 | 860 |
| 848 // All config's primary times are in the past. We should make the most recent | 861 // All config's primary times are in the past. We should make the most recent |
| 849 // and highest priority candidate primary. | 862 // and highest priority candidate primary. |
| 850 scoped_refptr<Config> new_primary(best_candidate); | 863 scoped_refptr<Config> new_primary(best_candidate); |
| 851 if (primary_config_.get()) { | 864 if (primary_config_.get()) { |
| 852 primary_config_->is_primary = false; | 865 primary_config_->is_primary = false; |
| 853 } | 866 } |
| 854 primary_config_ = new_primary; | 867 primary_config_ = new_primary; |
| 855 new_primary->is_primary = true; | 868 new_primary->is_primary = true; |
| 856 DVLOG(1) << "New primary config. orbit: " | 869 DVLOG(1) << "New primary config. orbit: " |
| 857 << base::HexEncode( | 870 << base::HexEncode( |
| 858 reinterpret_cast<const char*>(primary_config_->orbit), | 871 reinterpret_cast<const char*>(primary_config_->orbit), |
| 859 kOrbitSize) | 872 kOrbitSize) |
| 860 << " scid: " << base::HexEncode(primary_config_->id.data(), | 873 << " scid: " << base::HexEncode(primary_config_->id.data(), |
| 861 primary_config_->id.size()); | 874 primary_config_->id.size()); |
| 862 next_config_promotion_time_ = QuicWallTime::Zero(); | 875 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 863 if (primary_config_changed_cb_.get() != NULL) { | 876 if (primary_config_changed_cb_.get() != NULL) { |
| 864 primary_config_changed_cb_->Run(primary_config_->id); | 877 primary_config_changed_cb_->Run(primary_config_->id); |
| 865 } | 878 } |
| 866 } | 879 } |
| 867 | 880 |
| 868 void QuicCryptoServerConfig::EvaluateClientHello( | 881 void QuicCryptoServerConfig::EvaluateClientHello( |
| 869 const uint8* primary_orbit, | 882 const uint8* primary_orbit, |
| 870 scoped_refptr<Config> requested_config, | 883 scoped_refptr<Config> requested_config, |
| 871 ValidateClientHelloResultCallback::Result* client_hello_state, | 884 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 872 ValidateClientHelloResultCallback* done_cb) const { | 885 ValidateClientHelloResultCallback* done_cb) const { |
| 873 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 886 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
| 874 | 887 |
| 875 const CryptoHandshakeMessage& client_hello = | 888 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; |
| 876 client_hello_state->client_hello; | |
| 877 ClientHelloInfo* info = &(client_hello_state->info); | 889 ClientHelloInfo* info = &(client_hello_state->info); |
| 878 | 890 |
| 879 if (client_hello.size() < kClientHelloMinimumSize) { | 891 if (client_hello.size() < kClientHelloMinimumSize) { |
| 880 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, | 892 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, |
| 881 "Client hello too small"); | 893 "Client hello too small"); |
| 882 return; | 894 return; |
| 883 } | 895 } |
| 884 | 896 |
| 885 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 897 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
| 886 !CryptoUtils::IsValidSNI(info->sni)) { | 898 !CryptoUtils::IsValidSNI(info->sni)) { |
| 887 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 899 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
| 888 "Invalid SNI name"); | 900 "Invalid SNI name"); |
| 889 return; | 901 return; |
| 890 } | 902 } |
| 891 | 903 |
| 892 StringPiece srct; | 904 StringPiece srct; |
| 893 if (requested_config.get() != NULL && | 905 if (requested_config.get() != NULL && |
| 894 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && | 906 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && |
| 895 ValidateSourceAddressToken(*requested_config, | 907 ValidateSourceAddressToken( |
| 896 srct, | 908 *requested_config, srct, info->client_ip, info->now)) { |
| 897 info->client_ip, | |
| 898 info->now)) { | |
| 899 info->valid_source_address_token = true; | 909 info->valid_source_address_token = true; |
| 900 } else { | 910 } else { |
| 901 // No server config with the requested ID, or no valid source address token. | 911 // No server config with the requested ID, or no valid source address token. |
| 902 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 912 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 903 return; | 913 return; |
| 904 } | 914 } |
| 905 | 915 |
| 906 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 916 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
| 907 info->client_nonce.size() == kNonceSize) { | 917 info->client_nonce.size() == kNonceSize) { |
| 908 info->client_nonce_well_formed = true; | 918 info->client_nonce_well_formed = true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 933 StrikeRegisterClient* strike_register_client; | 943 StrikeRegisterClient* strike_register_client; |
| 934 { | 944 { |
| 935 base::AutoLock locked(strike_register_client_lock_); | 945 base::AutoLock locked(strike_register_client_lock_); |
| 936 | 946 |
| 937 if (strike_register_client_.get() == NULL) { | 947 if (strike_register_client_.get() == NULL) { |
| 938 strike_register_client_.reset(new LocalStrikeRegisterClient( | 948 strike_register_client_.reset(new LocalStrikeRegisterClient( |
| 939 strike_register_max_entries_, | 949 strike_register_max_entries_, |
| 940 static_cast<uint32>(info->now.ToUNIXSeconds()), | 950 static_cast<uint32>(info->now.ToUNIXSeconds()), |
| 941 strike_register_window_secs_, | 951 strike_register_window_secs_, |
| 942 primary_orbit, | 952 primary_orbit, |
| 943 strike_register_no_startup_period_ ? | 953 strike_register_no_startup_period_ |
| 944 StrikeRegister::NO_STARTUP_PERIOD_NEEDED : | 954 ? StrikeRegister::NO_STARTUP_PERIOD_NEEDED |
| 945 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); | 955 : StrikeRegister::DENY_REQUESTS_AT_STARTUP)); |
| 946 } | 956 } |
| 947 strike_register_client = strike_register_client_.get(); | 957 strike_register_client = strike_register_client_.get(); |
| 948 } | 958 } |
| 949 | 959 |
| 950 strike_register_client->VerifyNonceIsValidAndUnique( | 960 strike_register_client->VerifyNonceIsValidAndUnique( |
| 951 info->client_nonce, | 961 info->client_nonce, |
| 952 info->now, | 962 info->now, |
| 953 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); | 963 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); |
| 954 helper.StartedAsyncCallback(); | 964 helper.StartedAsyncCallback(); |
| 955 } | 965 } |
| 956 | 966 |
| 957 void QuicCryptoServerConfig::BuildRejection( | 967 void QuicCryptoServerConfig::BuildRejection( |
| 958 const Config& config, | 968 const Config& config, |
| 959 const CryptoHandshakeMessage& client_hello, | 969 const CryptoHandshakeMessage& client_hello, |
| 960 const ClientHelloInfo& info, | 970 const ClientHelloInfo& info, |
| 961 QuicRandom* rand, | 971 QuicRandom* rand, |
| 962 CryptoHandshakeMessage* out) const { | 972 CryptoHandshakeMessage* out) const { |
| 963 out->set_tag(kREJ); | 973 out->set_tag(kREJ); |
| 964 out->SetStringPiece(kSCFG, config.serialized); | 974 out->SetStringPiece(kSCFG, config.serialized); |
| 965 out->SetStringPiece(kSourceAddressTokenTag, | 975 out->SetStringPiece( |
| 966 NewSourceAddressToken( | 976 kSourceAddressTokenTag, |
| 967 config, | 977 NewSourceAddressToken(config, info.client_ip, rand, info.now)); |
| 968 info.client_ip, | |
| 969 rand, | |
| 970 info.now)); | |
| 971 if (replay_protection_) { | 978 if (replay_protection_) { |
| 972 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 979 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
| 973 } | 980 } |
| 974 | 981 |
| 975 // The client may have requested a certificate chain. | 982 // The client may have requested a certificate chain. |
| 976 const QuicTag* their_proof_demands; | 983 const QuicTag* their_proof_demands; |
| 977 size_t num_their_proof_demands; | 984 size_t num_their_proof_demands; |
| 978 | 985 |
| 979 if (proof_source_.get() == NULL || | 986 if (proof_source_.get() == NULL || |
| 980 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 987 client_hello.GetTaglist(kPDMD, |
| 981 &num_their_proof_demands) != | 988 &their_proof_demands, |
| 982 QUIC_NO_ERROR) { | 989 &num_their_proof_demands) != QUIC_NO_ERROR) { |
| 983 return; | 990 return; |
| 984 } | 991 } |
| 985 | 992 |
| 986 bool x509_supported = false, x509_ecdsa_supported = false; | 993 bool x509_supported = false, x509_ecdsa_supported = false; |
| 987 for (size_t i = 0; i < num_their_proof_demands; i++) { | 994 for (size_t i = 0; i < num_their_proof_demands; i++) { |
| 988 switch (their_proof_demands[i]) { | 995 switch (their_proof_demands[i]) { |
| 989 case kX509: | 996 case kX509: |
| 990 x509_supported = true; | 997 x509_supported = true; |
| 991 x509_ecdsa_supported = true; | 998 x509_ecdsa_supported = true; |
| 992 break; | 999 break; |
| 993 case kX59R: | 1000 case kX59R: |
| 994 x509_supported = true; | 1001 x509_supported = true; |
| 995 break; | 1002 break; |
| 996 } | 1003 } |
| 997 } | 1004 } |
| 998 | 1005 |
| 999 if (!x509_supported) { | 1006 if (!x509_supported) { |
| 1000 return; | 1007 return; |
| 1001 } | 1008 } |
| 1002 | 1009 |
| 1003 const vector<string>* certs; | 1010 const vector<string>* certs; |
| 1004 string signature; | 1011 string signature; |
| 1005 if (!proof_source_->GetProof(info.sni.as_string(), config.serialized, | 1012 if (!proof_source_->GetProof(info.sni.as_string(), |
| 1006 x509_ecdsa_supported, &certs, &signature)) { | 1013 config.serialized, |
| 1014 x509_ecdsa_supported, |
| 1015 &certs, |
| 1016 &signature)) { |
| 1007 return; | 1017 return; |
| 1008 } | 1018 } |
| 1009 | 1019 |
| 1010 StringPiece their_common_set_hashes; | 1020 StringPiece their_common_set_hashes; |
| 1011 StringPiece their_cached_cert_hashes; | 1021 StringPiece their_cached_cert_hashes; |
| 1012 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); | 1022 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); |
| 1013 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); | 1023 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); |
| 1014 | 1024 |
| 1015 const string compressed = CertCompressor::CompressChain( | 1025 const string compressed = |
| 1016 *certs, their_common_set_hashes, their_cached_cert_hashes, | 1026 CertCompressor::CompressChain(*certs, |
| 1017 config.common_cert_sets); | 1027 their_common_set_hashes, |
| 1028 their_cached_cert_hashes, |
| 1029 config.common_cert_sets); |
| 1018 | 1030 |
| 1019 // kREJOverheadBytes is a very rough estimate of how much of a REJ | 1031 // kREJOverheadBytes is a very rough estimate of how much of a REJ |
| 1020 // message is taken up by things other than the certificates. | 1032 // message is taken up by things other than the certificates. |
| 1021 // STK: 56 bytes | 1033 // STK: 56 bytes |
| 1022 // SNO: 56 bytes | 1034 // SNO: 56 bytes |
| 1023 // SCFG | 1035 // SCFG |
| 1024 // SCID: 16 bytes | 1036 // SCID: 16 bytes |
| 1025 // PUBS: 38 bytes | 1037 // PUBS: 38 bytes |
| 1026 const size_t kREJOverheadBytes = 166; | 1038 const size_t kREJOverheadBytes = 166; |
| 1027 // kMultiplier is the multiple of the CHLO message size that a REJ message | 1039 // kMultiplier is the multiple of the CHLO message size that a REJ message |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 StrikeRegisterClient* strike_register_client; | 1128 StrikeRegisterClient* strike_register_client; |
| 1117 { | 1129 { |
| 1118 base::AutoLock locked(strike_register_client_lock_); | 1130 base::AutoLock locked(strike_register_client_lock_); |
| 1119 strike_register_client = strike_register_client_.get(); | 1131 strike_register_client = strike_register_client_.get(); |
| 1120 } | 1132 } |
| 1121 | 1133 |
| 1122 if (strike_register_client != NULL && | 1134 if (strike_register_client != NULL && |
| 1123 !strike_register_client->IsKnownOrbit(orbit)) { | 1135 !strike_register_client->IsKnownOrbit(orbit)) { |
| 1124 LOG(WARNING) | 1136 LOG(WARNING) |
| 1125 << "Rejecting server config with orbit that the strike register " | 1137 << "Rejecting server config with orbit that the strike register " |
| 1126 "client doesn't know about."; | 1138 "client doesn't know about."; |
| 1127 return NULL; | 1139 return NULL; |
| 1128 } | 1140 } |
| 1129 } | 1141 } |
| 1130 | 1142 |
| 1131 if (kexs_len != protobuf->key_size()) { | 1143 if (kexs_len != protobuf->key_size()) { |
| 1132 LOG(WARNING) << "Server config has " << kexs_len | 1144 LOG(WARNING) << "Server config has " << kexs_len |
| 1133 << " key exchange methods configured, but " | 1145 << " key exchange methods configured, but " |
| 1134 << protobuf->key_size() << " private keys"; | 1146 << protobuf->key_size() << " private keys"; |
| 1135 return NULL; | 1147 return NULL; |
| 1136 } | 1148 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 return NULL; | 1197 return NULL; |
| 1186 } | 1198 } |
| 1187 break; | 1199 break; |
| 1188 default: | 1200 default: |
| 1189 LOG(WARNING) << "Server config message contains unknown key exchange " | 1201 LOG(WARNING) << "Server config message contains unknown key exchange " |
| 1190 "method: " << tag; | 1202 "method: " << tag; |
| 1191 return NULL; | 1203 return NULL; |
| 1192 } | 1204 } |
| 1193 | 1205 |
| 1194 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); | 1206 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); |
| 1195 i != config->key_exchanges.end(); ++i) { | 1207 i != config->key_exchanges.end(); |
| 1208 ++i) { |
| 1196 if ((*i)->tag() == tag) { | 1209 if ((*i)->tag() == tag) { |
| 1197 LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1210 LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
| 1198 return NULL; | 1211 return NULL; |
| 1199 } | 1212 } |
| 1200 } | 1213 } |
| 1201 | 1214 |
| 1202 config->key_exchanges.push_back(ka.release()); | 1215 config->key_exchanges.push_back(ka.release()); |
| 1203 } | 1216 } |
| 1204 | 1217 |
| 1205 return config; | 1218 return config; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 DCHECK(!server_nonce_strike_register_.get()); | 1279 DCHECK(!server_nonce_strike_register_.get()); |
| 1267 server_nonce_strike_register_window_secs_ = window_secs; | 1280 server_nonce_strike_register_window_secs_ = window_secs; |
| 1268 } | 1281 } |
| 1269 | 1282 |
| 1270 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1283 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
| 1271 PrimaryConfigChangedCallback* cb) { | 1284 PrimaryConfigChangedCallback* cb) { |
| 1272 base::AutoLock locked(configs_lock_); | 1285 base::AutoLock locked(configs_lock_); |
| 1273 primary_config_changed_cb_.reset(cb); | 1286 primary_config_changed_cb_.reset(cb); |
| 1274 } | 1287 } |
| 1275 | 1288 |
| 1276 string QuicCryptoServerConfig::NewSourceAddressToken( | 1289 string QuicCryptoServerConfig::NewSourceAddressToken(const Config& config, |
| 1277 const Config& config, | 1290 const IPEndPoint& ip, |
| 1278 const IPEndPoint& ip, | 1291 QuicRandom* rand, |
| 1279 QuicRandom* rand, | 1292 QuicWallTime now) const { |
| 1280 QuicWallTime now) const { | |
| 1281 SourceAddressToken source_address_token; | 1293 SourceAddressToken source_address_token; |
| 1282 source_address_token.set_ip(IPAddressToPackedString(ip.address())); | 1294 source_address_token.set_ip(IPAddressToPackedString(ip.address())); |
| 1283 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1295 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
| 1284 | 1296 |
| 1285 return config.source_address_token_boxer->Box( | 1297 return config.source_address_token_boxer->Box( |
| 1286 rand, source_address_token.SerializeAsString()); | 1298 rand, source_address_token.SerializeAsString()); |
| 1287 } | 1299 } |
| 1288 | 1300 |
| 1289 bool QuicCryptoServerConfig::ValidateSourceAddressToken( | 1301 bool QuicCryptoServerConfig::ValidateSourceAddressToken( |
| 1290 const Config& config, | 1302 const Config& config, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 | 1374 |
| 1363 if (plaintext.size() != kServerNoncePlaintextSize) { | 1375 if (plaintext.size() != kServerNoncePlaintextSize) { |
| 1364 // This should never happen because the value decrypted correctly. | 1376 // This should never happen because the value decrypted correctly. |
| 1365 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; | 1377 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; |
| 1366 return false; | 1378 return false; |
| 1367 } | 1379 } |
| 1368 | 1380 |
| 1369 uint8 server_nonce[32]; | 1381 uint8 server_nonce[32]; |
| 1370 memcpy(server_nonce, plaintext.data(), 4); | 1382 memcpy(server_nonce, plaintext.data(), 4); |
| 1371 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 1383 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
| 1372 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, | 1384 memcpy( |
| 1373 20); | 1385 server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, 20); |
| 1374 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), | 1386 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), |
| 1375 bad_nonce_buffer_length); | 1387 bad_nonce_buffer_length); |
| 1376 | 1388 |
| 1377 bool is_unique; | 1389 bool is_unique; |
| 1378 { | 1390 { |
| 1379 base::AutoLock auto_lock(server_nonce_strike_register_lock_); | 1391 base::AutoLock auto_lock(server_nonce_strike_register_lock_); |
| 1380 if (server_nonce_strike_register_.get() == NULL) { | 1392 if (server_nonce_strike_register_.get() == NULL) { |
| 1381 server_nonce_strike_register_.reset(new StrikeRegister( | 1393 server_nonce_strike_register_.reset( |
| 1382 server_nonce_strike_register_max_entries_, | 1394 new StrikeRegister(server_nonce_strike_register_max_entries_, |
| 1383 static_cast<uint32>(now.ToUNIXSeconds()), | 1395 static_cast<uint32>(now.ToUNIXSeconds()), |
| 1384 server_nonce_strike_register_window_secs_, server_nonce_orbit_, | 1396 server_nonce_strike_register_window_secs_, |
| 1385 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); | 1397 server_nonce_orbit_, |
| 1398 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); |
| 1386 } | 1399 } |
| 1387 is_unique = server_nonce_strike_register_->Insert( | 1400 is_unique = server_nonce_strike_register_->Insert( |
| 1388 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1401 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
| 1389 } | 1402 } |
| 1390 | 1403 |
| 1391 return is_unique; | 1404 return is_unique; |
| 1392 } | 1405 } |
| 1393 | 1406 |
| 1394 QuicCryptoServerConfig::Config::Config() | 1407 QuicCryptoServerConfig::Config::Config() |
| 1395 : channel_id_enabled(false), | 1408 : channel_id_enabled(false), |
| 1396 is_primary(false), | 1409 is_primary(false), |
| 1397 primary_time(QuicWallTime::Zero()), | 1410 primary_time(QuicWallTime::Zero()), |
| 1398 priority(0), | 1411 priority(0), |
| 1399 source_address_token_boxer(NULL) {} | 1412 source_address_token_boxer(NULL) { |
| 1413 } |
| 1400 | 1414 |
| 1401 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1415 QuicCryptoServerConfig::Config::~Config() { |
| 1416 STLDeleteElements(&key_exchanges); |
| 1417 } |
| 1402 | 1418 |
| 1403 } // namespace net | 1419 } // namespace net |
| OLD | NEW |