| 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 18 matching lines...) Expand all Loading... |
| 29 #include "net/quic/core/crypto/quic_decrypter.h" | 29 #include "net/quic/core/crypto/quic_decrypter.h" |
| 30 #include "net/quic/core/crypto/quic_encrypter.h" | 30 #include "net/quic/core/crypto/quic_encrypter.h" |
| 31 #include "net/quic/core/crypto/quic_random.h" | 31 #include "net/quic/core/crypto/quic_random.h" |
| 32 #include "net/quic/core/proto/source_address_token.pb.h" | 32 #include "net/quic/core/proto/source_address_token.pb.h" |
| 33 #include "net/quic/core/quic_flags.h" | 33 #include "net/quic/core/quic_flags.h" |
| 34 #include "net/quic/core/quic_packets.h" | 34 #include "net/quic/core/quic_packets.h" |
| 35 #include "net/quic/core/quic_socket_address_coder.h" | 35 #include "net/quic/core/quic_socket_address_coder.h" |
| 36 #include "net/quic/core/quic_utils.h" | 36 #include "net/quic/core/quic_utils.h" |
| 37 #include "net/quic/platform/api/quic_bug_tracker.h" | 37 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 38 #include "net/quic/platform/api/quic_clock.h" | 38 #include "net/quic/platform/api/quic_clock.h" |
| 39 #include "net/quic/platform/api/quic_logging.h" | |
| 40 #include "net/quic/platform/api/quic_reference_counted.h" | 39 #include "net/quic/platform/api/quic_reference_counted.h" |
| 41 #include "net/quic/platform/api/quic_text_utils.h" | 40 #include "net/quic/platform/api/quic_text_utils.h" |
| 42 | 41 |
| 43 using base::StringPiece; | 42 using base::StringPiece; |
| 44 using crypto::SecureHash; | 43 using crypto::SecureHash; |
| 45 using std::string; | 44 using std::string; |
| 46 | 45 |
| 47 namespace net { | 46 namespace net { |
| 48 | 47 |
| 49 namespace { | 48 namespace { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 return config; | 293 return config; |
| 295 } | 294 } |
| 296 | 295 |
| 297 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( | 296 CryptoHandshakeMessage* QuicCryptoServerConfig::AddConfig( |
| 298 std::unique_ptr<QuicServerConfigProtobuf> protobuf, | 297 std::unique_ptr<QuicServerConfigProtobuf> protobuf, |
| 299 const QuicWallTime now) { | 298 const QuicWallTime now) { |
| 300 std::unique_ptr<CryptoHandshakeMessage> msg( | 299 std::unique_ptr<CryptoHandshakeMessage> msg( |
| 301 CryptoFramer::ParseMessage(protobuf->config())); | 300 CryptoFramer::ParseMessage(protobuf->config())); |
| 302 | 301 |
| 303 if (!msg.get()) { | 302 if (!msg.get()) { |
| 304 QUIC_LOG(WARNING) << "Failed to parse server config message"; | 303 LOG(WARNING) << "Failed to parse server config message"; |
| 305 return nullptr; | 304 return nullptr; |
| 306 } | 305 } |
| 307 | 306 |
| 308 QuicReferenceCountedPointer<Config> config(ParseConfigProtobuf(protobuf)); | 307 QuicReferenceCountedPointer<Config> config(ParseConfigProtobuf(protobuf)); |
| 309 if (!config.get()) { | 308 if (!config.get()) { |
| 310 QUIC_LOG(WARNING) << "Failed to parse server config message"; | 309 LOG(WARNING) << "Failed to parse server config message"; |
| 311 return nullptr; | 310 return nullptr; |
| 312 } | 311 } |
| 313 | 312 |
| 314 { | 313 { |
| 315 QuicWriterMutexLock locked(&configs_lock_); | 314 QuicWriterMutexLock locked(&configs_lock_); |
| 316 if (configs_.find(config->id) != configs_.end()) { | 315 if (configs_.find(config->id) != configs_.end()) { |
| 317 QUIC_LOG(WARNING) << "Failed to add config because another with the same " | 316 LOG(WARNING) << "Failed to add config because another with the same " |
| 318 "server config id already exists: " | 317 "server config id already exists: " |
| 319 << QuicTextUtils::HexEncode(config->id); | 318 << QuicTextUtils::HexEncode(config->id); |
| 320 return nullptr; | 319 return nullptr; |
| 321 } | 320 } |
| 322 | 321 |
| 323 configs_[config->id] = config; | 322 configs_[config->id] = config; |
| 324 SelectNewPrimaryConfig(now); | 323 SelectNewPrimaryConfig(now); |
| 325 DCHECK(primary_config_.get()); | 324 DCHECK(primary_config_.get()); |
| 326 DCHECK_EQ(configs_.find(primary_config_->id)->second.get(), | 325 DCHECK_EQ(configs_.find(primary_config_->id)->second.get(), |
| 327 primary_config_.get()); | 326 primary_config_.get()); |
| 328 } | 327 } |
| 329 | 328 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 347 QuicReferenceCountedPointer<Config> config(ParseConfigProtobuf(protobuf)); | 346 QuicReferenceCountedPointer<Config> config(ParseConfigProtobuf(protobuf)); |
| 348 if (!config) { | 347 if (!config) { |
| 349 ok = false; | 348 ok = false; |
| 350 break; | 349 break; |
| 351 } | 350 } |
| 352 | 351 |
| 353 parsed_configs.push_back(config); | 352 parsed_configs.push_back(config); |
| 354 } | 353 } |
| 355 | 354 |
| 356 if (parsed_configs.empty()) { | 355 if (parsed_configs.empty()) { |
| 357 QUIC_LOG(WARNING) << "New config list is empty."; | 356 LOG(WARNING) << "New config list is empty."; |
| 358 ok = false; | 357 ok = false; |
| 359 } | 358 } |
| 360 | 359 |
| 361 if (!ok) { | 360 if (!ok) { |
| 362 QUIC_LOG(WARNING) << "Rejecting QUIC configs because of above errors"; | 361 LOG(WARNING) << "Rejecting QUIC configs because of above errors"; |
| 363 } else { | 362 } else { |
| 364 QUIC_LOG(INFO) << "Updating configs:"; | 363 VLOG(1) << "Updating configs:"; |
| 365 | 364 |
| 366 QuicWriterMutexLock locked(&configs_lock_); | 365 QuicWriterMutexLock locked(&configs_lock_); |
| 367 ConfigMap new_configs; | 366 ConfigMap new_configs; |
| 368 | 367 |
| 369 for (std::vector<QuicReferenceCountedPointer<Config>>::const_iterator i = | 368 for (std::vector<QuicReferenceCountedPointer<Config>>::const_iterator i = |
| 370 parsed_configs.begin(); | 369 parsed_configs.begin(); |
| 371 i != parsed_configs.end(); ++i) { | 370 i != parsed_configs.end(); ++i) { |
| 372 QuicReferenceCountedPointer<Config> config = *i; | 371 QuicReferenceCountedPointer<Config> config = *i; |
| 373 | 372 |
| 374 ConfigMap::iterator it = configs_.find(config->id); | 373 ConfigMap::iterator it = configs_.find(config->id); |
| 375 if (it != configs_.end()) { | 374 if (it != configs_.end()) { |
| 376 QUIC_LOG(INFO) << "Keeping scid: " | 375 VLOG(1) << "Keeping scid: " << QuicTextUtils::HexEncode(config->id) |
| 377 << QuicTextUtils::HexEncode(config->id) << " orbit: " | 376 << " orbit: " |
| 378 << QuicTextUtils::HexEncode( | 377 << QuicTextUtils::HexEncode( |
| 379 reinterpret_cast<const char*>(config->orbit), | 378 reinterpret_cast<const char*>(config->orbit), kOrbitSize) |
| 380 kOrbitSize) | 379 << " new primary_time " << config->primary_time.ToUNIXSeconds() |
| 381 << " new primary_time " | 380 << " old primary_time " |
| 382 << config->primary_time.ToUNIXSeconds() | 381 << it->second->primary_time.ToUNIXSeconds() << " new priority " |
| 383 << " old primary_time " | 382 << config->priority << " old priority " << it->second->priority; |
| 384 << it->second->primary_time.ToUNIXSeconds() | |
| 385 << " new priority " << config->priority | |
| 386 << " old priority " << it->second->priority; | |
| 387 // Update primary_time and priority. | 383 // Update primary_time and priority. |
| 388 it->second->primary_time = config->primary_time; | 384 it->second->primary_time = config->primary_time; |
| 389 it->second->priority = config->priority; | 385 it->second->priority = config->priority; |
| 390 new_configs.insert(*it); | 386 new_configs.insert(*it); |
| 391 } else { | 387 } else { |
| 392 QUIC_LOG(INFO) << "Adding scid: " | 388 VLOG(1) << "Adding scid: " << QuicTextUtils::HexEncode(config->id) |
| 393 << QuicTextUtils::HexEncode(config->id) << " orbit: " | 389 << " orbit: " |
| 394 << QuicTextUtils::HexEncode( | 390 << QuicTextUtils::HexEncode( |
| 395 reinterpret_cast<const char*>(config->orbit), | 391 reinterpret_cast<const char*>(config->orbit), kOrbitSize) |
| 396 kOrbitSize) | 392 << " primary_time " << config->primary_time.ToUNIXSeconds() |
| 397 << " primary_time " | 393 << " priority " << config->priority; |
| 398 << config->primary_time.ToUNIXSeconds() << " priority " | |
| 399 << config->priority; | |
| 400 new_configs.insert(std::make_pair(config->id, config)); | 394 new_configs.insert(std::make_pair(config->id, config)); |
| 401 } | 395 } |
| 402 } | 396 } |
| 403 | 397 |
| 404 configs_.swap(new_configs); | 398 configs_.swap(new_configs); |
| 405 SelectNewPrimaryConfig(now); | 399 SelectNewPrimaryConfig(now); |
| 406 DCHECK(primary_config_.get()); | 400 DCHECK(primary_config_.get()); |
| 407 DCHECK_EQ(configs_.find(primary_config_->id)->second.get(), | 401 DCHECK_EQ(configs_.find(primary_config_->id)->second.get(), |
| 408 primary_config_.get()); | 402 primary_config_.get()); |
| 409 } | 403 } |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 } | 1089 } |
| 1096 } else { | 1090 } else { |
| 1097 next_config_promotion_time_ = config->primary_time; | 1091 next_config_promotion_time_ = config->primary_time; |
| 1098 } | 1092 } |
| 1099 | 1093 |
| 1100 if (primary_config_) { | 1094 if (primary_config_) { |
| 1101 primary_config_->is_primary = false; | 1095 primary_config_->is_primary = false; |
| 1102 } | 1096 } |
| 1103 primary_config_ = new_primary; | 1097 primary_config_ = new_primary; |
| 1104 new_primary->is_primary = true; | 1098 new_primary->is_primary = true; |
| 1105 QUIC_DLOG(INFO) << "New primary config. orbit: " | 1099 DVLOG(1) << "New primary config. orbit: " |
| 1106 << QuicTextUtils::HexEncode(reinterpret_cast<const char*>( | 1100 << QuicTextUtils::HexEncode( |
| 1107 primary_config_->orbit), | 1101 reinterpret_cast<const char*>(primary_config_->orbit), |
| 1108 kOrbitSize); | 1102 kOrbitSize); |
| 1109 if (primary_config_changed_cb_.get() != nullptr) { | 1103 if (primary_config_changed_cb_.get() != nullptr) { |
| 1110 primary_config_changed_cb_->Run(primary_config_->id); | 1104 primary_config_changed_cb_->Run(primary_config_->id); |
| 1111 } | 1105 } |
| 1112 | 1106 |
| 1113 return; | 1107 return; |
| 1114 } | 1108 } |
| 1115 | 1109 |
| 1116 // All config's primary times are in the past. We should make the most recent | 1110 // All config's primary times are in the past. We should make the most recent |
| 1117 // and highest priority candidate primary. | 1111 // and highest priority candidate primary. |
| 1118 QuicReferenceCountedPointer<Config> new_primary = best_candidate; | 1112 QuicReferenceCountedPointer<Config> new_primary = best_candidate; |
| 1119 if (primary_config_) { | 1113 if (primary_config_) { |
| 1120 primary_config_->is_primary = false; | 1114 primary_config_->is_primary = false; |
| 1121 } | 1115 } |
| 1122 primary_config_ = new_primary; | 1116 primary_config_ = new_primary; |
| 1123 new_primary->is_primary = true; | 1117 new_primary->is_primary = true; |
| 1124 QUIC_DLOG(INFO) << "New primary config. orbit: " | 1118 DVLOG(1) << "New primary config. orbit: " |
| 1125 << QuicTextUtils::HexEncode( | 1119 << QuicTextUtils::HexEncode( |
| 1126 reinterpret_cast<const char*>(primary_config_->orbit), | 1120 reinterpret_cast<const char*>(primary_config_->orbit), |
| 1127 kOrbitSize) | 1121 kOrbitSize) |
| 1128 << " scid: " << QuicTextUtils::HexEncode(primary_config_->id); | 1122 << " scid: " << QuicTextUtils::HexEncode(primary_config_->id); |
| 1129 next_config_promotion_time_ = QuicWallTime::Zero(); | 1123 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 1130 if (primary_config_changed_cb_.get() != nullptr) { | 1124 if (primary_config_changed_cb_.get() != nullptr) { |
| 1131 primary_config_changed_cb_->Run(primary_config_->id); | 1125 primary_config_changed_cb_->Run(primary_config_->id); |
| 1132 } | 1126 } |
| 1133 } | 1127 } |
| 1134 | 1128 |
| 1135 class QuicCryptoServerConfig::EvaluateClientHelloCallback | 1129 class QuicCryptoServerConfig::EvaluateClientHelloCallback |
| 1136 : public ProofSource::Callback { | 1130 : public ProofSource::Callback { |
| 1137 public: | 1131 public: |
| 1138 EvaluateClientHelloCallback( | 1132 EvaluateClientHelloCallback( |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 | 1328 |
| 1335 if (signed_config->chain != nullptr && | 1329 if (signed_config->chain != nullptr && |
| 1336 !ValidateExpectedLeafCertificate(client_hello, | 1330 !ValidateExpectedLeafCertificate(client_hello, |
| 1337 signed_config->chain->certs)) { | 1331 signed_config->chain->certs)) { |
| 1338 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); | 1332 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); |
| 1339 } | 1333 } |
| 1340 | 1334 |
| 1341 if (info->client_nonce.size() != kNonceSize) { | 1335 if (info->client_nonce.size() != kNonceSize) { |
| 1342 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); | 1336 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); |
| 1343 // Invalid client nonce. | 1337 // Invalid client nonce. |
| 1344 QUIC_LOG_FIRST_N(ERROR, 2) << "Invalid client nonce: " | 1338 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); |
| 1345 << client_hello.DebugString(); | 1339 DVLOG(1) << "Invalid client nonce."; |
| 1346 QUIC_DLOG(INFO) << "Invalid client nonce."; | |
| 1347 } | 1340 } |
| 1348 | 1341 |
| 1349 // Server nonce is optional, and used for key derivation if present. | 1342 // Server nonce is optional, and used for key derivation if present. |
| 1350 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); | 1343 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
| 1351 | 1344 |
| 1352 QUIC_DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; | 1345 DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; |
| 1353 // If the server nonce is empty and we're requiring handshake confirmation | 1346 // If the server nonce is empty and we're requiring handshake confirmation |
| 1354 // for DoS reasons then we must reject the CHLO. | 1347 // for DoS reasons then we must reject the CHLO. |
| 1355 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && | 1348 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && |
| 1356 info->server_nonce.empty()) { | 1349 info->server_nonce.empty()) { |
| 1357 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); | 1350 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
| 1358 } | 1351 } |
| 1359 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); | 1352 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); |
| 1360 } | 1353 } |
| 1361 | 1354 |
| 1362 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1355 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1389 out->set_tag(kSCUP); | 1382 out->set_tag(kSCUP); |
| 1390 out->SetStringPiece(kSCFG, serialized); | 1383 out->SetStringPiece(kSCFG, serialized); |
| 1391 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); | 1384 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); |
| 1392 out->SetValue(kSTTL, | 1385 out->SetValue(kSTTL, |
| 1393 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); | 1386 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); |
| 1394 | 1387 |
| 1395 QuicReferenceCountedPointer<ProofSource::Chain> chain; | 1388 QuicReferenceCountedPointer<ProofSource::Chain> chain; |
| 1396 QuicCryptoProof proof; | 1389 QuicCryptoProof proof; |
| 1397 if (!proof_source_->GetProof(server_address, params.sni, serialized, version, | 1390 if (!proof_source_->GetProof(server_address, params.sni, serialized, version, |
| 1398 chlo_hash, connection_options, &chain, &proof)) { | 1391 chlo_hash, connection_options, &chain, &proof)) { |
| 1399 QUIC_DVLOG(1) << "Server: failed to get proof."; | 1392 DVLOG(1) << "Server: failed to get proof."; |
| 1400 return false; | 1393 return false; |
| 1401 } | 1394 } |
| 1402 | 1395 |
| 1403 const string compressed = CompressChain( | 1396 const string compressed = CompressChain( |
| 1404 compressed_certs_cache, chain, params.client_common_set_hashes, | 1397 compressed_certs_cache, chain, params.client_common_set_hashes, |
| 1405 params.client_cached_cert_hashes, common_cert_sets); | 1398 params.client_cached_cert_hashes, common_cert_sets); |
| 1406 | 1399 |
| 1407 out->SetStringPiece(kCertificateTag, compressed); | 1400 out->SetStringPiece(kCertificateTag, compressed); |
| 1408 out->SetStringPiece(kPROF, proof.signature); | 1401 out->SetStringPiece(kPROF, proof.signature); |
| 1409 if (params.sct_supported_by_client && enable_serving_sct_) { | 1402 if (params.sct_supported_by_client && enable_serving_sct_) { |
| 1410 if (proof.leaf_cert_scts.empty()) { | 1403 if (proof.leaf_cert_scts.empty()) { |
| 1411 QUIC_LOG_EVERY_N_SEC(WARNING, 60) | 1404 DLOG(WARNING) << "SCT is expected but it is empty. sni: " << params.sni |
| 1412 << "SCT is expected but it is empty. sni: " << params.sni | 1405 << " server_address: " << server_address.ToString(); |
| 1413 << " server_address: " << server_address.ToString(); | |
| 1414 } else { | 1406 } else { |
| 1415 out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); | 1407 out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); |
| 1416 } | 1408 } |
| 1417 } | 1409 } |
| 1418 return true; | 1410 return true; |
| 1419 } | 1411 } |
| 1420 | 1412 |
| 1421 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1413 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| 1422 QuicVersion version, | 1414 QuicVersion version, |
| 1423 StringPiece chlo_hash, | 1415 StringPiece chlo_hash, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1519 } | 1511 } |
| 1520 | 1512 |
| 1521 const string compressed = | 1513 const string compressed = |
| 1522 CompressChain(compressed_certs_cache, chain, client_common_set_hashes, | 1514 CompressChain(compressed_certs_cache, chain, client_common_set_hashes, |
| 1523 client_cached_cert_hashes, common_cert_sets); | 1515 client_cached_cert_hashes, common_cert_sets); |
| 1524 | 1516 |
| 1525 message.SetStringPiece(kCertificateTag, compressed); | 1517 message.SetStringPiece(kCertificateTag, compressed); |
| 1526 message.SetStringPiece(kPROF, signature); | 1518 message.SetStringPiece(kPROF, signature); |
| 1527 if (sct_supported_by_client && enable_serving_sct_) { | 1519 if (sct_supported_by_client && enable_serving_sct_) { |
| 1528 if (leaf_cert_sct.empty()) { | 1520 if (leaf_cert_sct.empty()) { |
| 1529 QUIC_LOG_EVERY_N_SEC(WARNING, 60) << "SCT is expected but it is empty."; | 1521 DLOG(WARNING) << "SCT is expected but it is empty."; |
| 1530 } else { | 1522 } else { |
| 1531 message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct); | 1523 message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct); |
| 1532 } | 1524 } |
| 1533 } | 1525 } |
| 1534 | 1526 |
| 1535 cb->Run(true, message); | 1527 cb->Run(true, message); |
| 1536 } | 1528 } |
| 1537 | 1529 |
| 1538 void QuicCryptoServerConfig::BuildRejection( | 1530 void QuicCryptoServerConfig::BuildRejection( |
| 1539 QuicVersion version, | 1531 QuicVersion version, |
| 1540 QuicWallTime now, | 1532 QuicWallTime now, |
| 1541 const Config& config, | 1533 const Config& config, |
| 1542 const CryptoHandshakeMessage& client_hello, | 1534 const CryptoHandshakeMessage& client_hello, |
| 1543 const ClientHelloInfo& info, | 1535 const ClientHelloInfo& info, |
| 1544 const CachedNetworkParameters& cached_network_params, | 1536 const CachedNetworkParameters& cached_network_params, |
| 1545 bool use_stateless_rejects, | 1537 bool use_stateless_rejects, |
| 1546 QuicConnectionId server_designated_connection_id, | 1538 QuicConnectionId server_designated_connection_id, |
| 1547 QuicRandom* rand, | 1539 QuicRandom* rand, |
| 1548 QuicCompressedCertsCache* compressed_certs_cache, | 1540 QuicCompressedCertsCache* compressed_certs_cache, |
| 1549 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, | 1541 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, |
| 1550 const QuicSignedServerConfig& signed_config, | 1542 const QuicSignedServerConfig& signed_config, |
| 1551 QuicByteCount total_framing_overhead, | 1543 QuicByteCount total_framing_overhead, |
| 1552 QuicByteCount chlo_packet_size, | 1544 QuicByteCount chlo_packet_size, |
| 1553 CryptoHandshakeMessage* out) const { | 1545 CryptoHandshakeMessage* out) const { |
| 1554 if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support && | 1546 if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support && |
| 1555 use_stateless_rejects) { | 1547 use_stateless_rejects) { |
| 1556 QUIC_DVLOG(1) << "QUIC Crypto server config returning stateless reject " | 1548 DVLOG(1) << "QUIC Crypto server config returning stateless reject " |
| 1557 << "with server-designated connection ID " | 1549 << "with server-designated connection ID " |
| 1558 << server_designated_connection_id; | 1550 << server_designated_connection_id; |
| 1559 out->set_tag(kSREJ); | 1551 out->set_tag(kSREJ); |
| 1560 out->SetValue(kRCID, server_designated_connection_id); | 1552 out->SetValue(kRCID, server_designated_connection_id); |
| 1561 } else { | 1553 } else { |
| 1562 out->set_tag(kREJ); | 1554 out->set_tag(kREJ); |
| 1563 } | 1555 } |
| 1564 out->SetStringPiece(kSCFG, config.serialized); | 1556 out->SetStringPiece(kSCFG, config.serialized); |
| 1565 out->SetStringPiece( | 1557 out->SetStringPiece( |
| 1566 kSourceAddressTokenTag, | 1558 kSourceAddressTokenTag, |
| 1567 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip, | 1559 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip, |
| 1568 rand, info.now, &cached_network_params)); | 1560 rand, info.now, &cached_network_params)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 params->sct_supported_by_client && enable_serving_sct_; | 1609 params->sct_supported_by_client && enable_serving_sct_; |
| 1618 const string& cert_sct = signed_config.proof.leaf_cert_scts; | 1610 const string& cert_sct = signed_config.proof.leaf_cert_scts; |
| 1619 const size_t sct_size = should_return_sct ? cert_sct.size() : 0; | 1611 const size_t sct_size = should_return_sct ? cert_sct.size() : 0; |
| 1620 const size_t total_size = | 1612 const size_t total_size = |
| 1621 signed_config.proof.signature.size() + compressed.size() + sct_size; | 1613 signed_config.proof.signature.size() + compressed.size() + sct_size; |
| 1622 if (info.valid_source_address_token || total_size < max_unverified_size) { | 1614 if (info.valid_source_address_token || total_size < max_unverified_size) { |
| 1623 out->SetStringPiece(kCertificateTag, compressed); | 1615 out->SetStringPiece(kCertificateTag, compressed); |
| 1624 out->SetStringPiece(kPROF, signed_config.proof.signature); | 1616 out->SetStringPiece(kPROF, signed_config.proof.signature); |
| 1625 if (should_return_sct) { | 1617 if (should_return_sct) { |
| 1626 if (cert_sct.empty()) { | 1618 if (cert_sct.empty()) { |
| 1627 QUIC_LOG_EVERY_N_SEC(WARNING, 60) << "SCT is expected but it is empty."; | 1619 DLOG(WARNING) << "SCT is expected but it is empty."; |
| 1628 } else { | 1620 } else { |
| 1629 out->SetStringPiece(kCertificateSCTTag, cert_sct); | 1621 out->SetStringPiece(kCertificateSCTTag, cert_sct); |
| 1630 } | 1622 } |
| 1631 } | 1623 } |
| 1632 } else { | 1624 } else { |
| 1633 QUIC_LOG_EVERY_N_SEC(WARNING, 60) | 1625 DLOG(WARNING) << "Sending inchoate REJ for hostname: " << info.sni |
| 1634 << "Sending inchoate REJ for hostname: " << info.sni | 1626 << " signature: " << signed_config.proof.signature.size() |
| 1635 << " signature: " << signed_config.proof.signature.size() | 1627 << " cert: " << compressed.size() << " sct:" << sct_size |
| 1636 << " cert: " << compressed.size() << " sct:" << sct_size | 1628 << " total: " << total_size |
| 1637 << " total: " << total_size << " max: " << max_unverified_size; | 1629 << " max: " << max_unverified_size; |
| 1638 } | 1630 } |
| 1639 } | 1631 } |
| 1640 | 1632 |
| 1641 string QuicCryptoServerConfig::CompressChain( | 1633 string QuicCryptoServerConfig::CompressChain( |
| 1642 QuicCompressedCertsCache* compressed_certs_cache, | 1634 QuicCompressedCertsCache* compressed_certs_cache, |
| 1643 const QuicReferenceCountedPointer<ProofSource::Chain>& chain, | 1635 const QuicReferenceCountedPointer<ProofSource::Chain>& chain, |
| 1644 const string& client_common_set_hashes, | 1636 const string& client_common_set_hashes, |
| 1645 const string& client_cached_cert_hashes, | 1637 const string& client_cached_cert_hashes, |
| 1646 const CommonCertSets* common_sets) { | 1638 const CommonCertSets* common_sets) { |
| 1647 // Check whether the compressed certs is available in the cache. | 1639 // Check whether the compressed certs is available in the cache. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1662 return compressed; | 1654 return compressed; |
| 1663 } | 1655 } |
| 1664 | 1656 |
| 1665 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> | 1657 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> |
| 1666 QuicCryptoServerConfig::ParseConfigProtobuf( | 1658 QuicCryptoServerConfig::ParseConfigProtobuf( |
| 1667 const std::unique_ptr<QuicServerConfigProtobuf>& protobuf) { | 1659 const std::unique_ptr<QuicServerConfigProtobuf>& protobuf) { |
| 1668 std::unique_ptr<CryptoHandshakeMessage> msg( | 1660 std::unique_ptr<CryptoHandshakeMessage> msg( |
| 1669 CryptoFramer::ParseMessage(protobuf->config())); | 1661 CryptoFramer::ParseMessage(protobuf->config())); |
| 1670 | 1662 |
| 1671 if (msg->tag() != kSCFG) { | 1663 if (msg->tag() != kSCFG) { |
| 1672 QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag() | 1664 LOG(WARNING) << "Server config message has tag " << msg->tag() |
| 1673 << " expected " << kSCFG; | 1665 << " expected " << kSCFG; |
| 1674 return nullptr; | 1666 return nullptr; |
| 1675 } | 1667 } |
| 1676 | 1668 |
| 1677 QuicReferenceCountedPointer<Config> config(new Config); | 1669 QuicReferenceCountedPointer<Config> config(new Config); |
| 1678 config->serialized = protobuf->config(); | 1670 config->serialized = protobuf->config(); |
| 1679 config->source_address_token_boxer = &source_address_token_boxer_; | 1671 config->source_address_token_boxer = &source_address_token_boxer_; |
| 1680 | 1672 |
| 1681 if (protobuf->has_primary_time()) { | 1673 if (protobuf->has_primary_time()) { |
| 1682 config->primary_time = | 1674 config->primary_time = |
| 1683 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1675 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
| 1684 } | 1676 } |
| 1685 | 1677 |
| 1686 config->priority = protobuf->priority(); | 1678 config->priority = protobuf->priority(); |
| 1687 | 1679 |
| 1688 StringPiece scid; | 1680 StringPiece scid; |
| 1689 if (!msg->GetStringPiece(kSCID, &scid)) { | 1681 if (!msg->GetStringPiece(kSCID, &scid)) { |
| 1690 QUIC_LOG(WARNING) << "Server config message is missing SCID"; | 1682 LOG(WARNING) << "Server config message is missing SCID"; |
| 1691 return nullptr; | 1683 return nullptr; |
| 1692 } | 1684 } |
| 1693 config->id = scid.as_string(); | 1685 config->id = scid.as_string(); |
| 1694 | 1686 |
| 1695 const QuicTag* aead_tags; | 1687 const QuicTag* aead_tags; |
| 1696 size_t aead_len; | 1688 size_t aead_len; |
| 1697 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | 1689 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { |
| 1698 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; | 1690 LOG(WARNING) << "Server config message is missing AEAD"; |
| 1699 return nullptr; | 1691 return nullptr; |
| 1700 } | 1692 } |
| 1701 config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); | 1693 config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); |
| 1702 | 1694 |
| 1703 const QuicTag* kexs_tags; | 1695 const QuicTag* kexs_tags; |
| 1704 size_t kexs_len; | 1696 size_t kexs_len; |
| 1705 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | 1697 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { |
| 1706 QUIC_LOG(WARNING) << "Server config message is missing KEXS"; | 1698 LOG(WARNING) << "Server config message is missing KEXS"; |
| 1707 return nullptr; | 1699 return nullptr; |
| 1708 } | 1700 } |
| 1709 | 1701 |
| 1710 const QuicTag* tbkp_tags; | 1702 const QuicTag* tbkp_tags; |
| 1711 size_t tbkp_len; | 1703 size_t tbkp_len; |
| 1712 QuicErrorCode err; | 1704 QuicErrorCode err; |
| 1713 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != | 1705 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != |
| 1714 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && | 1706 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && |
| 1715 err != QUIC_NO_ERROR) { | 1707 err != QUIC_NO_ERROR) { |
| 1716 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; | 1708 LOG(WARNING) << "Server config message is missing or has invalid TBKP"; |
| 1717 return nullptr; | 1709 return nullptr; |
| 1718 } | 1710 } |
| 1719 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); | 1711 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); |
| 1720 | 1712 |
| 1721 StringPiece orbit; | 1713 StringPiece orbit; |
| 1722 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1714 if (!msg->GetStringPiece(kORBT, &orbit)) { |
| 1723 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; | 1715 LOG(WARNING) << "Server config message is missing ORBT"; |
| 1724 return nullptr; | 1716 return nullptr; |
| 1725 } | 1717 } |
| 1726 | 1718 |
| 1727 if (orbit.size() != kOrbitSize) { | 1719 if (orbit.size() != kOrbitSize) { |
| 1728 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." | 1720 LOG(WARNING) << "Orbit value in server config is the wrong length." |
| 1729 " Got " | 1721 " Got " |
| 1730 << orbit.size() << " want " << kOrbitSize; | 1722 << orbit.size() << " want " << kOrbitSize; |
| 1731 return nullptr; | 1723 return nullptr; |
| 1732 } | 1724 } |
| 1733 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); | 1725 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); |
| 1734 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1726 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
| 1735 | 1727 |
| 1736 if (kexs_len != protobuf->key_size()) { | 1728 if (kexs_len != protobuf->key_size()) { |
| 1737 QUIC_LOG(WARNING) << "Server config has " << kexs_len | 1729 LOG(WARNING) << "Server config has " << kexs_len |
| 1738 << " key exchange methods configured, but " | 1730 << " key exchange methods configured, but " |
| 1739 << protobuf->key_size() << " private keys"; | 1731 << protobuf->key_size() << " private keys"; |
| 1740 return nullptr; | 1732 return nullptr; |
| 1741 } | 1733 } |
| 1742 | 1734 |
| 1743 const QuicTag* proof_demand_tags; | 1735 const QuicTag* proof_demand_tags; |
| 1744 size_t num_proof_demand_tags; | 1736 size_t num_proof_demand_tags; |
| 1745 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == | 1737 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == |
| 1746 QUIC_NO_ERROR) { | 1738 QUIC_NO_ERROR) { |
| 1747 for (size_t i = 0; i < num_proof_demand_tags; i++) { | 1739 for (size_t i = 0; i < num_proof_demand_tags; i++) { |
| 1748 if (proof_demand_tags[i] == kCHID) { | 1740 if (proof_demand_tags[i] == kCHID) { |
| 1749 config->channel_id_enabled = true; | 1741 config->channel_id_enabled = true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1760 | 1752 |
| 1761 for (size_t j = 0; j < protobuf->key_size(); j++) { | 1753 for (size_t j = 0; j < protobuf->key_size(); j++) { |
| 1762 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); | 1754 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); |
| 1763 if (key.tag() == tag) { | 1755 if (key.tag() == tag) { |
| 1764 private_key = key.private_key(); | 1756 private_key = key.private_key(); |
| 1765 break; | 1757 break; |
| 1766 } | 1758 } |
| 1767 } | 1759 } |
| 1768 | 1760 |
| 1769 if (private_key.empty()) { | 1761 if (private_key.empty()) { |
| 1770 QUIC_LOG(WARNING) << "Server config contains key exchange method without " | 1762 LOG(WARNING) << "Server config contains key exchange method without " |
| 1771 "corresponding private key: " | 1763 "corresponding private key: " |
| 1772 << tag; | 1764 << tag; |
| 1773 return nullptr; | 1765 return nullptr; |
| 1774 } | 1766 } |
| 1775 | 1767 |
| 1776 std::unique_ptr<KeyExchange> ka; | 1768 std::unique_ptr<KeyExchange> ka; |
| 1777 switch (tag) { | 1769 switch (tag) { |
| 1778 case kC255: | 1770 case kC255: |
| 1779 ka.reset(Curve25519KeyExchange::New(private_key)); | 1771 ka.reset(Curve25519KeyExchange::New(private_key)); |
| 1780 if (!ka.get()) { | 1772 if (!ka.get()) { |
| 1781 QUIC_LOG(WARNING) << "Server config contained an invalid curve25519" | 1773 LOG(WARNING) << "Server config contained an invalid curve25519" |
| 1782 " private key."; | 1774 " private key."; |
| 1783 return nullptr; | 1775 return nullptr; |
| 1784 } | 1776 } |
| 1785 break; | 1777 break; |
| 1786 case kP256: | 1778 case kP256: |
| 1787 ka.reset(P256KeyExchange::New(private_key)); | 1779 ka.reset(P256KeyExchange::New(private_key)); |
| 1788 if (!ka.get()) { | 1780 if (!ka.get()) { |
| 1789 QUIC_LOG(WARNING) << "Server config contained an invalid P-256" | 1781 LOG(WARNING) << "Server config contained an invalid P-256" |
| 1790 " private key."; | 1782 " private key."; |
| 1791 return nullptr; | 1783 return nullptr; |
| 1792 } | 1784 } |
| 1793 break; | 1785 break; |
| 1794 default: | 1786 default: |
| 1795 QUIC_LOG(WARNING) | 1787 LOG(WARNING) << "Server config message contains unknown key exchange " |
| 1796 << "Server config message contains unknown key exchange " | 1788 "method: " |
| 1797 "method: " | 1789 << tag; |
| 1798 << tag; | |
| 1799 return nullptr; | 1790 return nullptr; |
| 1800 } | 1791 } |
| 1801 | 1792 |
| 1802 for (const auto& key_exchange : config->key_exchanges) { | 1793 for (const auto& key_exchange : config->key_exchanges) { |
| 1803 if (key_exchange->tag() == tag) { | 1794 if (key_exchange->tag() == tag) { |
| 1804 QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1795 LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
| 1805 return nullptr; | 1796 return nullptr; |
| 1806 } | 1797 } |
| 1807 } | 1798 } |
| 1808 | 1799 |
| 1809 config->key_exchanges.push_back(std::move(ka)); | 1800 config->key_exchanges.push_back(std::move(ka)); |
| 1810 } | 1801 } |
| 1811 | 1802 |
| 1812 uint64_t expiry_seconds; | 1803 uint64_t expiry_seconds; |
| 1813 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { | 1804 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { |
| 1814 QUIC_LOG(WARNING) << "Server config message is missing EXPY"; | 1805 LOG(WARNING) << "Server config message is missing EXPY"; |
| 1815 return nullptr; | 1806 return nullptr; |
| 1816 } | 1807 } |
| 1817 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); | 1808 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); |
| 1818 | 1809 |
| 1819 return config; | 1810 return config; |
| 1820 } | 1811 } |
| 1821 | 1812 |
| 1822 void QuicCryptoServerConfig::SetEphemeralKeySource( | 1813 void QuicCryptoServerConfig::SetEphemeralKeySource( |
| 1823 EphemeralKeySource* ephemeral_key_source) { | 1814 EphemeralKeySource* ephemeral_key_source) { |
| 1824 ephemeral_key_source_.reset(ephemeral_key_source); | 1815 ephemeral_key_source_.reset(ephemeral_key_source); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2034 expiry_time(QuicWallTime::Zero()), | 2025 expiry_time(QuicWallTime::Zero()), |
| 2035 priority(0), | 2026 priority(0), |
| 2036 source_address_token_boxer(nullptr) {} | 2027 source_address_token_boxer(nullptr) {} |
| 2037 | 2028 |
| 2038 QuicCryptoServerConfig::Config::~Config() {} | 2029 QuicCryptoServerConfig::Config::~Config() {} |
| 2039 | 2030 |
| 2040 QuicSignedServerConfig::QuicSignedServerConfig() {} | 2031 QuicSignedServerConfig::QuicSignedServerConfig() {} |
| 2041 QuicSignedServerConfig::~QuicSignedServerConfig() {} | 2032 QuicSignedServerConfig::~QuicSignedServerConfig() {} |
| 2042 | 2033 |
| 2043 } // namespace net | 2034 } // namespace net |
| OLD | NEW |