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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 }; | 105 }; |
106 | 106 |
107 class ValidateClientHelloHelper { | 107 class ValidateClientHelloHelper { |
108 public: | 108 public: |
109 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, | 109 ValidateClientHelloHelper(ValidateClientHelloResultCallback::Result* result, |
110 ValidateClientHelloResultCallback* done_cb) | 110 ValidateClientHelloResultCallback* done_cb) |
111 : result_(result), done_cb_(done_cb) { | 111 : result_(result), done_cb_(done_cb) { |
112 } | 112 } |
113 | 113 |
114 ~ValidateClientHelloHelper() { | 114 ~ValidateClientHelloHelper() { |
115 LOG_IF(DFATAL, done_cb_ != NULL) | 115 LOG_IF(DFATAL, done_cb_ != nullptr) |
116 << "Deleting ValidateClientHelloHelper with a pending callback."; | 116 << "Deleting ValidateClientHelloHelper with a pending callback."; |
117 } | 117 } |
118 | 118 |
119 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { | 119 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { |
120 result_->error_code = error_code; | 120 result_->error_code = error_code; |
121 result_->error_details = error_details; | 121 result_->error_details = error_details; |
122 done_cb_->Run(result_); | 122 done_cb_->Run(result_); |
123 DetachCallback(); | 123 DetachCallback(); |
124 } | 124 } |
125 | 125 |
126 void StartedAsyncCallback() { | 126 void StartedAsyncCallback() { |
127 DetachCallback(); | 127 DetachCallback(); |
128 } | 128 } |
129 | 129 |
130 private: | 130 private: |
131 void DetachCallback() { | 131 void DetachCallback() { |
132 LOG_IF(DFATAL, done_cb_ == NULL) << "Callback already detached."; | 132 LOG_IF(DFATAL, done_cb_ == nullptr) << "Callback already detached."; |
133 done_cb_ = NULL; | 133 done_cb_ = nullptr; |
134 } | 134 } |
135 | 135 |
136 ValidateClientHelloResultCallback::Result* result_; | 136 ValidateClientHelloResultCallback::Result* result_; |
137 ValidateClientHelloResultCallback* done_cb_; | 137 ValidateClientHelloResultCallback* done_cb_; |
138 | 138 |
139 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); | 139 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); |
140 }; | 140 }; |
141 | 141 |
142 class VerifyNonceIsValidAndUniqueCallback | 142 class VerifyNonceIsValidAndUniqueCallback |
143 : public StrikeRegisterClient::ResultCallback { | 143 : public StrikeRegisterClient::ResultCallback { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() | 220 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() |
221 : expiry_time(QuicWallTime::Zero()), | 221 : expiry_time(QuicWallTime::Zero()), |
222 channel_id_enabled(false), | 222 channel_id_enabled(false), |
223 p256(false) {} | 223 p256(false) {} |
224 | 224 |
225 QuicCryptoServerConfig::QuicCryptoServerConfig( | 225 QuicCryptoServerConfig::QuicCryptoServerConfig( |
226 StringPiece source_address_token_secret, | 226 StringPiece source_address_token_secret, |
227 QuicRandom* rand) | 227 QuicRandom* rand) |
228 : replay_protection_(true), | 228 : replay_protection_(true), |
229 configs_lock_(), | 229 configs_lock_(), |
230 primary_config_(NULL), | 230 primary_config_(nullptr), |
231 next_config_promotion_time_(QuicWallTime::Zero()), | 231 next_config_promotion_time_(QuicWallTime::Zero()), |
232 server_nonce_strike_register_lock_(), | 232 server_nonce_strike_register_lock_(), |
233 strike_register_no_startup_period_(false), | 233 strike_register_no_startup_period_(false), |
234 strike_register_max_entries_(1 << 10), | 234 strike_register_max_entries_(1 << 10), |
235 strike_register_window_secs_(600), | 235 strike_register_window_secs_(600), |
236 source_address_token_future_secs_(3600), | 236 source_address_token_future_secs_(3600), |
237 source_address_token_lifetime_secs_(86400), | 237 source_address_token_lifetime_secs_(86400), |
238 server_nonce_strike_register_max_entries_(1 << 10), | 238 server_nonce_strike_register_max_entries_(1 << 10), |
239 server_nonce_strike_register_window_secs_(120) { | 239 server_nonce_strike_register_window_secs_(120) { |
240 default_source_address_token_boxer_.SetKey( | 240 default_source_address_token_boxer_.SetKey( |
241 DeriveSourceAddressTokenKey(source_address_token_secret)); | 241 DeriveSourceAddressTokenKey(source_address_token_secret)); |
242 | 242 |
243 // Generate a random key and orbit for server nonces. | 243 // Generate a random key and orbit for server nonces. |
244 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 244 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
245 const size_t key_size = server_nonce_boxer_.GetKeySize(); | 245 const size_t key_size = server_nonce_boxer_.GetKeySize(); |
246 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); | 246 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); |
247 rand->RandBytes(key_bytes.get(), key_size); | 247 rand->RandBytes(key_bytes.get(), key_size); |
248 | 248 |
249 server_nonce_boxer_.SetKey( | 249 server_nonce_boxer_.SetKey( |
250 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); | 250 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); |
251 } | 251 } |
252 | 252 |
253 QuicCryptoServerConfig::~QuicCryptoServerConfig() { | 253 QuicCryptoServerConfig::~QuicCryptoServerConfig() { |
254 primary_config_ = NULL; | 254 primary_config_ = nullptr; |
255 } | 255 } |
256 | 256 |
257 // static | 257 // static |
258 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig( | 258 QuicServerConfigProtobuf* QuicCryptoServerConfig::GenerateConfig( |
259 QuicRandom* rand, | 259 QuicRandom* rand, |
260 const QuicClock* clock, | 260 const QuicClock* clock, |
261 const ConfigOptions& options) { | 261 const ConfigOptions& options) { |
262 CryptoHandshakeMessage msg; | 262 CryptoHandshakeMessage msg; |
263 | 263 |
264 const string curve25519_private_key = | 264 const string curve25519_private_key = |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 360 } |
361 | 361 |
362 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( | 362 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( |
363 QuicServerConfigProtobuf* protobuf, | 363 QuicServerConfigProtobuf* protobuf, |
364 const QuicWallTime now) { | 364 const QuicWallTime now) { |
365 scoped_ptr<CryptoHandshakeMessage> msg( | 365 scoped_ptr<CryptoHandshakeMessage> msg( |
366 CryptoFramer::ParseMessage(protobuf->config())); | 366 CryptoFramer::ParseMessage(protobuf->config())); |
367 | 367 |
368 if (!msg.get()) { | 368 if (!msg.get()) { |
369 LOG(WARNING) << "Failed to parse server config message"; | 369 LOG(WARNING) << "Failed to parse server config message"; |
370 return NULL; | 370 return nullptr; |
371 } | 371 } |
372 | 372 |
373 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); | 373 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); |
374 if (!config.get()) { | 374 if (!config.get()) { |
375 LOG(WARNING) << "Failed to parse server config message"; | 375 LOG(WARNING) << "Failed to parse server config message"; |
376 return NULL; | 376 return nullptr; |
377 } | 377 } |
378 | 378 |
379 { | 379 { |
380 base::AutoLock locked(configs_lock_); | 380 base::AutoLock locked(configs_lock_); |
381 if (configs_.find(config->id) != configs_.end()) { | 381 if (configs_.find(config->id) != configs_.end()) { |
382 LOG(WARNING) << "Failed to add config because another with the same " | 382 LOG(WARNING) << "Failed to add config because another with the same " |
383 "server config id already exists: " | 383 "server config id already exists: " |
384 << base::HexEncode(config->id.data(), config->id.size()); | 384 << base::HexEncode(config->id.data(), config->id.size()); |
385 return NULL; | 385 return nullptr; |
386 } | 386 } |
387 | 387 |
388 configs_[config->id] = config; | 388 configs_[config->id] = config; |
389 SelectNewPrimaryConfig(now); | 389 SelectNewPrimaryConfig(now); |
390 DCHECK(primary_config_.get()); | 390 DCHECK(primary_config_.get()); |
391 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 391 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
392 } | 392 } |
393 | 393 |
394 return msg.release(); | 394 return msg.release(); |
395 } | 395 } |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 &num_their_key_exchanges) != QUIC_NO_ERROR || | 617 &num_their_key_exchanges) != QUIC_NO_ERROR || |
618 num_their_aeads != 1 || | 618 num_their_aeads != 1 || |
619 num_their_key_exchanges != 1) { | 619 num_their_key_exchanges != 1) { |
620 *error_details = "Missing or invalid AEAD or KEXS"; | 620 *error_details = "Missing or invalid AEAD or KEXS"; |
621 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 621 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
622 } | 622 } |
623 | 623 |
624 size_t key_exchange_index; | 624 size_t key_exchange_index; |
625 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, | 625 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, |
626 num_their_aeads, QuicUtils::LOCAL_PRIORITY, | 626 num_their_aeads, QuicUtils::LOCAL_PRIORITY, |
627 ¶ms->aead, NULL) || | 627 ¶ms->aead, nullptr) || |
628 !QuicUtils::FindMutualTag( | 628 !QuicUtils::FindMutualTag( |
629 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, | 629 requested_config->kexs, their_key_exchanges, num_their_key_exchanges, |
630 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, | 630 QuicUtils::LOCAL_PRIORITY, ¶ms->key_exchange, |
631 &key_exchange_index)) { | 631 &key_exchange_index)) { |
632 *error_details = "Unsupported AEAD or KEXS"; | 632 *error_details = "Unsupported AEAD or KEXS"; |
633 return QUIC_CRYPTO_NO_SUPPORT; | 633 return QUIC_CRYPTO_NO_SUPPORT; |
634 } | 634 } |
635 | 635 |
636 StringPiece public_value; | 636 StringPiece public_value; |
637 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 637 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 678 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
679 sizeof(connection_id)); | 679 sizeof(connection_id)); |
680 hkdf_input.append(client_hello_serialized.data(), | 680 hkdf_input.append(client_hello_serialized.data(), |
681 client_hello_serialized.length()); | 681 client_hello_serialized.length()); |
682 hkdf_input.append(requested_config->serialized); | 682 hkdf_input.append(requested_config->serialized); |
683 | 683 |
684 CrypterPair crypters; | 684 CrypterPair crypters; |
685 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 685 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, |
686 info.client_nonce, info.server_nonce, | 686 info.client_nonce, info.server_nonce, |
687 hkdf_input, CryptoUtils::SERVER, &crypters, | 687 hkdf_input, CryptoUtils::SERVER, &crypters, |
688 NULL /* subkey secret */)) { | 688 nullptr /* subkey secret */)) { |
689 *error_details = "Symmetric key setup failed"; | 689 *error_details = "Symmetric key setup failed"; |
690 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 690 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
691 } | 691 } |
692 | 692 |
693 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( | 693 scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket( |
694 0 /* sequence number */, StringPiece() /* associated data */, | 694 0 /* sequence number */, StringPiece() /* associated data */, |
695 cetv_ciphertext)); | 695 cetv_ciphertext)); |
696 if (!cetv_plaintext.get()) { | 696 if (!cetv_plaintext.get()) { |
697 *error_details = "CETV decryption failure"; | 697 *error_details = "CETV decryption failure"; |
698 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 698 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
(...skipping 21 matching lines...) Expand all Loading... |
720 string hkdf_input; | 720 string hkdf_input; |
721 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 721 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
722 hkdf_input.reserve(label_len + hkdf_suffix.size()); | 722 hkdf_input.reserve(label_len + hkdf_suffix.size()); |
723 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); | 723 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
724 hkdf_input.append(hkdf_suffix); | 724 hkdf_input.append(hkdf_suffix); |
725 | 725 |
726 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 726 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, |
727 info.client_nonce, info.server_nonce, hkdf_input, | 727 info.client_nonce, info.server_nonce, hkdf_input, |
728 CryptoUtils::SERVER, | 728 CryptoUtils::SERVER, |
729 ¶ms->initial_crypters, | 729 ¶ms->initial_crypters, |
730 NULL /* subkey secret */)) { | 730 nullptr /* subkey secret */)) { |
731 *error_details = "Symmetric key setup failed"; | 731 *error_details = "Symmetric key setup failed"; |
732 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 732 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
733 } | 733 } |
734 | 734 |
735 string forward_secure_public_value; | 735 string forward_secure_public_value; |
736 if (ephemeral_key_source_.get()) { | 736 if (ephemeral_key_source_.get()) { |
737 params->forward_secure_premaster_secret = | 737 params->forward_secure_premaster_secret = |
738 ephemeral_key_source_->CalculateForwardSecureKey( | 738 ephemeral_key_source_->CalculateForwardSecureKey( |
739 key_exchange, rand, clock->ApproximateNow(), public_value, | 739 key_exchange, rand, clock->ApproximateNow(), public_value, |
740 &forward_secure_public_value); | 740 &forward_secure_public_value); |
(...skipping 27 matching lines...) Expand all Loading... |
768 | 768 |
769 out->set_tag(kSHLO); | 769 out->set_tag(kSHLO); |
770 QuicTagVector supported_version_tags; | 770 QuicTagVector supported_version_tags; |
771 for (size_t i = 0; i < supported_versions.size(); ++i) { | 771 for (size_t i = 0; i < supported_versions.size(); ++i) { |
772 supported_version_tags.push_back | 772 supported_version_tags.push_back |
773 (QuicVersionToQuicTag(supported_versions[i])); | 773 (QuicVersionToQuicTag(supported_versions[i])); |
774 } | 774 } |
775 out->SetVector(kVER, supported_version_tags); | 775 out->SetVector(kVER, supported_version_tags); |
776 out->SetStringPiece( | 776 out->SetStringPiece( |
777 kSourceAddressTokenTag, | 777 kSourceAddressTokenTag, |
778 NewSourceAddressToken( | 778 NewSourceAddressToken(*requested_config.get(), |
779 *requested_config.get(), client_address, rand, info.now, NULL)); | 779 client_address, |
| 780 rand, |
| 781 info.now, |
| 782 nullptr)); |
780 QuicSocketAddressCoder address_coder(client_address); | 783 QuicSocketAddressCoder address_coder(client_address); |
781 out->SetStringPiece(kCADR, address_coder.Encode()); | 784 out->SetStringPiece(kCADR, address_coder.Encode()); |
782 out->SetStringPiece(kPUBS, forward_secure_public_value); | 785 out->SetStringPiece(kPUBS, forward_secure_public_value); |
783 | 786 |
784 return QUIC_NO_ERROR; | 787 return QUIC_NO_ERROR; |
785 } | 788 } |
786 | 789 |
787 scoped_refptr<QuicCryptoServerConfig::Config> | 790 scoped_refptr<QuicCryptoServerConfig::Config> |
788 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | 791 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { |
789 // In Chromium, we will dead lock if the lock is held by the current thread. | 792 // In Chromium, we will dead lock if the lock is held by the current thread. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 | 874 |
872 if (primary_config_.get()) { | 875 if (primary_config_.get()) { |
873 primary_config_->is_primary = false; | 876 primary_config_->is_primary = false; |
874 } | 877 } |
875 primary_config_ = new_primary; | 878 primary_config_ = new_primary; |
876 new_primary->is_primary = true; | 879 new_primary->is_primary = true; |
877 DVLOG(1) << "New primary config. orbit: " | 880 DVLOG(1) << "New primary config. orbit: " |
878 << base::HexEncode( | 881 << base::HexEncode( |
879 reinterpret_cast<const char*>(primary_config_->orbit), | 882 reinterpret_cast<const char*>(primary_config_->orbit), |
880 kOrbitSize); | 883 kOrbitSize); |
881 if (primary_config_changed_cb_.get() != NULL) { | 884 if (primary_config_changed_cb_.get() != nullptr) { |
882 primary_config_changed_cb_->Run(primary_config_->id); | 885 primary_config_changed_cb_->Run(primary_config_->id); |
883 } | 886 } |
884 | 887 |
885 return; | 888 return; |
886 } | 889 } |
887 | 890 |
888 // All config's primary times are in the past. We should make the most recent | 891 // All config's primary times are in the past. We should make the most recent |
889 // and highest priority candidate primary. | 892 // and highest priority candidate primary. |
890 scoped_refptr<Config> new_primary(best_candidate); | 893 scoped_refptr<Config> new_primary(best_candidate); |
891 if (primary_config_.get()) { | 894 if (primary_config_.get()) { |
892 primary_config_->is_primary = false; | 895 primary_config_->is_primary = false; |
893 } | 896 } |
894 primary_config_ = new_primary; | 897 primary_config_ = new_primary; |
895 new_primary->is_primary = true; | 898 new_primary->is_primary = true; |
896 DVLOG(1) << "New primary config. orbit: " | 899 DVLOG(1) << "New primary config. orbit: " |
897 << base::HexEncode( | 900 << base::HexEncode( |
898 reinterpret_cast<const char*>(primary_config_->orbit), | 901 reinterpret_cast<const char*>(primary_config_->orbit), |
899 kOrbitSize) | 902 kOrbitSize) |
900 << " scid: " << base::HexEncode(primary_config_->id.data(), | 903 << " scid: " << base::HexEncode(primary_config_->id.data(), |
901 primary_config_->id.size()); | 904 primary_config_->id.size()); |
902 next_config_promotion_time_ = QuicWallTime::Zero(); | 905 next_config_promotion_time_ = QuicWallTime::Zero(); |
903 if (primary_config_changed_cb_.get() != NULL) { | 906 if (primary_config_changed_cb_.get() != nullptr) { |
904 primary_config_changed_cb_->Run(primary_config_->id); | 907 primary_config_changed_cb_->Run(primary_config_->id); |
905 } | 908 } |
906 } | 909 } |
907 | 910 |
908 void QuicCryptoServerConfig::EvaluateClientHello( | 911 void QuicCryptoServerConfig::EvaluateClientHello( |
909 const uint8* primary_orbit, | 912 const uint8* primary_orbit, |
910 scoped_refptr<Config> requested_config, | 913 scoped_refptr<Config> requested_config, |
911 ValidateClientHelloResultCallback::Result* client_hello_state, | 914 ValidateClientHelloResultCallback::Result* client_hello_state, |
912 ValidateClientHelloResultCallback* done_cb) const { | 915 ValidateClientHelloResultCallback* done_cb) const { |
913 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 916 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 if (found_error) { | 1012 if (found_error) { |
1010 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 1013 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
1011 return; | 1014 return; |
1012 } | 1015 } |
1013 | 1016 |
1014 // Use the client nonce to establish uniqueness. | 1017 // Use the client nonce to establish uniqueness. |
1015 StrikeRegisterClient* strike_register_client; | 1018 StrikeRegisterClient* strike_register_client; |
1016 { | 1019 { |
1017 base::AutoLock locked(strike_register_client_lock_); | 1020 base::AutoLock locked(strike_register_client_lock_); |
1018 | 1021 |
1019 if (strike_register_client_.get() == NULL) { | 1022 if (strike_register_client_.get() == nullptr) { |
1020 strike_register_client_.reset(new LocalStrikeRegisterClient( | 1023 strike_register_client_.reset(new LocalStrikeRegisterClient( |
1021 strike_register_max_entries_, | 1024 strike_register_max_entries_, |
1022 static_cast<uint32>(info->now.ToUNIXSeconds()), | 1025 static_cast<uint32>(info->now.ToUNIXSeconds()), |
1023 strike_register_window_secs_, | 1026 strike_register_window_secs_, |
1024 primary_orbit, | 1027 primary_orbit, |
1025 strike_register_no_startup_period_ ? | 1028 strike_register_no_startup_period_ ? |
1026 StrikeRegister::NO_STARTUP_PERIOD_NEEDED : | 1029 StrikeRegister::NO_STARTUP_PERIOD_NEEDED : |
1027 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); | 1030 StrikeRegister::DENY_REQUESTS_AT_STARTUP)); |
1028 } | 1031 } |
1029 strike_register_client = strike_register_client_.get(); | 1032 strike_register_client = strike_register_client_.get(); |
(...skipping 16 matching lines...) Expand all Loading... |
1046 base::AutoLock locked(configs_lock_); | 1049 base::AutoLock locked(configs_lock_); |
1047 out->set_tag(kSCUP); | 1050 out->set_tag(kSCUP); |
1048 out->SetStringPiece(kSCFG, primary_config_->serialized); | 1051 out->SetStringPiece(kSCFG, primary_config_->serialized); |
1049 out->SetStringPiece(kSourceAddressTokenTag, | 1052 out->SetStringPiece(kSourceAddressTokenTag, |
1050 NewSourceAddressToken(*primary_config_.get(), | 1053 NewSourceAddressToken(*primary_config_.get(), |
1051 client_ip, | 1054 client_ip, |
1052 rand, | 1055 rand, |
1053 clock->WallNow(), | 1056 clock->WallNow(), |
1054 cached_network_params)); | 1057 cached_network_params)); |
1055 | 1058 |
1056 if (proof_source_ == NULL) { | 1059 if (proof_source_ == nullptr) { |
1057 // Insecure QUIC, can send SCFG without proof. | 1060 // Insecure QUIC, can send SCFG without proof. |
1058 return true; | 1061 return true; |
1059 } | 1062 } |
1060 | 1063 |
1061 const vector<string>* certs; | 1064 const vector<string>* certs; |
1062 string signature; | 1065 string signature; |
1063 if (!proof_source_->GetProof(params.sni, primary_config_->serialized, | 1066 if (!proof_source_->GetProof(params.sni, primary_config_->serialized, |
1064 params.x509_ecdsa_supported, &certs, | 1067 params.x509_ecdsa_supported, &certs, |
1065 &signature)) { | 1068 &signature)) { |
1066 DVLOG(1) << "Server: failed to get proof."; | 1069 DVLOG(1) << "Server: failed to get proof."; |
(...skipping 17 matching lines...) Expand all Loading... |
1084 QuicCryptoNegotiatedParameters *params, | 1087 QuicCryptoNegotiatedParameters *params, |
1085 CryptoHandshakeMessage* out) const { | 1088 CryptoHandshakeMessage* out) const { |
1086 out->set_tag(kREJ); | 1089 out->set_tag(kREJ); |
1087 out->SetStringPiece(kSCFG, config.serialized); | 1090 out->SetStringPiece(kSCFG, config.serialized); |
1088 out->SetStringPiece(kSourceAddressTokenTag, | 1091 out->SetStringPiece(kSourceAddressTokenTag, |
1089 NewSourceAddressToken( | 1092 NewSourceAddressToken( |
1090 config, | 1093 config, |
1091 info.client_ip, | 1094 info.client_ip, |
1092 rand, | 1095 rand, |
1093 info.now, | 1096 info.now, |
1094 NULL)); | 1097 nullptr)); |
1095 if (replay_protection_) { | 1098 if (replay_protection_) { |
1096 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 1099 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
1097 } | 1100 } |
1098 | 1101 |
1099 if (FLAGS_send_quic_crypto_reject_reason) { | 1102 if (FLAGS_send_quic_crypto_reject_reason) { |
1100 // Send client the reject reason for debugging purposes. | 1103 // Send client the reject reason for debugging purposes. |
1101 DCHECK_LT(0u, info.reject_reasons.size()); | 1104 DCHECK_LT(0u, info.reject_reasons.size()); |
1102 out->SetVector(kRREJ, info.reject_reasons); | 1105 out->SetVector(kRREJ, info.reject_reasons); |
1103 } | 1106 } |
1104 | 1107 |
1105 // The client may have requested a certificate chain. | 1108 // The client may have requested a certificate chain. |
1106 const QuicTag* their_proof_demands; | 1109 const QuicTag* their_proof_demands; |
1107 size_t num_their_proof_demands; | 1110 size_t num_their_proof_demands; |
1108 | 1111 |
1109 if (proof_source_.get() == NULL || | 1112 if (proof_source_.get() == nullptr || |
1110 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 1113 client_hello.GetTaglist(kPDMD, &their_proof_demands, |
1111 &num_their_proof_demands) != | 1114 &num_their_proof_demands) != |
1112 QUIC_NO_ERROR) { | 1115 QUIC_NO_ERROR) { |
1113 return; | 1116 return; |
1114 } | 1117 } |
1115 | 1118 |
1116 bool x509_supported = false; | 1119 bool x509_supported = false; |
1117 for (size_t i = 0; i < num_their_proof_demands; i++) { | 1120 for (size_t i = 0; i < num_their_proof_demands; i++) { |
1118 switch (their_proof_demands[i]) { | 1121 switch (their_proof_demands[i]) { |
1119 case kX509: | 1122 case kX509: |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 | 1183 |
1181 scoped_refptr<QuicCryptoServerConfig::Config> | 1184 scoped_refptr<QuicCryptoServerConfig::Config> |
1182 QuicCryptoServerConfig::ParseConfigProtobuf( | 1185 QuicCryptoServerConfig::ParseConfigProtobuf( |
1183 QuicServerConfigProtobuf* protobuf) { | 1186 QuicServerConfigProtobuf* protobuf) { |
1184 scoped_ptr<CryptoHandshakeMessage> msg( | 1187 scoped_ptr<CryptoHandshakeMessage> msg( |
1185 CryptoFramer::ParseMessage(protobuf->config())); | 1188 CryptoFramer::ParseMessage(protobuf->config())); |
1186 | 1189 |
1187 if (msg->tag() != kSCFG) { | 1190 if (msg->tag() != kSCFG) { |
1188 LOG(WARNING) << "Server config message has tag " << msg->tag() | 1191 LOG(WARNING) << "Server config message has tag " << msg->tag() |
1189 << " expected " << kSCFG; | 1192 << " expected " << kSCFG; |
1190 return NULL; | 1193 return nullptr; |
1191 } | 1194 } |
1192 | 1195 |
1193 scoped_refptr<Config> config(new Config); | 1196 scoped_refptr<Config> config(new Config); |
1194 config->serialized = protobuf->config(); | 1197 config->serialized = protobuf->config(); |
1195 | 1198 |
1196 if (!protobuf->has_source_address_token_secret_override()) { | 1199 if (!protobuf->has_source_address_token_secret_override()) { |
1197 // Use the default boxer. | 1200 // Use the default boxer. |
1198 config->source_address_token_boxer = &default_source_address_token_boxer_; | 1201 config->source_address_token_boxer = &default_source_address_token_boxer_; |
1199 } else { | 1202 } else { |
1200 // Create override boxer instance. | 1203 // Create override boxer instance. |
1201 CryptoSecretBoxer* boxer = new CryptoSecretBoxer; | 1204 CryptoSecretBoxer* boxer = new CryptoSecretBoxer; |
1202 boxer->SetKey(DeriveSourceAddressTokenKey( | 1205 boxer->SetKey(DeriveSourceAddressTokenKey( |
1203 protobuf->source_address_token_secret_override())); | 1206 protobuf->source_address_token_secret_override())); |
1204 config->source_address_token_boxer_storage.reset(boxer); | 1207 config->source_address_token_boxer_storage.reset(boxer); |
1205 config->source_address_token_boxer = boxer; | 1208 config->source_address_token_boxer = boxer; |
1206 } | 1209 } |
1207 | 1210 |
1208 if (protobuf->has_primary_time()) { | 1211 if (protobuf->has_primary_time()) { |
1209 config->primary_time = | 1212 config->primary_time = |
1210 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1213 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
1211 } | 1214 } |
1212 | 1215 |
1213 config->priority = protobuf->priority(); | 1216 config->priority = protobuf->priority(); |
1214 | 1217 |
1215 StringPiece scid; | 1218 StringPiece scid; |
1216 if (!msg->GetStringPiece(kSCID, &scid)) { | 1219 if (!msg->GetStringPiece(kSCID, &scid)) { |
1217 LOG(WARNING) << "Server config message is missing SCID"; | 1220 LOG(WARNING) << "Server config message is missing SCID"; |
1218 return NULL; | 1221 return nullptr; |
1219 } | 1222 } |
1220 config->id = scid.as_string(); | 1223 config->id = scid.as_string(); |
1221 | 1224 |
1222 const QuicTag* aead_tags; | 1225 const QuicTag* aead_tags; |
1223 size_t aead_len; | 1226 size_t aead_len; |
1224 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | 1227 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { |
1225 LOG(WARNING) << "Server config message is missing AEAD"; | 1228 LOG(WARNING) << "Server config message is missing AEAD"; |
1226 return NULL; | 1229 return nullptr; |
1227 } | 1230 } |
1228 config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len); | 1231 config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len); |
1229 | 1232 |
1230 const QuicTag* kexs_tags; | 1233 const QuicTag* kexs_tags; |
1231 size_t kexs_len; | 1234 size_t kexs_len; |
1232 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | 1235 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { |
1233 LOG(WARNING) << "Server config message is missing KEXS"; | 1236 LOG(WARNING) << "Server config message is missing KEXS"; |
1234 return NULL; | 1237 return nullptr; |
1235 } | 1238 } |
1236 | 1239 |
1237 StringPiece orbit; | 1240 StringPiece orbit; |
1238 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1241 if (!msg->GetStringPiece(kORBT, &orbit)) { |
1239 LOG(WARNING) << "Server config message is missing ORBT"; | 1242 LOG(WARNING) << "Server config message is missing ORBT"; |
1240 return NULL; | 1243 return nullptr; |
1241 } | 1244 } |
1242 | 1245 |
1243 if (orbit.size() != kOrbitSize) { | 1246 if (orbit.size() != kOrbitSize) { |
1244 LOG(WARNING) << "Orbit value in server config is the wrong length." | 1247 LOG(WARNING) << "Orbit value in server config is the wrong length." |
1245 " Got " << orbit.size() << " want " << kOrbitSize; | 1248 " Got " << orbit.size() << " want " << kOrbitSize; |
1246 return NULL; | 1249 return nullptr; |
1247 } | 1250 } |
1248 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); | 1251 COMPILE_ASSERT(sizeof(config->orbit) == kOrbitSize, orbit_incorrect_size); |
1249 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1252 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
1250 | 1253 |
1251 { | 1254 { |
1252 StrikeRegisterClient* strike_register_client; | 1255 StrikeRegisterClient* strike_register_client; |
1253 { | 1256 { |
1254 base::AutoLock locked(strike_register_client_lock_); | 1257 base::AutoLock locked(strike_register_client_lock_); |
1255 strike_register_client = strike_register_client_.get(); | 1258 strike_register_client = strike_register_client_.get(); |
1256 } | 1259 } |
1257 | 1260 |
1258 if (strike_register_client != NULL && | 1261 if (strike_register_client != nullptr && |
1259 !strike_register_client->IsKnownOrbit(orbit)) { | 1262 !strike_register_client->IsKnownOrbit(orbit)) { |
1260 LOG(WARNING) | 1263 LOG(WARNING) |
1261 << "Rejecting server config with orbit that the strike register " | 1264 << "Rejecting server config with orbit that the strike register " |
1262 "client doesn't know about."; | 1265 "client doesn't know about."; |
1263 return NULL; | 1266 return nullptr; |
1264 } | 1267 } |
1265 } | 1268 } |
1266 | 1269 |
1267 if (kexs_len != protobuf->key_size()) { | 1270 if (kexs_len != protobuf->key_size()) { |
1268 LOG(WARNING) << "Server config has " << kexs_len | 1271 LOG(WARNING) << "Server config has " << kexs_len |
1269 << " key exchange methods configured, but " | 1272 << " key exchange methods configured, but " |
1270 << protobuf->key_size() << " private keys"; | 1273 << protobuf->key_size() << " private keys"; |
1271 return NULL; | 1274 return nullptr; |
1272 } | 1275 } |
1273 | 1276 |
1274 const QuicTag* proof_demand_tags; | 1277 const QuicTag* proof_demand_tags; |
1275 size_t num_proof_demand_tags; | 1278 size_t num_proof_demand_tags; |
1276 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == | 1279 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == |
1277 QUIC_NO_ERROR) { | 1280 QUIC_NO_ERROR) { |
1278 for (size_t i = 0; i < num_proof_demand_tags; i++) { | 1281 for (size_t i = 0; i < num_proof_demand_tags; i++) { |
1279 if (proof_demand_tags[i] == kCHID) { | 1282 if (proof_demand_tags[i] == kCHID) { |
1280 config->channel_id_enabled = true; | 1283 config->channel_id_enabled = true; |
1281 break; | 1284 break; |
(...skipping 11 matching lines...) Expand all Loading... |
1293 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); | 1296 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); |
1294 if (key.tag() == tag) { | 1297 if (key.tag() == tag) { |
1295 private_key = key.private_key(); | 1298 private_key = key.private_key(); |
1296 break; | 1299 break; |
1297 } | 1300 } |
1298 } | 1301 } |
1299 | 1302 |
1300 if (private_key.empty()) { | 1303 if (private_key.empty()) { |
1301 LOG(WARNING) << "Server config contains key exchange method without " | 1304 LOG(WARNING) << "Server config contains key exchange method without " |
1302 "corresponding private key: " << tag; | 1305 "corresponding private key: " << tag; |
1303 return NULL; | 1306 return nullptr; |
1304 } | 1307 } |
1305 | 1308 |
1306 scoped_ptr<KeyExchange> ka; | 1309 scoped_ptr<KeyExchange> ka; |
1307 switch (tag) { | 1310 switch (tag) { |
1308 case kC255: | 1311 case kC255: |
1309 ka.reset(Curve25519KeyExchange::New(private_key)); | 1312 ka.reset(Curve25519KeyExchange::New(private_key)); |
1310 if (!ka.get()) { | 1313 if (!ka.get()) { |
1311 LOG(WARNING) << "Server config contained an invalid curve25519" | 1314 LOG(WARNING) << "Server config contained an invalid curve25519" |
1312 " private key."; | 1315 " private key."; |
1313 return NULL; | 1316 return nullptr; |
1314 } | 1317 } |
1315 break; | 1318 break; |
1316 case kP256: | 1319 case kP256: |
1317 ka.reset(P256KeyExchange::New(private_key)); | 1320 ka.reset(P256KeyExchange::New(private_key)); |
1318 if (!ka.get()) { | 1321 if (!ka.get()) { |
1319 LOG(WARNING) << "Server config contained an invalid P-256" | 1322 LOG(WARNING) << "Server config contained an invalid P-256" |
1320 " private key."; | 1323 " private key."; |
1321 return NULL; | 1324 return nullptr; |
1322 } | 1325 } |
1323 break; | 1326 break; |
1324 default: | 1327 default: |
1325 LOG(WARNING) << "Server config message contains unknown key exchange " | 1328 LOG(WARNING) << "Server config message contains unknown key exchange " |
1326 "method: " << tag; | 1329 "method: " << tag; |
1327 return NULL; | 1330 return nullptr; |
1328 } | 1331 } |
1329 | 1332 |
1330 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); | 1333 for (vector<KeyExchange*>::const_iterator i = config->key_exchanges.begin(); |
1331 i != config->key_exchanges.end(); ++i) { | 1334 i != config->key_exchanges.end(); ++i) { |
1332 if ((*i)->tag() == tag) { | 1335 if ((*i)->tag() == tag) { |
1333 LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1336 LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
1334 return NULL; | 1337 return nullptr; |
1335 } | 1338 } |
1336 } | 1339 } |
1337 | 1340 |
1338 config->key_exchanges.push_back(ka.release()); | 1341 config->key_exchanges.push_back(ka.release()); |
1339 } | 1342 } |
1340 | 1343 |
1341 return config; | 1344 return config; |
1342 } | 1345 } |
1343 | 1346 |
1344 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { | 1347 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 QuicRandom* rand, | 1418 QuicRandom* rand, |
1416 QuicWallTime now, | 1419 QuicWallTime now, |
1417 const CachedNetworkParameters* cached_network_params) const { | 1420 const CachedNetworkParameters* cached_network_params) const { |
1418 IPAddressNumber ip_address = ip.address(); | 1421 IPAddressNumber ip_address = ip.address(); |
1419 if (ip.GetSockAddrFamily() == AF_INET) { | 1422 if (ip.GetSockAddrFamily() == AF_INET) { |
1420 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); | 1423 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); |
1421 } | 1424 } |
1422 SourceAddressToken source_address_token; | 1425 SourceAddressToken source_address_token; |
1423 source_address_token.set_ip(IPAddressToPackedString(ip_address)); | 1426 source_address_token.set_ip(IPAddressToPackedString(ip_address)); |
1424 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1427 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
1425 if (cached_network_params != NULL) { | 1428 if (cached_network_params != nullptr) { |
1426 source_address_token.set_cached_network_parameters(*cached_network_params); | 1429 source_address_token.set_cached_network_parameters(*cached_network_params); |
1427 } | 1430 } |
1428 | 1431 |
1429 return config.source_address_token_boxer->Box( | 1432 return config.source_address_token_boxer->Box( |
1430 rand, source_address_token.SerializeAsString()); | 1433 rand, source_address_token.SerializeAsString()); |
1431 } | 1434 } |
1432 | 1435 |
1433 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( | 1436 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( |
1434 const Config& config, | 1437 const Config& config, |
1435 StringPiece token, | 1438 StringPiece token, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 memcpy(server_nonce, plaintext.data(), 4); | 1522 memcpy(server_nonce, plaintext.data(), 4); |
1520 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 1523 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
1521 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, | 1524 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, |
1522 20); | 1525 20); |
1523 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), | 1526 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), |
1524 bad_nonce_buffer_length); | 1527 bad_nonce_buffer_length); |
1525 | 1528 |
1526 InsertStatus nonce_error; | 1529 InsertStatus nonce_error; |
1527 { | 1530 { |
1528 base::AutoLock auto_lock(server_nonce_strike_register_lock_); | 1531 base::AutoLock auto_lock(server_nonce_strike_register_lock_); |
1529 if (server_nonce_strike_register_.get() == NULL) { | 1532 if (server_nonce_strike_register_.get() == nullptr) { |
1530 server_nonce_strike_register_.reset(new StrikeRegister( | 1533 server_nonce_strike_register_.reset(new StrikeRegister( |
1531 server_nonce_strike_register_max_entries_, | 1534 server_nonce_strike_register_max_entries_, |
1532 static_cast<uint32>(now.ToUNIXSeconds()), | 1535 static_cast<uint32>(now.ToUNIXSeconds()), |
1533 server_nonce_strike_register_window_secs_, server_nonce_orbit_, | 1536 server_nonce_strike_register_window_secs_, server_nonce_orbit_, |
1534 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); | 1537 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); |
1535 } | 1538 } |
1536 nonce_error = server_nonce_strike_register_->Insert( | 1539 nonce_error = server_nonce_strike_register_->Insert( |
1537 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1540 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
1538 } | 1541 } |
1539 | 1542 |
(...skipping 14 matching lines...) Expand all Loading... |
1554 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error; | 1557 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error; |
1555 return SERVER_NONCE_NOT_UNIQUE_FAILURE; | 1558 return SERVER_NONCE_NOT_UNIQUE_FAILURE; |
1556 } | 1559 } |
1557 } | 1560 } |
1558 | 1561 |
1559 QuicCryptoServerConfig::Config::Config() | 1562 QuicCryptoServerConfig::Config::Config() |
1560 : channel_id_enabled(false), | 1563 : channel_id_enabled(false), |
1561 is_primary(false), | 1564 is_primary(false), |
1562 primary_time(QuicWallTime::Zero()), | 1565 primary_time(QuicWallTime::Zero()), |
1563 priority(0), | 1566 priority(0), |
1564 source_address_token_boxer(NULL) {} | 1567 source_address_token_boxer(nullptr) {} |
1565 | 1568 |
1566 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1569 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
1567 | 1570 |
1568 } // namespace net | 1571 } // namespace net |
OLD | NEW |