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 ComputeSourceAddressTokenKey(StringPiece source_address_token_secret) { | |
wtc
2014/04/07 18:38:24
Nit: "Derive" is the usual verb for this operation
ramant (doing other things)
2014/04/21 22:39:29
Done.
| |
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 ComputeSourceAddressTokenKey(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 requested_config = GetConfigWithScid(requested_scid); | |
460 } | 477 } |
461 | 478 |
462 if (result->error_code == QUIC_NO_ERROR) { | 479 if (result->error_code == QUIC_NO_ERROR) { |
463 EvaluateClientHello(primary_orbit, result, done_cb); | 480 EvaluateClientHello(primary_orbit, requested_config, result, done_cb); |
464 } else { | 481 } else { |
465 done_cb->Run(result); | 482 done_cb->Run(result); |
466 } | 483 } |
467 } | 484 } |
468 | 485 |
469 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( | 486 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( |
470 const ValidateClientHelloResultCallback::Result& validate_chlo_result, | 487 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
471 QuicConnectionId connection_id, | 488 QuicConnectionId connection_id, |
472 IPEndPoint client_address, | 489 IPEndPoint client_address, |
473 QuicVersion version, | 490 QuicVersion version, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
522 | 539 |
523 if (!next_config_promotion_time_.IsZero() && | 540 if (!next_config_promotion_time_.IsZero() && |
524 next_config_promotion_time_.IsAfter(now)) { | 541 next_config_promotion_time_.IsAfter(now)) { |
525 SelectNewPrimaryConfig(now); | 542 SelectNewPrimaryConfig(now); |
526 DCHECK(primary_config_); | 543 DCHECK(primary_config_); |
527 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); | 544 DCHECK(configs_.find(primary_config_->id)->second == primary_config_); |
528 } | 545 } |
529 | 546 |
530 primary_config = primary_config_; | 547 primary_config = primary_config_; |
531 | 548 |
532 if (!requested_scid.empty()) { | 549 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 } | 550 } |
542 | 551 |
543 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { | 552 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { |
544 *error_details = validate_chlo_result.error_details; | 553 *error_details = validate_chlo_result.error_details; |
545 return validate_chlo_result.error_code; | 554 return validate_chlo_result.error_code; |
546 } | 555 } |
547 | 556 |
548 out->Clear(); | 557 out->Clear(); |
549 | 558 |
550 if (!info.valid_source_address_token || | 559 if (!info.valid_source_address_token || |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
711 } | 720 } |
712 | 721 |
713 out->set_tag(kSHLO); | 722 out->set_tag(kSHLO); |
714 QuicTagVector supported_version_tags; | 723 QuicTagVector supported_version_tags; |
715 for (size_t i = 0; i < supported_versions.size(); ++i) { | 724 for (size_t i = 0; i < supported_versions.size(); ++i) { |
716 supported_version_tags.push_back | 725 supported_version_tags.push_back |
717 (QuicVersionToQuicTag(supported_versions[i])); | 726 (QuicVersionToQuicTag(supported_versions[i])); |
718 } | 727 } |
719 out->SetVector(kVER, supported_version_tags); | 728 out->SetVector(kVER, supported_version_tags); |
720 out->SetStringPiece(kSourceAddressTokenTag, | 729 out->SetStringPiece(kSourceAddressTokenTag, |
721 NewSourceAddressToken(client_address, rand, info.now)); | 730 NewSourceAddressToken( |
731 requested_config.get(), | |
732 client_address, rand, | |
733 info.now)); | |
722 QuicSocketAddressCoder address_coder(client_address); | 734 QuicSocketAddressCoder address_coder(client_address); |
723 out->SetStringPiece(kCADR, address_coder.Encode()); | 735 out->SetStringPiece(kCADR, address_coder.Encode()); |
724 out->SetStringPiece(kPUBS, forward_secure_public_value); | 736 out->SetStringPiece(kPUBS, forward_secure_public_value); |
725 | 737 |
726 // Set initial receive window for flow control. | 738 // Set initial receive window for flow control. |
727 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 739 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
728 | 740 |
729 return QUIC_NO_ERROR; | 741 return QUIC_NO_ERROR; |
730 } | 742 } |
731 | 743 |
744 scoped_refptr<QuicCryptoServerConfig::Config> | |
745 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | |
746 // In Chromium, we will dead lock if the lock is held by the current thread. | |
747 // Chromium doesn't have AssertReaderHeld API call. | |
748 // configs_lock_.AssertReaderHeld(); | |
749 | |
750 if (!requested_scid.empty()) { | |
751 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | |
752 if (it != configs_.end()) { | |
753 // We'll use the config that the client requested in order to do | |
754 // key-agreement. Otherwise we'll give it a copy of |primary_config_| | |
755 // to use. | |
wtc
2014/04/07 18:38:24
The comment "Otherwise we'll give it a copy of |pr
ramant (doing other things)
2014/04/21 22:39:29
Please take a look at the new comments.
Done.
| |
756 return scoped_refptr<Config>(it->second); | |
757 } | |
758 } | |
759 | |
760 return scoped_refptr<Config>(); | |
761 } | |
762 | |
732 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for | 763 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for |
733 // Config's based on their primary_time. | 764 // Config's based on their primary_time. |
734 // static | 765 // static |
735 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( | 766 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( |
736 const scoped_refptr<Config>& a, | 767 const scoped_refptr<Config>& a, |
737 const scoped_refptr<Config>& b) { | 768 const scoped_refptr<Config>& b) { |
738 if (a->primary_time.IsBefore(b->primary_time) || | 769 if (a->primary_time.IsBefore(b->primary_time) || |
739 b->primary_time.IsBefore(a->primary_time)) { | 770 b->primary_time.IsBefore(a->primary_time)) { |
740 // Primary times differ. | 771 // Primary times differ. |
741 return a->primary_time.IsBefore(b->primary_time); | 772 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. | 847 // and highest priority candidate primary. |
817 scoped_refptr<Config> new_primary(best_candidate); | 848 scoped_refptr<Config> new_primary(best_candidate); |
818 if (primary_config_.get()) { | 849 if (primary_config_.get()) { |
819 primary_config_->is_primary = false; | 850 primary_config_->is_primary = false; |
820 } | 851 } |
821 primary_config_ = new_primary; | 852 primary_config_ = new_primary; |
822 new_primary->is_primary = true; | 853 new_primary->is_primary = true; |
823 DVLOG(1) << "New primary config. orbit: " | 854 DVLOG(1) << "New primary config. orbit: " |
824 << base::HexEncode( | 855 << base::HexEncode( |
825 reinterpret_cast<const char*>(primary_config_->orbit), | 856 reinterpret_cast<const char*>(primary_config_->orbit), |
826 kOrbitSize); | 857 kOrbitSize) |
858 << " scid: " << base::HexEncode(primary_config_->id.data(), | |
859 primary_config_->id.size()); | |
827 next_config_promotion_time_ = QuicWallTime::Zero(); | 860 next_config_promotion_time_ = QuicWallTime::Zero(); |
828 if (primary_config_changed_cb_.get() != NULL) { | 861 if (primary_config_changed_cb_.get() != NULL) { |
829 primary_config_changed_cb_->Run(primary_config_->id); | 862 primary_config_changed_cb_->Run(primary_config_->id); |
830 } | 863 } |
831 } | 864 } |
832 | 865 |
833 void QuicCryptoServerConfig::EvaluateClientHello( | 866 void QuicCryptoServerConfig::EvaluateClientHello( |
834 const uint8* primary_orbit, | 867 const uint8* primary_orbit, |
868 scoped_refptr<Config> requested_config, | |
835 ValidateClientHelloResultCallback::Result* client_hello_state, | 869 ValidateClientHelloResultCallback::Result* client_hello_state, |
836 ValidateClientHelloResultCallback* done_cb) const { | 870 ValidateClientHelloResultCallback* done_cb) const { |
837 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 871 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
838 | 872 |
839 const CryptoHandshakeMessage& client_hello = | 873 const CryptoHandshakeMessage& client_hello = |
840 client_hello_state->client_hello; | 874 client_hello_state->client_hello; |
841 ClientHelloInfo* info = &(client_hello_state->info); | 875 ClientHelloInfo* info = &(client_hello_state->info); |
842 | 876 |
843 if (client_hello.size() < kClientHelloMinimumSize) { | 877 if (client_hello.size() < kClientHelloMinimumSize) { |
844 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, | 878 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, |
845 "Client hello too small"); | 879 "Client hello too small"); |
846 return; | 880 return; |
847 } | 881 } |
848 | 882 |
849 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 883 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
850 !CryptoUtils::IsValidSNI(info->sni)) { | 884 !CryptoUtils::IsValidSNI(info->sni)) { |
851 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 885 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
852 "Invalid SNI name"); | 886 "Invalid SNI name"); |
853 return; | 887 return; |
854 } | 888 } |
855 | 889 |
856 StringPiece srct; | 890 StringPiece srct; |
857 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && | 891 if (requested_config.get() != NULL && |
wtc
2014/04/07 18:38:24
Why do we want to allow requested_config to be NUL
ramant (doing other things)
2014/04/21 22:39:29
Will make this change in internal source code.
| |
858 ValidateSourceAddressToken(srct, info->client_ip, info->now)) { | 892 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && |
893 ValidateSourceAddressToken(requested_config.get(), | |
894 srct, | |
895 info->client_ip, | |
896 info->now)) { | |
859 info->valid_source_address_token = true; | 897 info->valid_source_address_token = true; |
860 } else { | 898 } else { |
861 // No valid source address token. | 899 // No valid source address token. |
wtc
2014/04/07 18:38:24
With the new code, this comment is no longer accur
ramant (doing other things)
2014/04/21 22:39:29
Done.
| |
862 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 900 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
863 return; | 901 return; |
864 } | 902 } |
865 | 903 |
866 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 904 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
867 info->client_nonce.size() == kNonceSize) { | 905 info->client_nonce.size() == kNonceSize) { |
868 info->client_nonce_well_formed = true; | 906 info->client_nonce_well_formed = true; |
869 } else { | 907 } else { |
870 // Invalid client nonce. | 908 // Invalid client nonce. |
871 DVLOG(1) << "Invalid client nonce."; | 909 DVLOG(1) << "Invalid client nonce."; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
916 | 954 |
917 void QuicCryptoServerConfig::BuildRejection( | 955 void QuicCryptoServerConfig::BuildRejection( |
918 const scoped_refptr<Config>& config, | 956 const scoped_refptr<Config>& config, |
919 const CryptoHandshakeMessage& client_hello, | 957 const CryptoHandshakeMessage& client_hello, |
920 const ClientHelloInfo& info, | 958 const ClientHelloInfo& info, |
921 QuicRandom* rand, | 959 QuicRandom* rand, |
922 CryptoHandshakeMessage* out) const { | 960 CryptoHandshakeMessage* out) const { |
923 out->set_tag(kREJ); | 961 out->set_tag(kREJ); |
924 out->SetStringPiece(kSCFG, config->serialized); | 962 out->SetStringPiece(kSCFG, config->serialized); |
925 out->SetStringPiece(kSourceAddressTokenTag, | 963 out->SetStringPiece(kSourceAddressTokenTag, |
926 NewSourceAddressToken(info.client_ip, rand, info.now)); | 964 NewSourceAddressToken( |
965 config, | |
966 info.client_ip, | |
967 rand, | |
968 info.now)); | |
927 if (replay_protection_) { | 969 if (replay_protection_) { |
928 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 970 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
929 } | 971 } |
930 | 972 |
931 // The client may have requested a certificate chain. | 973 // The client may have requested a certificate chain. |
932 const QuicTag* their_proof_demands; | 974 const QuicTag* their_proof_demands; |
933 size_t num_their_proof_demands; | 975 size_t num_their_proof_demands; |
934 | 976 |
935 if (proof_source_.get() == NULL || | 977 if (proof_source_.get() == NULL || |
936 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 978 client_hello.GetTaglist(kPDMD, &their_proof_demands, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1006 | 1048 |
1007 if (msg->tag() != kSCFG) { | 1049 if (msg->tag() != kSCFG) { |
1008 LOG(WARNING) << "Server config message has tag " << msg->tag() | 1050 LOG(WARNING) << "Server config message has tag " << msg->tag() |
1009 << " expected " << kSCFG; | 1051 << " expected " << kSCFG; |
1010 return NULL; | 1052 return NULL; |
1011 } | 1053 } |
1012 | 1054 |
1013 scoped_refptr<Config> config(new Config); | 1055 scoped_refptr<Config> config(new Config); |
1014 config->serialized = protobuf->config(); | 1056 config->serialized = protobuf->config(); |
1015 | 1057 |
1058 if (!protobuf->has_source_address_token_secret_override()) { | |
1059 // Use the default boxer. | |
1060 config->source_address_token_boxer = &default_source_address_token_boxer_; | |
1061 } else { | |
1062 // Create override boxer instance. | |
1063 CryptoSecretBoxer* boxer = new CryptoSecretBoxer; | |
1064 boxer->SetKey(ComputeSourceAddressTokenKey( | |
1065 protobuf->source_address_token_secret_override())); | |
1066 config->source_address_token_boxer_storage.reset(boxer); | |
1067 config->source_address_token_boxer = boxer; | |
1068 } | |
1069 | |
1016 if (protobuf->has_primary_time()) { | 1070 if (protobuf->has_primary_time()) { |
1017 config->primary_time = | 1071 config->primary_time = |
1018 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1072 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
1019 } | 1073 } |
1020 | 1074 |
1021 config->priority = protobuf->priority(); | 1075 config->priority = protobuf->priority(); |
1022 | 1076 |
1023 StringPiece scid; | 1077 StringPiece scid; |
1024 if (!msg->GetStringPiece(kSCID, &scid)) { | 1078 if (!msg->GetStringPiece(kSCID, &scid)) { |
1025 LOG(WARNING) << "Server config message is missing SCID"; | 1079 LOG(WARNING) << "Server config message is missing SCID"; |
(...skipping 11 matching lines...) Expand all Loading... | |
1037 | 1091 |
1038 const QuicTag* kexs_tags; | 1092 const QuicTag* kexs_tags; |
1039 size_t kexs_len; | 1093 size_t kexs_len; |
1040 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | 1094 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { |
1041 LOG(WARNING) << "Server config message is missing KEXS"; | 1095 LOG(WARNING) << "Server config message is missing KEXS"; |
1042 return NULL; | 1096 return NULL; |
1043 } | 1097 } |
1044 | 1098 |
1045 StringPiece orbit; | 1099 StringPiece orbit; |
1046 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1100 if (!msg->GetStringPiece(kORBT, &orbit)) { |
1047 LOG(WARNING) << "Server config message is missing OBIT"; | 1101 LOG(WARNING) << "Server config message is missing ORBT"; |
1048 return NULL; | 1102 return NULL; |
1049 } | 1103 } |
1050 | 1104 |
1051 if (orbit.size() != kOrbitSize) { | 1105 if (orbit.size() != kOrbitSize) { |
1052 LOG(WARNING) << "Orbit value in server config is the wrong length." | 1106 LOG(WARNING) << "Orbit value in server config is the wrong length." |
1053 " Got " << orbit.size() << " want " << kOrbitSize; | 1107 " Got " << orbit.size() << " want " << kOrbitSize; |
1054 return NULL; | 1108 return NULL; |
1055 } | 1109 } |
1056 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); | 1110 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); |
1057 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1111 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; | 1265 server_nonce_strike_register_window_secs_ = window_secs; |
1212 } | 1266 } |
1213 | 1267 |
1214 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1268 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
1215 PrimaryConfigChangedCallback* cb) { | 1269 PrimaryConfigChangedCallback* cb) { |
1216 base::AutoLock locked(configs_lock_); | 1270 base::AutoLock locked(configs_lock_); |
1217 primary_config_changed_cb_.reset(cb); | 1271 primary_config_changed_cb_.reset(cb); |
1218 } | 1272 } |
1219 | 1273 |
1220 string QuicCryptoServerConfig::NewSourceAddressToken( | 1274 string QuicCryptoServerConfig::NewSourceAddressToken( |
1275 const QuicCryptoServerConfig::Config* config, | |
1221 const IPEndPoint& ip, | 1276 const IPEndPoint& ip, |
1222 QuicRandom* rand, | 1277 QuicRandom* rand, |
1223 QuicWallTime now) const { | 1278 QuicWallTime now) const { |
1224 SourceAddressToken source_address_token; | 1279 SourceAddressToken source_address_token; |
1225 source_address_token.set_ip(IPAddressToPackedString(ip.address())); | 1280 source_address_token.set_ip(IPAddressToPackedString(ip.address())); |
1226 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1281 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
1227 | 1282 |
1228 return source_address_token_boxer_.Box( | 1283 return config->source_address_token_boxer->Box( |
1229 rand, source_address_token.SerializeAsString()); | 1284 rand, source_address_token.SerializeAsString()); |
1230 } | 1285 } |
1231 | 1286 |
1232 bool QuicCryptoServerConfig::ValidateSourceAddressToken( | 1287 bool QuicCryptoServerConfig::ValidateSourceAddressToken( |
1288 const QuicCryptoServerConfig::Config* config, | |
1233 StringPiece token, | 1289 StringPiece token, |
1234 const IPEndPoint& ip, | 1290 const IPEndPoint& ip, |
1235 QuicWallTime now) const { | 1291 QuicWallTime now) const { |
1236 string storage; | 1292 string storage; |
1237 StringPiece plaintext; | 1293 StringPiece plaintext; |
1238 if (!source_address_token_boxer_.Unbox(token, &storage, &plaintext)) { | 1294 if (!config->source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
1239 return false; | 1295 return false; |
1240 } | 1296 } |
1241 | 1297 |
1242 SourceAddressToken source_address_token; | 1298 SourceAddressToken source_address_token; |
1243 if (!source_address_token.ParseFromArray(plaintext.data(), | 1299 if (!source_address_token.ParseFromArray(plaintext.data(), |
1244 plaintext.size())) { | 1300 plaintext.size())) { |
1245 return false; | 1301 return false; |
1246 } | 1302 } |
1247 | 1303 |
1248 if (source_address_token.ip() != IPAddressToPackedString(ip.address())) { | 1304 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())); | 1386 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
1331 } | 1387 } |
1332 | 1388 |
1333 return is_unique; | 1389 return is_unique; |
1334 } | 1390 } |
1335 | 1391 |
1336 QuicCryptoServerConfig::Config::Config() | 1392 QuicCryptoServerConfig::Config::Config() |
1337 : channel_id_enabled(false), | 1393 : channel_id_enabled(false), |
1338 is_primary(false), | 1394 is_primary(false), |
1339 primary_time(QuicWallTime::Zero()), | 1395 primary_time(QuicWallTime::Zero()), |
1340 priority(0) {} | 1396 priority(0), |
1397 source_address_token_boxer(NULL) {} | |
1341 | 1398 |
1342 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1399 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
1343 | 1400 |
1344 } // namespace net | 1401 } // namespace net |
OLD | NEW |