Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: net/quic/crypto/quic_crypto_server_config.cc

Issue 213473003: This change introduces a way to tie source address token keys to specific QUIC server configs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge internal change: 65382861 Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698