Chromium Code Reviews| 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 28 matching lines...) Expand all Loading... | |
| 39 | 39 |
| 40 using base::StringPiece; | 40 using base::StringPiece; |
| 41 using crypto::SecureHash; | 41 using crypto::SecureHash; |
| 42 using std::map; | 42 using std::map; |
| 43 using std::sort; | 43 using std::sort; |
| 44 using std::string; | 44 using std::string; |
| 45 using std::vector; | 45 using std::vector; |
| 46 | 46 |
| 47 namespace net { | 47 namespace net { |
| 48 | 48 |
| 49 namespace { | |
| 50 | |
| 51 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { | |
| 52 crypto::HKDF hkdf(source_address_token_secret, | |
| 53 StringPiece() /* no salt */, | |
| 54 "QUIC source address token key", | |
| 55 CryptoSecretBoxer::GetKeySize(), | |
| 56 0 /* no fixed IV needed */); | |
| 57 return hkdf.server_write_key().as_string(); | |
| 58 } | |
| 59 | |
| 60 } // namespace | |
| 61 | |
| 49 // ClientHelloInfo contains information about a client hello message that is | 62 // ClientHelloInfo contains information about a client hello message that is |
| 50 // only kept for as long as it's being processed. | 63 // only kept for as long as it's being processed. |
| 51 struct ClientHelloInfo { | 64 struct ClientHelloInfo { |
| 52 ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now) | 65 ClientHelloInfo(const IPEndPoint& in_client_ip, QuicWallTime in_now) |
| 53 : client_ip(in_client_ip), | 66 : client_ip(in_client_ip), |
| 54 now(in_now), | 67 now(in_now), |
| 55 valid_source_address_token(false), | 68 valid_source_address_token(false), |
| 56 client_nonce_well_formed(false), | 69 client_nonce_well_formed(false), |
| 57 unique(false) {} | 70 unique(false) {} |
| 58 | 71 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 primary_config_(NULL), | 189 primary_config_(NULL), |
| 177 next_config_promotion_time_(QuicWallTime::Zero()), | 190 next_config_promotion_time_(QuicWallTime::Zero()), |
| 178 server_nonce_strike_register_lock_(), | 191 server_nonce_strike_register_lock_(), |
| 179 strike_register_no_startup_period_(false), | 192 strike_register_no_startup_period_(false), |
| 180 strike_register_max_entries_(1 << 10), | 193 strike_register_max_entries_(1 << 10), |
| 181 strike_register_window_secs_(600), | 194 strike_register_window_secs_(600), |
| 182 source_address_token_future_secs_(3600), | 195 source_address_token_future_secs_(3600), |
| 183 source_address_token_lifetime_secs_(86400), | 196 source_address_token_lifetime_secs_(86400), |
| 184 server_nonce_strike_register_max_entries_(1 << 10), | 197 server_nonce_strike_register_max_entries_(1 << 10), |
| 185 server_nonce_strike_register_window_secs_(120) { | 198 server_nonce_strike_register_window_secs_(120) { |
| 186 crypto::HKDF hkdf(source_address_token_secret, StringPiece() /* no salt */, | 199 default_source_address_token_boxer_.SetKey( |
| 187 "QUIC source address token key", | 200 DeriveSourceAddressTokenKey(source_address_token_secret)); |
| 188 CryptoSecretBoxer::GetKeySize(), | |
| 189 0 /* no fixed IV needed */); | |
| 190 source_address_token_boxer_.SetKey(hkdf.server_write_key()); | |
| 191 | 201 |
| 192 // Generate a random key and orbit for server nonces. | 202 // Generate a random key and orbit for server nonces. |
| 193 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 203 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
| 194 const size_t key_size = server_nonce_boxer_.GetKeySize(); | 204 const size_t key_size = server_nonce_boxer_.GetKeySize(); |
| 195 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); | 205 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); |
| 196 rand->RandBytes(key_bytes.get(), key_size); | 206 rand->RandBytes(key_bytes.get(), key_size); |
| 197 | 207 |
| 198 server_nonce_boxer_.SetKey( | 208 server_nonce_boxer_.SetKey( |
| 199 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); | 209 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); |
| 200 } | 210 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 } else { | 389 } else { |
| 380 VLOG(1) << "Updating configs:"; | 390 VLOG(1) << "Updating configs:"; |
| 381 | 391 |
| 382 base::AutoLock locked(configs_lock_); | 392 base::AutoLock locked(configs_lock_); |
| 383 ConfigMap new_configs; | 393 ConfigMap new_configs; |
| 384 | 394 |
| 385 for (vector<scoped_refptr<Config> >::const_iterator i = | 395 for (vector<scoped_refptr<Config> >::const_iterator i = |
| 386 parsed_configs.begin(); | 396 parsed_configs.begin(); |
| 387 i != parsed_configs.end(); ++i) { | 397 i != parsed_configs.end(); ++i) { |
| 388 scoped_refptr<Config> config = *i; | 398 scoped_refptr<Config> config = *i; |
| 399 | |
| 389 ConfigMap::iterator it = configs_.find(config->id); | 400 ConfigMap::iterator it = configs_.find(config->id); |
| 390 if (it != configs_.end()) { | 401 if (it != configs_.end()) { |
| 391 VLOG(1) | 402 VLOG(1) |
| 392 << "Keeping scid: " << base::HexEncode( | 403 << "Keeping scid: " << base::HexEncode( |
| 393 config->id.data(), config->id.size()) | 404 config->id.data(), config->id.size()) |
| 394 << " orbit: " << base::HexEncode( | 405 << " orbit: " << base::HexEncode( |
| 395 reinterpret_cast<const char *>(config->orbit), kOrbitSize) | 406 reinterpret_cast<const char *>(config->orbit), kOrbitSize) |
| 396 << " new primary_time " << config->primary_time.ToUNIXSeconds() | 407 << " new primary_time " << config->primary_time.ToUNIXSeconds() |
| 397 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() | 408 << " old primary_time " << it->second->primary_time.ToUNIXSeconds() |
| 398 << " new priority " << config->priority | 409 << " new priority " << config->priority |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 const CryptoHandshakeMessage& client_hello, | 444 const CryptoHandshakeMessage& client_hello, |
| 434 IPEndPoint client_ip, | 445 IPEndPoint client_ip, |
| 435 const QuicClock* clock, | 446 const QuicClock* clock, |
| 436 ValidateClientHelloResultCallback* done_cb) const { | 447 ValidateClientHelloResultCallback* done_cb) const { |
| 437 const QuicWallTime now(clock->WallNow()); | 448 const QuicWallTime now(clock->WallNow()); |
| 438 | 449 |
| 439 ValidateClientHelloResultCallback::Result* result = | 450 ValidateClientHelloResultCallback::Result* result = |
| 440 new ValidateClientHelloResultCallback::Result( | 451 new ValidateClientHelloResultCallback::Result( |
| 441 client_hello, client_ip, now); | 452 client_hello, client_ip, now); |
| 442 | 453 |
| 454 StringPiece requested_scid; | |
| 455 client_hello.GetStringPiece(kSCID, &requested_scid); | |
| 456 | |
| 443 uint8 primary_orbit[kOrbitSize]; | 457 uint8 primary_orbit[kOrbitSize]; |
| 458 scoped_refptr<Config> requested_config; | |
| 444 { | 459 { |
| 445 base::AutoLock locked(configs_lock_); | 460 base::AutoLock locked(configs_lock_); |
| 446 | 461 |
| 447 if (!primary_config_.get()) { | 462 if (!primary_config_.get()) { |
| 448 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; | 463 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; |
| 449 result->error_details = "No configurations loaded"; | 464 result->error_details = "No configurations loaded"; |
| 450 } else { | 465 } else { |
| 451 if (!next_config_promotion_time_.IsZero() && | 466 if (!next_config_promotion_time_.IsZero() && |
| 452 next_config_promotion_time_.IsAfter(now)) { | 467 next_config_promotion_time_.IsAfter(now)) { |
| 453 SelectNewPrimaryConfig(now); | 468 SelectNewPrimaryConfig(now); |
| 454 DCHECK(primary_config_); | 469 DCHECK(primary_config_); |
| 455 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); | 470 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); |
| 456 } | 471 } |
| 457 | 472 |
| 458 memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit)); | 473 memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit)); |
| 459 } | 474 } |
| 475 | |
| 476 // We'll use the config that the client requested in order to do | |
| 477 // key-agreement. Otherwise we'll give it a copy of |primary_config_| | |
| 478 // to use. | |
|
wtc
2014/04/22 19:12:10
IMPORTANT: The original code doesn't have this com
ramant (doing other things)
2014/04/25 23:40:58
Done.
| |
| 479 requested_config = GetConfigWithScid(requested_scid); | |
| 460 } | 480 } |
| 461 | 481 |
| 462 if (result->error_code == QUIC_NO_ERROR) { | 482 if (result->error_code == QUIC_NO_ERROR) { |
| 463 EvaluateClientHello(primary_orbit, result, done_cb); | 483 EvaluateClientHello(primary_orbit, requested_config, result, done_cb); |
| 464 } else { | 484 } else { |
| 465 done_cb->Run(result); | 485 done_cb->Run(result); |
| 466 } | 486 } |
| 467 } | 487 } |
| 468 | 488 |
| 469 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( | 489 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( |
| 470 const ValidateClientHelloResultCallback::Result& validate_chlo_result, | 490 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
| 471 QuicConnectionId connection_id, | 491 QuicConnectionId connection_id, |
| 472 IPEndPoint client_address, | 492 IPEndPoint client_address, |
| 473 QuicVersion version, | 493 QuicVersion version, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 return QUIC_CRYPTO_INTERNAL_ERROR; | 540 return QUIC_CRYPTO_INTERNAL_ERROR; |
| 521 } | 541 } |
| 522 | 542 |
| 523 if (!next_config_promotion_time_.IsZero() && | 543 if (!next_config_promotion_time_.IsZero() && |
| 524 next_config_promotion_time_.IsAfter(now)) { | 544 next_config_promotion_time_.IsAfter(now)) { |
| 525 SelectNewPrimaryConfig(now); | 545 SelectNewPrimaryConfig(now); |
| 526 DCHECK(primary_config_); | 546 DCHECK(primary_config_); |
| 527 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); | 547 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); |
| 528 } | 548 } |
| 529 | 549 |
| 550 // We'll use the config that the client requested in order to do | |
| 551 // key-agreement. Otherwise we'll give it a copy of |primary_config_| | |
| 552 // to use. | |
| 530 primary_config = primary_config_; | 553 primary_config = primary_config_; |
| 531 | 554 |
| 532 if (!requested_scid.empty()) { | 555 requested_config = GetConfigWithScid(requested_scid); |
| 533 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | |
| 534 if (it != configs_.end()) { | |
| 535 // We'll use the config that the client requested in order to do | |
| 536 // key-agreement. Otherwise we'll give it a copy of |primary_config_| | |
| 537 // to use. | |
| 538 requested_config = it->second; | |
| 539 } | |
| 540 } | |
| 541 } | 556 } |
| 542 | 557 |
| 543 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { | 558 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { |
| 544 *error_details = validate_chlo_result.error_details; | 559 *error_details = validate_chlo_result.error_details; |
| 545 return validate_chlo_result.error_code; | 560 return validate_chlo_result.error_code; |
| 546 } | 561 } |
| 547 | 562 |
| 548 out->Clear(); | 563 out->Clear(); |
| 549 | 564 |
| 550 if (!info.valid_source_address_token || | 565 if (!info.valid_source_address_token || |
| 551 !info.client_nonce_well_formed || | 566 !info.client_nonce_well_formed || |
| 552 !info.unique || | 567 !info.unique || |
| 553 !requested_config.get()) { | 568 !requested_config.get()) { |
| 554 BuildRejection(primary_config.get(), client_hello, info, rand, out); | 569 BuildRejection(*primary_config, client_hello, info, rand, out); |
| 555 return QUIC_NO_ERROR; | 570 return QUIC_NO_ERROR; |
| 556 } | 571 } |
| 557 | 572 |
| 558 const QuicTag* their_aeads; | 573 const QuicTag* their_aeads; |
| 559 const QuicTag* their_key_exchanges; | 574 const QuicTag* their_key_exchanges; |
| 560 size_t num_their_aeads, num_their_key_exchanges; | 575 size_t num_their_aeads, num_their_key_exchanges; |
| 561 if (client_hello.GetTaglist(kAEAD, &their_aeads, | 576 if (client_hello.GetTaglist(kAEAD, &their_aeads, |
| 562 &num_their_aeads) != QUIC_NO_ERROR || | 577 &num_their_aeads) != QUIC_NO_ERROR || |
| 563 client_hello.GetTaglist(kKEXS, &their_key_exchanges, | 578 client_hello.GetTaglist(kKEXS, &their_key_exchanges, |
| 564 &num_their_key_exchanges) != QUIC_NO_ERROR || | 579 &num_their_key_exchanges) != QUIC_NO_ERROR || |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 } | 726 } |
| 712 | 727 |
| 713 out->set_tag(kSHLO); | 728 out->set_tag(kSHLO); |
| 714 QuicTagVector supported_version_tags; | 729 QuicTagVector supported_version_tags; |
| 715 for (size_t i = 0; i < supported_versions.size(); ++i) { | 730 for (size_t i = 0; i < supported_versions.size(); ++i) { |
| 716 supported_version_tags.push_back | 731 supported_version_tags.push_back |
| 717 (QuicVersionToQuicTag(supported_versions[i])); | 732 (QuicVersionToQuicTag(supported_versions[i])); |
| 718 } | 733 } |
| 719 out->SetVector(kVER, supported_version_tags); | 734 out->SetVector(kVER, supported_version_tags); |
| 720 out->SetStringPiece(kSourceAddressTokenTag, | 735 out->SetStringPiece(kSourceAddressTokenTag, |
| 721 NewSourceAddressToken(client_address, rand, info.now)); | 736 NewSourceAddressToken( |
| 737 *requested_config, | |
| 738 client_address, rand, | |
| 739 info.now)); | |
| 722 QuicSocketAddressCoder address_coder(client_address); | 740 QuicSocketAddressCoder address_coder(client_address); |
| 723 out->SetStringPiece(kCADR, address_coder.Encode()); | 741 out->SetStringPiece(kCADR, address_coder.Encode()); |
| 724 out->SetStringPiece(kPUBS, forward_secure_public_value); | 742 out->SetStringPiece(kPUBS, forward_secure_public_value); |
| 725 | 743 |
| 726 // Set initial receive window for flow control. | 744 // Set initial receive window for flow control. |
| 727 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 745 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
| 728 | 746 |
| 729 return QUIC_NO_ERROR; | 747 return QUIC_NO_ERROR; |
| 730 } | 748 } |
| 731 | 749 |
| 750 scoped_refptr<QuicCryptoServerConfig::Config> | |
|
wtc
2014/04/22 19:12:10
Please see if we can change QuicCryptoServerConfig
ramant (doing other things)
2014/04/25 23:40:58
Wasn't able to. Compile errors on linux.
../../ne
| |
| 751 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | |
| 752 // In Chromium, we will dead lock if the lock is held by the current thread. | |
| 753 // Chromium doesn't have AssertReaderHeld API call. | |
| 754 // configs_lock_.AssertReaderHeld(); | |
| 755 | |
| 756 if (!requested_scid.empty()) { | |
| 757 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | |
| 758 if (it != configs_.end()) { | |
| 759 // We'll use the config that the client requested in order to do | |
| 760 // key-agreement. | |
| 761 return scoped_refptr<Config>(it->second); | |
| 762 } | |
| 763 } | |
| 764 | |
| 765 return scoped_refptr<Config>(); | |
| 766 } | |
| 767 | |
| 732 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for | 768 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for |
| 733 // Config's based on their primary_time. | 769 // Config's based on their primary_time. |
| 734 // static | 770 // static |
| 735 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( | 771 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( |
| 736 const scoped_refptr<Config>& a, | 772 const scoped_refptr<Config>& a, |
| 737 const scoped_refptr<Config>& b) { | 773 const scoped_refptr<Config>& b) { |
| 738 if (a->primary_time.IsBefore(b->primary_time) || | 774 if (a->primary_time.IsBefore(b->primary_time) || |
| 739 b->primary_time.IsBefore(a->primary_time)) { | 775 b->primary_time.IsBefore(a->primary_time)) { |
| 740 // Primary times differ. | 776 // Primary times differ. |
| 741 return a->primary_time.IsBefore(b->primary_time); | 777 return a->primary_time.IsBefore(b->primary_time); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 // and highest priority candidate primary. | 852 // and highest priority candidate primary. |
| 817 scoped_refptr<Config> new_primary(best_candidate); | 853 scoped_refptr<Config> new_primary(best_candidate); |
| 818 if (primary_config_.get()) { | 854 if (primary_config_.get()) { |
| 819 primary_config_->is_primary = false; | 855 primary_config_->is_primary = false; |
| 820 } | 856 } |
| 821 primary_config_ = new_primary; | 857 primary_config_ = new_primary; |
| 822 new_primary->is_primary = true; | 858 new_primary->is_primary = true; |
| 823 DVLOG(1) << "New primary config. orbit: " | 859 DVLOG(1) << "New primary config. orbit: " |
| 824 << base::HexEncode( | 860 << base::HexEncode( |
| 825 reinterpret_cast<const char*>(primary_config_->orbit), | 861 reinterpret_cast<const char*>(primary_config_->orbit), |
| 826 kOrbitSize); | 862 kOrbitSize) |
| 863 << " scid: " << base::HexEncode(primary_config_->id.data(), | |
| 864 primary_config_->id.size()); | |
| 827 next_config_promotion_time_ = QuicWallTime::Zero(); | 865 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 828 if (primary_config_changed_cb_.get() != NULL) { | 866 if (primary_config_changed_cb_.get() != NULL) { |
| 829 primary_config_changed_cb_->Run(primary_config_->id); | 867 primary_config_changed_cb_->Run(primary_config_->id); |
| 830 } | 868 } |
| 831 } | 869 } |
| 832 | 870 |
| 833 void QuicCryptoServerConfig::EvaluateClientHello( | 871 void QuicCryptoServerConfig::EvaluateClientHello( |
| 834 const uint8* primary_orbit, | 872 const uint8* primary_orbit, |
| 873 scoped_refptr<Config> requested_config, | |
| 835 ValidateClientHelloResultCallback::Result* client_hello_state, | 874 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 836 ValidateClientHelloResultCallback* done_cb) const { | 875 ValidateClientHelloResultCallback* done_cb) const { |
| 837 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 876 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
| 838 | 877 |
| 839 const CryptoHandshakeMessage& client_hello = | 878 const CryptoHandshakeMessage& client_hello = |
| 840 client_hello_state->client_hello; | 879 client_hello_state->client_hello; |
| 841 ClientHelloInfo* info = &(client_hello_state->info); | 880 ClientHelloInfo* info = &(client_hello_state->info); |
| 842 | 881 |
| 843 if (client_hello.size() < kClientHelloMinimumSize) { | 882 if (client_hello.size() < kClientHelloMinimumSize) { |
| 844 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, | 883 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, |
| 845 "Client hello too small"); | 884 "Client hello too small"); |
| 846 return; | 885 return; |
| 847 } | 886 } |
| 848 | 887 |
| 849 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 888 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
| 850 !CryptoUtils::IsValidSNI(info->sni)) { | 889 !CryptoUtils::IsValidSNI(info->sni)) { |
| 851 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 890 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
| 852 "Invalid SNI name"); | 891 "Invalid SNI name"); |
| 853 return; | 892 return; |
| 854 } | 893 } |
| 855 | 894 |
| 856 StringPiece srct; | 895 StringPiece srct; |
| 857 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && | 896 if (requested_config.get() != NULL && |
| 858 ValidateSourceAddressToken(srct, info->client_ip, info->now)) { | 897 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && |
| 898 ValidateSourceAddressToken(*requested_config, | |
| 899 srct, | |
| 900 info->client_ip, | |
| 901 info->now)) { | |
| 859 info->valid_source_address_token = true; | 902 info->valid_source_address_token = true; |
| 860 } else { | 903 } else { |
| 861 // No valid source address token. | 904 // No server config with the requested ID, or no valid source address token. |
| 862 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 905 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 863 return; | 906 return; |
| 864 } | 907 } |
| 865 | 908 |
| 866 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 909 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
| 867 info->client_nonce.size() == kNonceSize) { | 910 info->client_nonce.size() == kNonceSize) { |
| 868 info->client_nonce_well_formed = true; | 911 info->client_nonce_well_formed = true; |
| 869 } else { | 912 } else { |
| 870 // Invalid client nonce. | 913 // Invalid client nonce. |
| 871 DVLOG(1) << "Invalid client nonce."; | 914 DVLOG(1) << "Invalid client nonce."; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 } | 951 } |
| 909 | 952 |
| 910 strike_register_client->VerifyNonceIsValidAndUnique( | 953 strike_register_client->VerifyNonceIsValidAndUnique( |
| 911 info->client_nonce, | 954 info->client_nonce, |
| 912 info->now, | 955 info->now, |
| 913 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); | 956 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); |
| 914 helper.StartedAsyncCallback(); | 957 helper.StartedAsyncCallback(); |
| 915 } | 958 } |
| 916 | 959 |
| 917 void QuicCryptoServerConfig::BuildRejection( | 960 void QuicCryptoServerConfig::BuildRejection( |
| 918 const scoped_refptr<Config>& config, | 961 const Config& config, |
| 919 const CryptoHandshakeMessage& client_hello, | 962 const CryptoHandshakeMessage& client_hello, |
| 920 const ClientHelloInfo& info, | 963 const ClientHelloInfo& info, |
| 921 QuicRandom* rand, | 964 QuicRandom* rand, |
| 922 CryptoHandshakeMessage* out) const { | 965 CryptoHandshakeMessage* out) const { |
| 923 out->set_tag(kREJ); | 966 out->set_tag(kREJ); |
| 924 out->SetStringPiece(kSCFG, config->serialized); | 967 out->SetStringPiece(kSCFG, config.serialized); |
| 925 out->SetStringPiece(kSourceAddressTokenTag, | 968 out->SetStringPiece(kSourceAddressTokenTag, |
| 926 NewSourceAddressToken(info.client_ip, rand, info.now)); | 969 NewSourceAddressToken( |
| 970 config, | |
| 971 info.client_ip, | |
| 972 rand, | |
| 973 info.now)); | |
| 927 if (replay_protection_) { | 974 if (replay_protection_) { |
| 928 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 975 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
| 929 } | 976 } |
| 930 | 977 |
| 931 // The client may have requested a certificate chain. | 978 // The client may have requested a certificate chain. |
| 932 const QuicTag* their_proof_demands; | 979 const QuicTag* their_proof_demands; |
| 933 size_t num_their_proof_demands; | 980 size_t num_their_proof_demands; |
| 934 | 981 |
| 935 if (proof_source_.get() == NULL || | 982 if (proof_source_.get() == NULL || |
| 936 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 983 client_hello.GetTaglist(kPDMD, &their_proof_demands, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 951 break; | 998 break; |
| 952 } | 999 } |
| 953 } | 1000 } |
| 954 | 1001 |
| 955 if (!x509_supported) { | 1002 if (!x509_supported) { |
| 956 return; | 1003 return; |
| 957 } | 1004 } |
| 958 | 1005 |
| 959 const vector<string>* certs; | 1006 const vector<string>* certs; |
| 960 string signature; | 1007 string signature; |
| 961 if (!proof_source_->GetProof(info.sni.as_string(), config->serialized, | 1008 if (!proof_source_->GetProof(info.sni.as_string(), config.serialized, |
| 962 x509_ecdsa_supported, &certs, &signature)) { | 1009 x509_ecdsa_supported, &certs, &signature)) { |
| 963 return; | 1010 return; |
| 964 } | 1011 } |
| 965 | 1012 |
| 966 StringPiece their_common_set_hashes; | 1013 StringPiece their_common_set_hashes; |
| 967 StringPiece their_cached_cert_hashes; | 1014 StringPiece their_cached_cert_hashes; |
| 968 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); | 1015 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); |
| 969 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); | 1016 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); |
| 970 | 1017 |
| 971 const string compressed = CertCompressor::CompressChain( | 1018 const string compressed = CertCompressor::CompressChain( |
| 972 *certs, their_common_set_hashes, their_cached_cert_hashes, | 1019 *certs, their_common_set_hashes, their_cached_cert_hashes, |
| 973 config->common_cert_sets); | 1020 config.common_cert_sets); |
| 974 | 1021 |
| 975 // kREJOverheadBytes is a very rough estimate of how much of a REJ | 1022 // kREJOverheadBytes is a very rough estimate of how much of a REJ |
| 976 // message is taken up by things other than the certificates. | 1023 // message is taken up by things other than the certificates. |
| 977 // STK: 56 bytes | 1024 // STK: 56 bytes |
| 978 // SNO: 56 bytes | 1025 // SNO: 56 bytes |
| 979 // SCFG | 1026 // SCFG |
| 980 // SCID: 16 bytes | 1027 // SCID: 16 bytes |
| 981 // PUBS: 38 bytes | 1028 // PUBS: 38 bytes |
| 982 const size_t kREJOverheadBytes = 166; | 1029 const size_t kREJOverheadBytes = 166; |
| 983 // kMultiplier is the multiple of the CHLO message size that a REJ message | 1030 // kMultiplier is the multiple of the CHLO message size that a REJ message |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1006 | 1053 |
| 1007 if (msg->tag() != kSCFG) { | 1054 if (msg->tag() != kSCFG) { |
| 1008 LOG(WARNING) << "Server config message has tag " << msg->tag() | 1055 LOG(WARNING) << "Server config message has tag " << msg->tag() |
| 1009 << " expected " << kSCFG; | 1056 << " expected " << kSCFG; |
| 1010 return NULL; | 1057 return NULL; |
| 1011 } | 1058 } |
| 1012 | 1059 |
| 1013 scoped_refptr<Config> config(new Config); | 1060 scoped_refptr<Config> config(new Config); |
| 1014 config->serialized = protobuf->config(); | 1061 config->serialized = protobuf->config(); |
| 1015 | 1062 |
| 1063 if (!protobuf->has_source_address_token_secret_override()) { | |
| 1064 // Use the default boxer. | |
| 1065 config->source_address_token_boxer = &default_source_address_token_boxer_; | |
| 1066 } else { | |
| 1067 // Create override boxer instance. | |
| 1068 CryptoSecretBoxer* boxer = new CryptoSecretBoxer; | |
| 1069 boxer->SetKey(DeriveSourceAddressTokenKey( | |
| 1070 protobuf->source_address_token_secret_override())); | |
| 1071 config->source_address_token_boxer_storage.reset(boxer); | |
| 1072 config->source_address_token_boxer = boxer; | |
| 1073 } | |
| 1074 | |
| 1016 if (protobuf->has_primary_time()) { | 1075 if (protobuf->has_primary_time()) { |
| 1017 config->primary_time = | 1076 config->primary_time = |
| 1018 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1077 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
| 1019 } | 1078 } |
| 1020 | 1079 |
| 1021 config->priority = protobuf->priority(); | 1080 config->priority = protobuf->priority(); |
| 1022 | 1081 |
| 1023 StringPiece scid; | 1082 StringPiece scid; |
| 1024 if (!msg->GetStringPiece(kSCID, &scid)) { | 1083 if (!msg->GetStringPiece(kSCID, &scid)) { |
| 1025 LOG(WARNING) << "Server config message is missing SCID"; | 1084 LOG(WARNING) << "Server config message is missing SCID"; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1037 | 1096 |
| 1038 const QuicTag* kexs_tags; | 1097 const QuicTag* kexs_tags; |
| 1039 size_t kexs_len; | 1098 size_t kexs_len; |
| 1040 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | 1099 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { |
| 1041 LOG(WARNING) << "Server config message is missing KEXS"; | 1100 LOG(WARNING) << "Server config message is missing KEXS"; |
| 1042 return NULL; | 1101 return NULL; |
| 1043 } | 1102 } |
| 1044 | 1103 |
| 1045 StringPiece orbit; | 1104 StringPiece orbit; |
| 1046 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1105 if (!msg->GetStringPiece(kORBT, &orbit)) { |
| 1047 LOG(WARNING) << "Server config message is missing OBIT"; | 1106 LOG(WARNING) << "Server config message is missing ORBT"; |
| 1048 return NULL; | 1107 return NULL; |
| 1049 } | 1108 } |
| 1050 | 1109 |
| 1051 if (orbit.size() != kOrbitSize) { | 1110 if (orbit.size() != kOrbitSize) { |
| 1052 LOG(WARNING) << "Orbit value in server config is the wrong length." | 1111 LOG(WARNING) << "Orbit value in server config is the wrong length." |
| 1053 " Got " << orbit.size() << " want " << kOrbitSize; | 1112 " Got " << orbit.size() << " want " << kOrbitSize; |
| 1054 return NULL; | 1113 return NULL; |
| 1055 } | 1114 } |
| 1056 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); | 1115 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); |
| 1057 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1116 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 server_nonce_strike_register_window_secs_ = window_secs; | 1270 server_nonce_strike_register_window_secs_ = window_secs; |
| 1212 } | 1271 } |
| 1213 | 1272 |
| 1214 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1273 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
| 1215 PrimaryConfigChangedCallback* cb) { | 1274 PrimaryConfigChangedCallback* cb) { |
| 1216 base::AutoLock locked(configs_lock_); | 1275 base::AutoLock locked(configs_lock_); |
| 1217 primary_config_changed_cb_.reset(cb); | 1276 primary_config_changed_cb_.reset(cb); |
| 1218 } | 1277 } |
| 1219 | 1278 |
| 1220 string QuicCryptoServerConfig::NewSourceAddressToken( | 1279 string QuicCryptoServerConfig::NewSourceAddressToken( |
| 1280 const QuicCryptoServerConfig::Config& config, | |
| 1221 const IPEndPoint& ip, | 1281 const IPEndPoint& ip, |
| 1222 QuicRandom* rand, | 1282 QuicRandom* rand, |
| 1223 QuicWallTime now) const { | 1283 QuicWallTime now) const { |
| 1224 SourceAddressToken source_address_token; | 1284 SourceAddressToken source_address_token; |
| 1225 source_address_token.set_ip(IPAddressToPackedString(ip.address())); | 1285 source_address_token.set_ip(IPAddressToPackedString(ip.address())); |
| 1226 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1286 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
| 1227 | 1287 |
| 1228 return source_address_token_boxer_.Box( | 1288 return config.source_address_token_boxer->Box( |
| 1229 rand, source_address_token.SerializeAsString()); | 1289 rand, source_address_token.SerializeAsString()); |
| 1230 } | 1290 } |
| 1231 | 1291 |
| 1232 bool QuicCryptoServerConfig::ValidateSourceAddressToken( | 1292 bool QuicCryptoServerConfig::ValidateSourceAddressToken( |
| 1293 const QuicCryptoServerConfig::Config& config, | |
|
wtc
2014/04/22 19:12:10
Change QuicCryptoServerConfig::Config to Config on
ramant (doing other things)
2014/04/25 23:40:58
Done.
| |
| 1233 StringPiece token, | 1294 StringPiece token, |
| 1234 const IPEndPoint& ip, | 1295 const IPEndPoint& ip, |
| 1235 QuicWallTime now) const { | 1296 QuicWallTime now) const { |
| 1236 string storage; | 1297 string storage; |
| 1237 StringPiece plaintext; | 1298 StringPiece plaintext; |
| 1238 if (!source_address_token_boxer_.Unbox(token, &storage, &plaintext)) { | 1299 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
| 1239 return false; | 1300 return false; |
| 1240 } | 1301 } |
| 1241 | 1302 |
| 1242 SourceAddressToken source_address_token; | 1303 SourceAddressToken source_address_token; |
| 1243 if (!source_address_token.ParseFromArray(plaintext.data(), | 1304 if (!source_address_token.ParseFromArray(plaintext.data(), |
| 1244 plaintext.size())) { | 1305 plaintext.size())) { |
| 1245 return false; | 1306 return false; |
| 1246 } | 1307 } |
| 1247 | 1308 |
| 1248 if (source_address_token.ip() != IPAddressToPackedString(ip.address())) { | 1309 if (source_address_token.ip() != IPAddressToPackedString(ip.address())) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1330 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1391 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
| 1331 } | 1392 } |
| 1332 | 1393 |
| 1333 return is_unique; | 1394 return is_unique; |
| 1334 } | 1395 } |
| 1335 | 1396 |
| 1336 QuicCryptoServerConfig::Config::Config() | 1397 QuicCryptoServerConfig::Config::Config() |
| 1337 : channel_id_enabled(false), | 1398 : channel_id_enabled(false), |
| 1338 is_primary(false), | 1399 is_primary(false), |
| 1339 primary_time(QuicWallTime::Zero()), | 1400 primary_time(QuicWallTime::Zero()), |
| 1340 priority(0) {} | 1401 priority(0), |
| 1402 source_address_token_boxer(NULL) {} | |
| 1341 | 1403 |
| 1342 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1404 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
| 1343 | 1405 |
| 1344 } // namespace net | 1406 } // namespace net |
| OLD | NEW |