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