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

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: Fix wtc's comments for patch set 5 Created 6 years, 7 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 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 return QUIC_CRYPTO_INTERNAL_ERROR; 537 return QUIC_CRYPTO_INTERNAL_ERROR;
521 } 538 }
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
547 // We'll use the config that the client requested in order to do
548 // key-agreement. Otherwise we'll give it a copy of |primary_config_|
549 // to use.
530 primary_config = primary_config_; 550 primary_config = primary_config_;
531 551
532 if (!requested_scid.empty()) { 552 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 } 553 }
542 554
543 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { 555 if (validate_chlo_result.error_code != QUIC_NO_ERROR) {
544 *error_details = validate_chlo_result.error_details; 556 *error_details = validate_chlo_result.error_details;
545 return validate_chlo_result.error_code; 557 return validate_chlo_result.error_code;
546 } 558 }
547 559
548 out->Clear(); 560 out->Clear();
549 561
550 if (!info.valid_source_address_token || 562 if (!info.valid_source_address_token ||
551 !info.client_nonce_well_formed || 563 !info.client_nonce_well_formed ||
552 !info.unique || 564 !info.unique ||
553 !requested_config.get()) { 565 !requested_config.get()) {
554 BuildRejection(primary_config.get(), client_hello, info, rand, out); 566 BuildRejection(*primary_config, client_hello, info, rand, out);
555 return QUIC_NO_ERROR; 567 return QUIC_NO_ERROR;
556 } 568 }
557 569
558 const QuicTag* their_aeads; 570 const QuicTag* their_aeads;
559 const QuicTag* their_key_exchanges; 571 const QuicTag* their_key_exchanges;
560 size_t num_their_aeads, num_their_key_exchanges; 572 size_t num_their_aeads, num_their_key_exchanges;
561 if (client_hello.GetTaglist(kAEAD, &their_aeads, 573 if (client_hello.GetTaglist(kAEAD, &their_aeads,
562 &num_their_aeads) != QUIC_NO_ERROR || 574 &num_their_aeads) != QUIC_NO_ERROR ||
563 client_hello.GetTaglist(kKEXS, &their_key_exchanges, 575 client_hello.GetTaglist(kKEXS, &their_key_exchanges,
564 &num_their_key_exchanges) != QUIC_NO_ERROR || 576 &num_their_key_exchanges) != QUIC_NO_ERROR ||
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 723 }
712 724
713 out->set_tag(kSHLO); 725 out->set_tag(kSHLO);
714 QuicTagVector supported_version_tags; 726 QuicTagVector supported_version_tags;
715 for (size_t i = 0; i < supported_versions.size(); ++i) { 727 for (size_t i = 0; i < supported_versions.size(); ++i) {
716 supported_version_tags.push_back 728 supported_version_tags.push_back
717 (QuicVersionToQuicTag(supported_versions[i])); 729 (QuicVersionToQuicTag(supported_versions[i]));
718 } 730 }
719 out->SetVector(kVER, supported_version_tags); 731 out->SetVector(kVER, supported_version_tags);
720 out->SetStringPiece(kSourceAddressTokenTag, 732 out->SetStringPiece(kSourceAddressTokenTag,
721 NewSourceAddressToken(client_address, rand, info.now)); 733 NewSourceAddressToken(
734 *requested_config,
735 client_address, rand,
736 info.now));
722 QuicSocketAddressCoder address_coder(client_address); 737 QuicSocketAddressCoder address_coder(client_address);
723 out->SetStringPiece(kCADR, address_coder.Encode()); 738 out->SetStringPiece(kCADR, address_coder.Encode());
724 out->SetStringPiece(kPUBS, forward_secure_public_value); 739 out->SetStringPiece(kPUBS, forward_secure_public_value);
725 740
726 // Set initial receive window for flow control. 741 // Set initial receive window for flow control.
727 out->SetValue(kIFCW, initial_flow_control_window_bytes); 742 out->SetValue(kIFCW, initial_flow_control_window_bytes);
728 743
729 return QUIC_NO_ERROR; 744 return QUIC_NO_ERROR;
730 } 745 }
731 746
747 scoped_refptr<QuicCryptoServerConfig::Config>
748 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const {
749 // In Chromium, we will dead lock if the lock is held by the current thread.
750 // Chromium doesn't have AssertReaderHeld API call.
751 // configs_lock_.AssertReaderHeld();
752
753 if (!requested_scid.empty()) {
754 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string());
755 if (it != configs_.end()) {
756 // We'll use the config that the client requested in order to do
757 // key-agreement.
758 return scoped_refptr<Config>(it->second);
759 }
760 }
761
762 return scoped_refptr<Config>();
763 }
764
732 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for 765 // ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
733 // Config's based on their primary_time. 766 // Config's based on their primary_time.
734 // static 767 // static
735 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( 768 bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan(
736 const scoped_refptr<Config>& a, 769 const scoped_refptr<Config>& a,
737 const scoped_refptr<Config>& b) { 770 const scoped_refptr<Config>& b) {
738 if (a->primary_time.IsBefore(b->primary_time) || 771 if (a->primary_time.IsBefore(b->primary_time) ||
739 b->primary_time.IsBefore(a->primary_time)) { 772 b->primary_time.IsBefore(a->primary_time)) {
740 // Primary times differ. 773 // Primary times differ.
741 return a->primary_time.IsBefore(b->primary_time); 774 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. 849 // and highest priority candidate primary.
817 scoped_refptr<Config> new_primary(best_candidate); 850 scoped_refptr<Config> new_primary(best_candidate);
818 if (primary_config_.get()) { 851 if (primary_config_.get()) {
819 primary_config_->is_primary = false; 852 primary_config_->is_primary = false;
820 } 853 }
821 primary_config_ = new_primary; 854 primary_config_ = new_primary;
822 new_primary->is_primary = true; 855 new_primary->is_primary = true;
823 DVLOG(1) << "New primary config. orbit: " 856 DVLOG(1) << "New primary config. orbit: "
824 << base::HexEncode( 857 << base::HexEncode(
825 reinterpret_cast<const char*>(primary_config_->orbit), 858 reinterpret_cast<const char*>(primary_config_->orbit),
826 kOrbitSize); 859 kOrbitSize)
860 << " scid: " << base::HexEncode(primary_config_->id.data(),
861 primary_config_->id.size());
827 next_config_promotion_time_ = QuicWallTime::Zero(); 862 next_config_promotion_time_ = QuicWallTime::Zero();
828 if (primary_config_changed_cb_.get() != NULL) { 863 if (primary_config_changed_cb_.get() != NULL) {
829 primary_config_changed_cb_->Run(primary_config_->id); 864 primary_config_changed_cb_->Run(primary_config_->id);
830 } 865 }
831 } 866 }
832 867
833 void QuicCryptoServerConfig::EvaluateClientHello( 868 void QuicCryptoServerConfig::EvaluateClientHello(
834 const uint8* primary_orbit, 869 const uint8* primary_orbit,
870 scoped_refptr<Config> requested_config,
835 ValidateClientHelloResultCallback::Result* client_hello_state, 871 ValidateClientHelloResultCallback::Result* client_hello_state,
836 ValidateClientHelloResultCallback* done_cb) const { 872 ValidateClientHelloResultCallback* done_cb) const {
837 ValidateClientHelloHelper helper(client_hello_state, done_cb); 873 ValidateClientHelloHelper helper(client_hello_state, done_cb);
838 874
839 const CryptoHandshakeMessage& client_hello = 875 const CryptoHandshakeMessage& client_hello =
840 client_hello_state->client_hello; 876 client_hello_state->client_hello;
841 ClientHelloInfo* info = &(client_hello_state->info); 877 ClientHelloInfo* info = &(client_hello_state->info);
842 878
843 if (client_hello.size() < kClientHelloMinimumSize) { 879 if (client_hello.size() < kClientHelloMinimumSize) {
844 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, 880 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH,
845 "Client hello too small"); 881 "Client hello too small");
846 return; 882 return;
847 } 883 }
848 884
849 if (client_hello.GetStringPiece(kSNI, &info->sni) && 885 if (client_hello.GetStringPiece(kSNI, &info->sni) &&
850 !CryptoUtils::IsValidSNI(info->sni)) { 886 !CryptoUtils::IsValidSNI(info->sni)) {
851 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, 887 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER,
852 "Invalid SNI name"); 888 "Invalid SNI name");
853 return; 889 return;
854 } 890 }
855 891
856 StringPiece srct; 892 StringPiece srct;
857 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && 893 if (requested_config.get() != NULL &&
858 ValidateSourceAddressToken(srct, info->client_ip, info->now)) { 894 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) &&
895 ValidateSourceAddressToken(*requested_config,
896 srct,
897 info->client_ip,
898 info->now)) {
859 info->valid_source_address_token = true; 899 info->valid_source_address_token = true;
860 } else { 900 } else {
861 // No valid source address token. 901 // No server config with the requested ID, or no valid source address token.
862 helper.ValidationComplete(QUIC_NO_ERROR, ""); 902 helper.ValidationComplete(QUIC_NO_ERROR, "");
863 return; 903 return;
864 } 904 }
865 905
866 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && 906 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) &&
867 info->client_nonce.size() == kNonceSize) { 907 info->client_nonce.size() == kNonceSize) {
868 info->client_nonce_well_formed = true; 908 info->client_nonce_well_formed = true;
869 } else { 909 } else {
870 // Invalid client nonce. 910 // Invalid client nonce.
871 DVLOG(1) << "Invalid client nonce."; 911 DVLOG(1) << "Invalid client nonce.";
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 } 948 }
909 949
910 strike_register_client->VerifyNonceIsValidAndUnique( 950 strike_register_client->VerifyNonceIsValidAndUnique(
911 info->client_nonce, 951 info->client_nonce,
912 info->now, 952 info->now,
913 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); 953 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb));
914 helper.StartedAsyncCallback(); 954 helper.StartedAsyncCallback();
915 } 955 }
916 956
917 void QuicCryptoServerConfig::BuildRejection( 957 void QuicCryptoServerConfig::BuildRejection(
918 const scoped_refptr<Config>& config, 958 const Config& config,
919 const CryptoHandshakeMessage& client_hello, 959 const CryptoHandshakeMessage& client_hello,
920 const ClientHelloInfo& info, 960 const ClientHelloInfo& info,
921 QuicRandom* rand, 961 QuicRandom* rand,
922 CryptoHandshakeMessage* out) const { 962 CryptoHandshakeMessage* out) const {
923 out->set_tag(kREJ); 963 out->set_tag(kREJ);
924 out->SetStringPiece(kSCFG, config->serialized); 964 out->SetStringPiece(kSCFG, config.serialized);
925 out->SetStringPiece(kSourceAddressTokenTag, 965 out->SetStringPiece(kSourceAddressTokenTag,
926 NewSourceAddressToken(info.client_ip, rand, info.now)); 966 NewSourceAddressToken(
967 config,
968 info.client_ip,
969 rand,
970 info.now));
927 if (replay_protection_) { 971 if (replay_protection_) {
928 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); 972 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
929 } 973 }
930 974
931 // The client may have requested a certificate chain. 975 // The client may have requested a certificate chain.
932 const QuicTag* their_proof_demands; 976 const QuicTag* their_proof_demands;
933 size_t num_their_proof_demands; 977 size_t num_their_proof_demands;
934 978
935 if (proof_source_.get() == NULL || 979 if (proof_source_.get() == NULL ||
936 client_hello.GetTaglist(kPDMD, &their_proof_demands, 980 client_hello.GetTaglist(kPDMD, &their_proof_demands,
(...skipping 14 matching lines...) Expand all
951 break; 995 break;
952 } 996 }
953 } 997 }
954 998
955 if (!x509_supported) { 999 if (!x509_supported) {
956 return; 1000 return;
957 } 1001 }
958 1002
959 const vector<string>* certs; 1003 const vector<string>* certs;
960 string signature; 1004 string signature;
961 if (!proof_source_->GetProof(info.sni.as_string(), config->serialized, 1005 if (!proof_source_->GetProof(info.sni.as_string(), config.serialized,
962 x509_ecdsa_supported, &certs, &signature)) { 1006 x509_ecdsa_supported, &certs, &signature)) {
963 return; 1007 return;
964 } 1008 }
965 1009
966 StringPiece their_common_set_hashes; 1010 StringPiece their_common_set_hashes;
967 StringPiece their_cached_cert_hashes; 1011 StringPiece their_cached_cert_hashes;
968 client_hello.GetStringPiece(kCCS, &their_common_set_hashes); 1012 client_hello.GetStringPiece(kCCS, &their_common_set_hashes);
969 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes); 1013 client_hello.GetStringPiece(kCCRT, &their_cached_cert_hashes);
970 1014
971 const string compressed = CertCompressor::CompressChain( 1015 const string compressed = CertCompressor::CompressChain(
972 *certs, their_common_set_hashes, their_cached_cert_hashes, 1016 *certs, their_common_set_hashes, their_cached_cert_hashes,
973 config->common_cert_sets); 1017 config.common_cert_sets);
974 1018
975 // kREJOverheadBytes is a very rough estimate of how much of a REJ 1019 // kREJOverheadBytes is a very rough estimate of how much of a REJ
976 // message is taken up by things other than the certificates. 1020 // message is taken up by things other than the certificates.
977 // STK: 56 bytes 1021 // STK: 56 bytes
978 // SNO: 56 bytes 1022 // SNO: 56 bytes
979 // SCFG 1023 // SCFG
980 // SCID: 16 bytes 1024 // SCID: 16 bytes
981 // PUBS: 38 bytes 1025 // PUBS: 38 bytes
982 const size_t kREJOverheadBytes = 166; 1026 const size_t kREJOverheadBytes = 166;
983 // kMultiplier is the multiple of the CHLO message size that a REJ message 1027 // kMultiplier is the multiple of the CHLO message size that a REJ message
(...skipping 22 matching lines...) Expand all
1006 1050
1007 if (msg->tag() != kSCFG) { 1051 if (msg->tag() != kSCFG) {
1008 LOG(WARNING) << "Server config message has tag " << msg->tag() 1052 LOG(WARNING) << "Server config message has tag " << msg->tag()
1009 << " expected " << kSCFG; 1053 << " expected " << kSCFG;
1010 return NULL; 1054 return NULL;
1011 } 1055 }
1012 1056
1013 scoped_refptr<Config> config(new Config); 1057 scoped_refptr<Config> config(new Config);
1014 config->serialized = protobuf->config(); 1058 config->serialized = protobuf->config();
1015 1059
1060 if (!protobuf->has_source_address_token_secret_override()) {
1061 // Use the default boxer.
1062 config->source_address_token_boxer = &default_source_address_token_boxer_;
1063 } else {
1064 // Create override boxer instance.
1065 CryptoSecretBoxer* boxer = new CryptoSecretBoxer;
1066 boxer->SetKey(DeriveSourceAddressTokenKey(
1067 protobuf->source_address_token_secret_override()));
1068 config->source_address_token_boxer_storage.reset(boxer);
1069 config->source_address_token_boxer = boxer;
1070 }
1071
1016 if (protobuf->has_primary_time()) { 1072 if (protobuf->has_primary_time()) {
1017 config->primary_time = 1073 config->primary_time =
1018 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); 1074 QuicWallTime::FromUNIXSeconds(protobuf->primary_time());
1019 } 1075 }
1020 1076
1021 config->priority = protobuf->priority(); 1077 config->priority = protobuf->priority();
1022 1078
1023 StringPiece scid; 1079 StringPiece scid;
1024 if (!msg->GetStringPiece(kSCID, &scid)) { 1080 if (!msg->GetStringPiece(kSCID, &scid)) {
1025 LOG(WARNING) << "Server config message is missing SCID"; 1081 LOG(WARNING) << "Server config message is missing SCID";
(...skipping 11 matching lines...) Expand all
1037 1093
1038 const QuicTag* kexs_tags; 1094 const QuicTag* kexs_tags;
1039 size_t kexs_len; 1095 size_t kexs_len;
1040 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { 1096 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) {
1041 LOG(WARNING) << "Server config message is missing KEXS"; 1097 LOG(WARNING) << "Server config message is missing KEXS";
1042 return NULL; 1098 return NULL;
1043 } 1099 }
1044 1100
1045 StringPiece orbit; 1101 StringPiece orbit;
1046 if (!msg->GetStringPiece(kORBT, &orbit)) { 1102 if (!msg->GetStringPiece(kORBT, &orbit)) {
1047 LOG(WARNING) << "Server config message is missing OBIT"; 1103 LOG(WARNING) << "Server config message is missing ORBT";
1048 return NULL; 1104 return NULL;
1049 } 1105 }
1050 1106
1051 if (orbit.size() != kOrbitSize) { 1107 if (orbit.size() != kOrbitSize) {
1052 LOG(WARNING) << "Orbit value in server config is the wrong length." 1108 LOG(WARNING) << "Orbit value in server config is the wrong length."
1053 " Got " << orbit.size() << " want " << kOrbitSize; 1109 " Got " << orbit.size() << " want " << kOrbitSize;
1054 return NULL; 1110 return NULL;
1055 } 1111 }
1056 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); 1112 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size);
1057 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); 1113 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; 1267 server_nonce_strike_register_window_secs_ = window_secs;
1212 } 1268 }
1213 1269
1214 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( 1270 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
1215 PrimaryConfigChangedCallback* cb) { 1271 PrimaryConfigChangedCallback* cb) {
1216 base::AutoLock locked(configs_lock_); 1272 base::AutoLock locked(configs_lock_);
1217 primary_config_changed_cb_.reset(cb); 1273 primary_config_changed_cb_.reset(cb);
1218 } 1274 }
1219 1275
1220 string QuicCryptoServerConfig::NewSourceAddressToken( 1276 string QuicCryptoServerConfig::NewSourceAddressToken(
1277 const Config& config,
1221 const IPEndPoint& ip, 1278 const IPEndPoint& ip,
1222 QuicRandom* rand, 1279 QuicRandom* rand,
1223 QuicWallTime now) const { 1280 QuicWallTime now) const {
1224 SourceAddressToken source_address_token; 1281 SourceAddressToken source_address_token;
1225 source_address_token.set_ip(IPAddressToPackedString(ip.address())); 1282 source_address_token.set_ip(IPAddressToPackedString(ip.address()));
1226 source_address_token.set_timestamp(now.ToUNIXSeconds()); 1283 source_address_token.set_timestamp(now.ToUNIXSeconds());
1227 1284
1228 return source_address_token_boxer_.Box( 1285 return config.source_address_token_boxer->Box(
1229 rand, source_address_token.SerializeAsString()); 1286 rand, source_address_token.SerializeAsString());
1230 } 1287 }
1231 1288
1232 bool QuicCryptoServerConfig::ValidateSourceAddressToken( 1289 bool QuicCryptoServerConfig::ValidateSourceAddressToken(
1290 const Config& config,
1233 StringPiece token, 1291 StringPiece token,
1234 const IPEndPoint& ip, 1292 const IPEndPoint& ip,
1235 QuicWallTime now) const { 1293 QuicWallTime now) const {
1236 string storage; 1294 string storage;
1237 StringPiece plaintext; 1295 StringPiece plaintext;
1238 if (!source_address_token_boxer_.Unbox(token, &storage, &plaintext)) { 1296 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
1239 return false; 1297 return false;
1240 } 1298 }
1241 1299
1242 SourceAddressToken source_address_token; 1300 SourceAddressToken source_address_token;
1243 if (!source_address_token.ParseFromArray(plaintext.data(), 1301 if (!source_address_token.ParseFromArray(plaintext.data(),
1244 plaintext.size())) { 1302 plaintext.size())) {
1245 return false; 1303 return false;
1246 } 1304 }
1247 1305
1248 if (source_address_token.ip() != IPAddressToPackedString(ip.address())) { 1306 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())); 1388 server_nonce, static_cast<uint32>(now.ToUNIXSeconds()));
1331 } 1389 }
1332 1390
1333 return is_unique; 1391 return is_unique;
1334 } 1392 }
1335 1393
1336 QuicCryptoServerConfig::Config::Config() 1394 QuicCryptoServerConfig::Config::Config()
1337 : channel_id_enabled(false), 1395 : channel_id_enabled(false),
1338 is_primary(false), 1396 is_primary(false),
1339 primary_time(QuicWallTime::Zero()), 1397 primary_time(QuicWallTime::Zero()),
1340 priority(0) {} 1398 priority(0),
1399 source_address_token_boxer(NULL) {}
1341 1400
1342 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1401 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1343 1402
1344 } // namespace net 1403 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698