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 |