| 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/core/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 return nullptr; | 304 return nullptr; |
| 305 } | 305 } |
| 306 | 306 |
| 307 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); | 307 scoped_refptr<Config> config(ParseConfigProtobuf(protobuf)); |
| 308 if (!config.get()) { | 308 if (!config.get()) { |
| 309 LOG(WARNING) << "Failed to parse server config message"; | 309 LOG(WARNING) << "Failed to parse server config message"; |
| 310 return nullptr; | 310 return nullptr; |
| 311 } | 311 } |
| 312 | 312 |
| 313 { | 313 { |
| 314 base::AutoLock locked(configs_lock_); | 314 QuicWriterMutexLock locked(&configs_lock_); |
| 315 if (configs_.find(config->id) != configs_.end()) { | 315 if (configs_.find(config->id) != configs_.end()) { |
| 316 LOG(WARNING) << "Failed to add config because another with the same " | 316 LOG(WARNING) << "Failed to add config because another with the same " |
| 317 "server config id already exists: " | 317 "server config id already exists: " |
| 318 << QuicUtils::HexEncode(config->id); | 318 << QuicUtils::HexEncode(config->id); |
| 319 return nullptr; | 319 return nullptr; |
| 320 } | 320 } |
| 321 | 321 |
| 322 configs_[config->id] = config; | 322 configs_[config->id] = config; |
| 323 SelectNewPrimaryConfig(now); | 323 SelectNewPrimaryConfig(now); |
| 324 DCHECK(primary_config_.get()); | 324 DCHECK(primary_config_.get()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 354 if (parsed_configs.empty()) { | 354 if (parsed_configs.empty()) { |
| 355 LOG(WARNING) << "New config list is empty."; | 355 LOG(WARNING) << "New config list is empty."; |
| 356 ok = false; | 356 ok = false; |
| 357 } | 357 } |
| 358 | 358 |
| 359 if (!ok) { | 359 if (!ok) { |
| 360 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; | 360 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; |
| 361 } else { | 361 } else { |
| 362 VLOG(1) << "Updating configs:"; | 362 VLOG(1) << "Updating configs:"; |
| 363 | 363 |
| 364 base::AutoLock locked(configs_lock_); | 364 QuicWriterMutexLock locked(&configs_lock_); |
| 365 ConfigMap new_configs; | 365 ConfigMap new_configs; |
| 366 | 366 |
| 367 for (std::vector<scoped_refptr<Config>>::const_iterator i = | 367 for (std::vector<scoped_refptr<Config>>::const_iterator i = |
| 368 parsed_configs.begin(); | 368 parsed_configs.begin(); |
| 369 i != parsed_configs.end(); ++i) { | 369 i != parsed_configs.end(); ++i) { |
| 370 scoped_refptr<Config> config = *i; | 370 scoped_refptr<Config> config = *i; |
| 371 | 371 |
| 372 ConfigMap::iterator it = configs_.find(config->id); | 372 ConfigMap::iterator it = configs_.find(config->id); |
| 373 if (it != configs_.end()) { | 373 if (it != configs_.end()) { |
| 374 VLOG(1) << "Keeping scid: " << QuicUtils::HexEncode(config->id) | 374 VLOG(1) << "Keeping scid: " << QuicUtils::HexEncode(config->id) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 402 | 402 |
| 403 return ok; | 403 return ok; |
| 404 } | 404 } |
| 405 | 405 |
| 406 void QuicCryptoServerConfig::SetSourceAddressTokenKeys( | 406 void QuicCryptoServerConfig::SetSourceAddressTokenKeys( |
| 407 const std::vector<string>& keys) { | 407 const std::vector<string>& keys) { |
| 408 source_address_token_boxer_.SetKeys(keys); | 408 source_address_token_boxer_.SetKeys(keys); |
| 409 } | 409 } |
| 410 | 410 |
| 411 void QuicCryptoServerConfig::GetConfigIds(std::vector<string>* scids) const { | 411 void QuicCryptoServerConfig::GetConfigIds(std::vector<string>* scids) const { |
| 412 base::AutoLock locked(configs_lock_); | 412 QuicReaderMutexLock locked(&configs_lock_); |
| 413 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); | 413 for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
| 414 ++it) { | 414 ++it) { |
| 415 scids->push_back(it->first); | 415 scids->push_back(it->first); |
| 416 } | 416 } |
| 417 } | 417 } |
| 418 | 418 |
| 419 void QuicCryptoServerConfig::ValidateClientHello( | 419 void QuicCryptoServerConfig::ValidateClientHello( |
| 420 const CryptoHandshakeMessage& client_hello, | 420 const CryptoHandshakeMessage& client_hello, |
| 421 const QuicIpAddress& client_ip, | 421 const QuicIpAddress& client_ip, |
| 422 const QuicSocketAddress& server_address, | 422 const QuicSocketAddress& server_address, |
| 423 QuicVersion version, | 423 QuicVersion version, |
| 424 const QuicClock* clock, | 424 const QuicClock* clock, |
| 425 scoped_refptr<QuicSignedServerConfig> signed_config, | 425 scoped_refptr<QuicSignedServerConfig> signed_config, |
| 426 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { | 426 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
| 427 const QuicWallTime now(clock->WallNow()); | 427 const QuicWallTime now(clock->WallNow()); |
| 428 | 428 |
| 429 scoped_refptr<ValidateClientHelloResultCallback::Result> result( | 429 scoped_refptr<ValidateClientHelloResultCallback::Result> result( |
| 430 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, | 430 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, |
| 431 now)); | 431 now)); |
| 432 | 432 |
| 433 StringPiece requested_scid; | 433 StringPiece requested_scid; |
| 434 client_hello.GetStringPiece(kSCID, &requested_scid); | 434 client_hello.GetStringPiece(kSCID, &requested_scid); |
| 435 | 435 |
| 436 scoped_refptr<Config> requested_config; | 436 scoped_refptr<Config> requested_config; |
| 437 scoped_refptr<Config> primary_config; | 437 scoped_refptr<Config> primary_config; |
| 438 { | 438 { |
| 439 base::AutoLock locked(configs_lock_); | 439 QuicReaderMutexLock locked(&configs_lock_); |
| 440 | 440 |
| 441 if (!primary_config_.get()) { | 441 if (!primary_config_.get()) { |
| 442 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; | 442 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; |
| 443 result->error_details = "No configurations loaded"; | 443 result->error_details = "No configurations loaded"; |
| 444 } else { | 444 } else { |
| 445 if (!next_config_promotion_time_.IsZero() && | 445 if (!next_config_promotion_time_.IsZero() && |
| 446 next_config_promotion_time_.IsAfter(now)) { | 446 next_config_promotion_time_.IsAfter(now)) { |
| 447 configs_lock_.ReaderUnlock(); |
| 448 configs_lock_.WriterLock(); |
| 447 SelectNewPrimaryConfig(now); | 449 SelectNewPrimaryConfig(now); |
| 448 DCHECK(primary_config_.get()); | 450 DCHECK(primary_config_.get()); |
| 449 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 451 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 452 configs_lock_.WriterUnlock(); |
| 453 configs_lock_.ReaderLock(); |
| 450 } | 454 } |
| 451 } | 455 } |
| 452 | 456 |
| 453 requested_config = GetConfigWithScid(requested_scid); | 457 requested_config = GetConfigWithScid(requested_scid); |
| 454 primary_config = primary_config_; | 458 primary_config = primary_config_; |
| 455 signed_config->config = primary_config_; | 459 signed_config->config = primary_config_; |
| 456 } | 460 } |
| 457 | 461 |
| 458 if (result->error_code == QUIC_NO_ERROR) { | 462 if (result->error_code == QUIC_NO_ERROR) { |
| 459 // QUIC requires a new proof for each CHLO so clear any existing proof. | 463 // QUIC requires a new proof for each CHLO so clear any existing proof. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 } | 626 } |
| 623 | 627 |
| 624 StringPiece requested_scid; | 628 StringPiece requested_scid; |
| 625 client_hello.GetStringPiece(kSCID, &requested_scid); | 629 client_hello.GetStringPiece(kSCID, &requested_scid); |
| 626 const QuicWallTime now(clock->WallNow()); | 630 const QuicWallTime now(clock->WallNow()); |
| 627 | 631 |
| 628 scoped_refptr<Config> requested_config; | 632 scoped_refptr<Config> requested_config; |
| 629 scoped_refptr<Config> primary_config; | 633 scoped_refptr<Config> primary_config; |
| 630 bool no_primary_config = false; | 634 bool no_primary_config = false; |
| 631 { | 635 { |
| 632 base::AutoLock locked(configs_lock_); | 636 QuicReaderMutexLock locked(&configs_lock_); |
| 633 | 637 |
| 634 if (!primary_config_) { | 638 if (!primary_config_) { |
| 635 no_primary_config = true; | 639 no_primary_config = true; |
| 636 } else { | 640 } else { |
| 637 if (!next_config_promotion_time_.IsZero() && | 641 if (!next_config_promotion_time_.IsZero() && |
| 638 next_config_promotion_time_.IsAfter(now)) { | 642 next_config_promotion_time_.IsAfter(now)) { |
| 643 configs_lock_.ReaderUnlock(); |
| 644 configs_lock_.WriterLock(); |
| 639 SelectNewPrimaryConfig(now); | 645 SelectNewPrimaryConfig(now); |
| 640 DCHECK(primary_config_.get()); | 646 DCHECK(primary_config_.get()); |
| 641 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 647 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 648 configs_lock_.WriterUnlock(); |
| 649 configs_lock_.ReaderLock(); |
| 642 } | 650 } |
| 643 | 651 |
| 644 // Use the config that the client requested in order to do key-agreement. | 652 // Use the config that the client requested in order to do key-agreement. |
| 645 // Otherwise give it a copy of |primary_config_| to use. | 653 // Otherwise give it a copy of |primary_config_| to use. |
| 646 primary_config = signed_config->config; | 654 primary_config = signed_config->config; |
| 647 requested_config = GetConfigWithScid(requested_scid); | 655 requested_config = GetConfigWithScid(requested_scid); |
| 648 } | 656 } |
| 649 } | 657 } |
| 650 if (no_primary_config) { | 658 if (no_primary_config) { |
| 651 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded"); | 659 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded"); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 QuicSocketAddressCoder address_coder(client_address); | 996 QuicSocketAddressCoder address_coder(client_address); |
| 989 out->SetStringPiece(kCADR, address_coder.Encode()); | 997 out->SetStringPiece(kCADR, address_coder.Encode()); |
| 990 out->SetStringPiece(kPUBS, forward_secure_public_value); | 998 out->SetStringPiece(kPUBS, forward_secure_public_value); |
| 991 | 999 |
| 992 helper.Succeed(std::move(out), std::move(out_diversification_nonce), | 1000 helper.Succeed(std::move(out), std::move(out_diversification_nonce), |
| 993 std::move(proof_source_details)); | 1001 std::move(proof_source_details)); |
| 994 } | 1002 } |
| 995 | 1003 |
| 996 scoped_refptr<QuicCryptoServerConfig::Config> | 1004 scoped_refptr<QuicCryptoServerConfig::Config> |
| 997 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | 1005 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { |
| 998 // In Chromium, we will dead lock if the lock is held by the current thread. | 1006 configs_lock_.AssertReaderHeld(); |
| 999 // Chromium doesn't have AssertReaderHeld API call. | |
| 1000 // configs_lock_.AssertReaderHeld(); | |
| 1001 | 1007 |
| 1002 if (!requested_scid.empty()) { | 1008 if (!requested_scid.empty()) { |
| 1003 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | 1009 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); |
| 1004 if (it != configs_.end()) { | 1010 if (it != configs_.end()) { |
| 1005 // We'll use the config that the client requested in order to do | 1011 // We'll use the config that the client requested in order to do |
| 1006 // key-agreement. | 1012 // key-agreement. |
| 1007 return scoped_refptr<Config>(it->second); | 1013 return scoped_refptr<Config>(it->second); |
| 1008 } | 1014 } |
| 1009 } | 1015 } |
| 1010 | 1016 |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 QuicCompressedCertsCache* compressed_certs_cache, | 1345 QuicCompressedCertsCache* compressed_certs_cache, |
| 1340 const QuicCryptoNegotiatedParameters& params, | 1346 const QuicCryptoNegotiatedParameters& params, |
| 1341 const CachedNetworkParameters* cached_network_params, | 1347 const CachedNetworkParameters* cached_network_params, |
| 1342 const QuicTagVector& connection_options, | 1348 const QuicTagVector& connection_options, |
| 1343 CryptoHandshakeMessage* out) const { | 1349 CryptoHandshakeMessage* out) const { |
| 1344 string serialized; | 1350 string serialized; |
| 1345 string source_address_token; | 1351 string source_address_token; |
| 1346 QuicWallTime expiry_time = QuicWallTime::Zero(); | 1352 QuicWallTime expiry_time = QuicWallTime::Zero(); |
| 1347 const CommonCertSets* common_cert_sets; | 1353 const CommonCertSets* common_cert_sets; |
| 1348 { | 1354 { |
| 1349 base::AutoLock locked(configs_lock_); | 1355 QuicReaderMutexLock locked(&configs_lock_); |
| 1350 serialized = primary_config_->serialized; | 1356 serialized = primary_config_->serialized; |
| 1351 common_cert_sets = primary_config_->common_cert_sets; | 1357 common_cert_sets = primary_config_->common_cert_sets; |
| 1352 expiry_time = primary_config_->expiry_time; | 1358 expiry_time = primary_config_->expiry_time; |
| 1353 source_address_token = NewSourceAddressToken( | 1359 source_address_token = NewSourceAddressToken( |
| 1354 *primary_config_, previous_source_address_tokens, client_ip, rand, | 1360 *primary_config_, previous_source_address_tokens, client_ip, rand, |
| 1355 clock->WallNow(), cached_network_params); | 1361 clock->WallNow(), cached_network_params); |
| 1356 } | 1362 } |
| 1357 | 1363 |
| 1358 out->set_tag(kSCUP); | 1364 out->set_tag(kSCUP); |
| 1359 out->SetStringPiece(kSCFG, serialized); | 1365 out->SetStringPiece(kSCFG, serialized); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 QuicRandom* rand, | 1402 QuicRandom* rand, |
| 1397 QuicCompressedCertsCache* compressed_certs_cache, | 1403 QuicCompressedCertsCache* compressed_certs_cache, |
| 1398 const QuicCryptoNegotiatedParameters& params, | 1404 const QuicCryptoNegotiatedParameters& params, |
| 1399 const CachedNetworkParameters* cached_network_params, | 1405 const CachedNetworkParameters* cached_network_params, |
| 1400 const QuicTagVector& connection_options, | 1406 const QuicTagVector& connection_options, |
| 1401 std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { | 1407 std::unique_ptr<BuildServerConfigUpdateMessageResultCallback> cb) const { |
| 1402 string serialized; | 1408 string serialized; |
| 1403 string source_address_token; | 1409 string source_address_token; |
| 1404 const CommonCertSets* common_cert_sets; | 1410 const CommonCertSets* common_cert_sets; |
| 1405 { | 1411 { |
| 1406 base::AutoLock locked(configs_lock_); | 1412 QuicReaderMutexLock locked(&configs_lock_); |
| 1407 serialized = primary_config_->serialized; | 1413 serialized = primary_config_->serialized; |
| 1408 common_cert_sets = primary_config_->common_cert_sets; | 1414 common_cert_sets = primary_config_->common_cert_sets; |
| 1409 source_address_token = NewSourceAddressToken( | 1415 source_address_token = NewSourceAddressToken( |
| 1410 *primary_config_, previous_source_address_tokens, client_ip, rand, | 1416 *primary_config_, previous_source_address_tokens, client_ip, rand, |
| 1411 clock->WallNow(), cached_network_params); | 1417 clock->WallNow(), cached_network_params); |
| 1412 } | 1418 } |
| 1413 | 1419 |
| 1414 CryptoHandshakeMessage message; | 1420 CryptoHandshakeMessage message; |
| 1415 message.set_tag(kSCUP); | 1421 message.set_tag(kSCUP); |
| 1416 message.SetStringPiece(kSCFG, serialized); | 1422 message.SetStringPiece(kSCFG, serialized); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1808 uint32_t lifetime_secs) { | 1814 uint32_t lifetime_secs) { |
| 1809 source_address_token_lifetime_secs_ = lifetime_secs; | 1815 source_address_token_lifetime_secs_ = lifetime_secs; |
| 1810 } | 1816 } |
| 1811 | 1817 |
| 1812 void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) { | 1818 void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) { |
| 1813 enable_serving_sct_ = enable_serving_sct; | 1819 enable_serving_sct_ = enable_serving_sct; |
| 1814 } | 1820 } |
| 1815 | 1821 |
| 1816 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( | 1822 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( |
| 1817 std::unique_ptr<PrimaryConfigChangedCallback> cb) { | 1823 std::unique_ptr<PrimaryConfigChangedCallback> cb) { |
| 1818 base::AutoLock locked(configs_lock_); | 1824 QuicWriterMutexLock locked(&configs_lock_); |
| 1819 primary_config_changed_cb_ = std::move(cb); | 1825 primary_config_changed_cb_ = std::move(cb); |
| 1820 } | 1826 } |
| 1821 | 1827 |
| 1822 string QuicCryptoServerConfig::NewSourceAddressToken( | 1828 string QuicCryptoServerConfig::NewSourceAddressToken( |
| 1823 const Config& config, | 1829 const Config& config, |
| 1824 const SourceAddressTokens& previous_tokens, | 1830 const SourceAddressTokens& previous_tokens, |
| 1825 const QuicIpAddress& ip, | 1831 const QuicIpAddress& ip, |
| 1826 QuicRandom* rand, | 1832 QuicRandom* rand, |
| 1827 QuicWallTime now, | 1833 QuicWallTime now, |
| 1828 const CachedNetworkParameters* cached_network_params) const { | 1834 const CachedNetworkParameters* cached_network_params) const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1851 } | 1857 } |
| 1852 | 1858 |
| 1853 *(source_address_tokens.add_tokens()) = token; | 1859 *(source_address_tokens.add_tokens()) = token; |
| 1854 } | 1860 } |
| 1855 | 1861 |
| 1856 return config.source_address_token_boxer->Box( | 1862 return config.source_address_token_boxer->Box( |
| 1857 rand, source_address_tokens.SerializeAsString()); | 1863 rand, source_address_tokens.SerializeAsString()); |
| 1858 } | 1864 } |
| 1859 | 1865 |
| 1860 int QuicCryptoServerConfig::NumberOfConfigs() const { | 1866 int QuicCryptoServerConfig::NumberOfConfigs() const { |
| 1861 base::AutoLock locked(configs_lock_); | 1867 QuicReaderMutexLock locked(&configs_lock_); |
| 1862 return configs_.size(); | 1868 return configs_.size(); |
| 1863 } | 1869 } |
| 1864 | 1870 |
| 1865 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( | 1871 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( |
| 1866 const Config& config, | 1872 const Config& config, |
| 1867 StringPiece token, | 1873 StringPiece token, |
| 1868 SourceAddressTokens* tokens) const { | 1874 SourceAddressTokens* tokens) const { |
| 1869 string storage; | 1875 string storage; |
| 1870 StringPiece plaintext; | 1876 StringPiece plaintext; |
| 1871 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { | 1877 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 priority(0), | 2010 priority(0), |
| 2005 source_address_token_boxer(nullptr) {} | 2011 source_address_token_boxer(nullptr) {} |
| 2006 | 2012 |
| 2007 QuicCryptoServerConfig::Config::~Config() { | 2013 QuicCryptoServerConfig::Config::~Config() { |
| 2008 } | 2014 } |
| 2009 | 2015 |
| 2010 QuicSignedServerConfig::QuicSignedServerConfig() {} | 2016 QuicSignedServerConfig::QuicSignedServerConfig() {} |
| 2011 QuicSignedServerConfig::~QuicSignedServerConfig() {} | 2017 QuicSignedServerConfig::~QuicSignedServerConfig() {} |
| 2012 | 2018 |
| 2013 } // namespace net | 2019 } // namespace net |
| OLD | NEW |