| 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_bug_tracker.h" | 33 #include "net/quic/core/quic_bug_tracker.h" |
| 34 #include "net/quic/core/quic_flags.h" | 34 #include "net/quic/core/quic_flags.h" |
| 35 #include "net/quic/core/quic_packets.h" | 35 #include "net/quic/core/quic_packets.h" |
| 36 #include "net/quic/core/quic_socket_address_coder.h" | 36 #include "net/quic/core/quic_socket_address_coder.h" |
| 37 #include "net/quic/core/quic_utils.h" | 37 #include "net/quic/core/quic_utils.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 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 } | 1096 } |
| 1091 } else { | 1097 } else { |
| 1092 next_config_promotion_time_ = config->primary_time; | 1098 next_config_promotion_time_ = config->primary_time; |
| 1093 } | 1099 } |
| 1094 | 1100 |
| 1095 if (primary_config_) { | 1101 if (primary_config_) { |
| 1096 primary_config_->is_primary = false; | 1102 primary_config_->is_primary = false; |
| 1097 } | 1103 } |
| 1098 primary_config_ = new_primary; | 1104 primary_config_ = new_primary; |
| 1099 new_primary->is_primary = true; | 1105 new_primary->is_primary = true; |
| 1100 DVLOG(1) << "New primary config. orbit: " | 1106 QUIC_DLOG(INFO) << "New primary config. orbit: " |
| 1101 << QuicTextUtils::HexEncode( | 1107 << QuicTextUtils::HexEncode(reinterpret_cast<const char*>( |
| 1102 reinterpret_cast<const char*>(primary_config_->orbit), | 1108 primary_config_->orbit), |
| 1103 kOrbitSize); | 1109 kOrbitSize); |
| 1104 if (primary_config_changed_cb_.get() != nullptr) { | 1110 if (primary_config_changed_cb_.get() != nullptr) { |
| 1105 primary_config_changed_cb_->Run(primary_config_->id); | 1111 primary_config_changed_cb_->Run(primary_config_->id); |
| 1106 } | 1112 } |
| 1107 | 1113 |
| 1108 return; | 1114 return; |
| 1109 } | 1115 } |
| 1110 | 1116 |
| 1111 // All config's primary times are in the past. We should make the most recent | 1117 // All config's primary times are in the past. We should make the most recent |
| 1112 // and highest priority candidate primary. | 1118 // and highest priority candidate primary. |
| 1113 QuicReferenceCountedPointer<Config> new_primary = best_candidate; | 1119 QuicReferenceCountedPointer<Config> new_primary = best_candidate; |
| 1114 if (primary_config_) { | 1120 if (primary_config_) { |
| 1115 primary_config_->is_primary = false; | 1121 primary_config_->is_primary = false; |
| 1116 } | 1122 } |
| 1117 primary_config_ = new_primary; | 1123 primary_config_ = new_primary; |
| 1118 new_primary->is_primary = true; | 1124 new_primary->is_primary = true; |
| 1119 DVLOG(1) << "New primary config. orbit: " | 1125 QUIC_DLOG(INFO) << "New primary config. orbit: " |
| 1120 << QuicTextUtils::HexEncode( | 1126 << QuicTextUtils::HexEncode( |
| 1121 reinterpret_cast<const char*>(primary_config_->orbit), | 1127 reinterpret_cast<const char*>(primary_config_->orbit), |
| 1122 kOrbitSize) | 1128 kOrbitSize) |
| 1123 << " scid: " << QuicTextUtils::HexEncode(primary_config_->id); | 1129 << " scid: " << QuicTextUtils::HexEncode(primary_config_->id); |
| 1124 next_config_promotion_time_ = QuicWallTime::Zero(); | 1130 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 1125 if (primary_config_changed_cb_.get() != nullptr) { | 1131 if (primary_config_changed_cb_.get() != nullptr) { |
| 1126 primary_config_changed_cb_->Run(primary_config_->id); | 1132 primary_config_changed_cb_->Run(primary_config_->id); |
| 1127 } | 1133 } |
| 1128 } | 1134 } |
| 1129 | 1135 |
| 1130 class QuicCryptoServerConfig::EvaluateClientHelloCallback | 1136 class QuicCryptoServerConfig::EvaluateClientHelloCallback |
| 1131 : public ProofSource::Callback { | 1137 : public ProofSource::Callback { |
| 1132 public: | 1138 public: |
| 1133 EvaluateClientHelloCallback( | 1139 EvaluateClientHelloCallback( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); | 1333 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
| 1328 } | 1334 } |
| 1329 | 1335 |
| 1330 if (!ValidateExpectedLeafCertificate(client_hello, *signed_config)) { | 1336 if (!ValidateExpectedLeafCertificate(client_hello, *signed_config)) { |
| 1331 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); | 1337 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); |
| 1332 } | 1338 } |
| 1333 | 1339 |
| 1334 if (info->client_nonce.size() != kNonceSize) { | 1340 if (info->client_nonce.size() != kNonceSize) { |
| 1335 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); | 1341 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); |
| 1336 // Invalid client nonce. | 1342 // Invalid client nonce. |
| 1337 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); | 1343 QUIC_LOG_FIRST_N(ERROR, 2) << "Invalid client nonce: " |
| 1338 DVLOG(1) << "Invalid client nonce."; | 1344 << client_hello.DebugString(); |
| 1345 QUIC_DLOG(INFO) << "Invalid client nonce."; |
| 1339 } | 1346 } |
| 1340 | 1347 |
| 1341 // Server nonce is optional, and used for key derivation if present. | 1348 // Server nonce is optional, and used for key derivation if present. |
| 1342 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); | 1349 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
| 1343 | 1350 |
| 1344 DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; | 1351 QUIC_DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; |
| 1345 // If the server nonce is empty and we're requiring handshake confirmation | 1352 // If the server nonce is empty and we're requiring handshake confirmation |
| 1346 // for DoS reasons then we must reject the CHLO. | 1353 // for DoS reasons then we must reject the CHLO. |
| 1347 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && | 1354 if (FLAGS_quic_reloadable_flag_quic_require_handshake_confirmation && |
| 1348 info->server_nonce.empty()) { | 1355 info->server_nonce.empty()) { |
| 1349 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); | 1356 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
| 1350 } | 1357 } |
| 1351 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); | 1358 helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); |
| 1352 } | 1359 } |
| 1353 | 1360 |
| 1354 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1361 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1381 out->set_tag(kSCUP); | 1388 out->set_tag(kSCUP); |
| 1382 out->SetStringPiece(kSCFG, serialized); | 1389 out->SetStringPiece(kSCFG, serialized); |
| 1383 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); | 1390 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); |
| 1384 out->SetValue(kSTTL, | 1391 out->SetValue(kSTTL, |
| 1385 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); | 1392 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); |
| 1386 | 1393 |
| 1387 QuicReferenceCountedPointer<ProofSource::Chain> chain; | 1394 QuicReferenceCountedPointer<ProofSource::Chain> chain; |
| 1388 QuicCryptoProof proof; | 1395 QuicCryptoProof proof; |
| 1389 if (!proof_source_->GetProof(server_address, params.sni, serialized, version, | 1396 if (!proof_source_->GetProof(server_address, params.sni, serialized, version, |
| 1390 chlo_hash, connection_options, &chain, &proof)) { | 1397 chlo_hash, connection_options, &chain, &proof)) { |
| 1391 DVLOG(1) << "Server: failed to get proof."; | 1398 QUIC_DVLOG(1) << "Server: failed to get proof."; |
| 1392 return false; | 1399 return false; |
| 1393 } | 1400 } |
| 1394 | 1401 |
| 1395 const string compressed = CompressChain( | 1402 const string compressed = CompressChain( |
| 1396 compressed_certs_cache, chain, params.client_common_set_hashes, | 1403 compressed_certs_cache, chain, params.client_common_set_hashes, |
| 1397 params.client_cached_cert_hashes, common_cert_sets); | 1404 params.client_cached_cert_hashes, common_cert_sets); |
| 1398 | 1405 |
| 1399 out->SetStringPiece(kCertificateTag, compressed); | 1406 out->SetStringPiece(kCertificateTag, compressed); |
| 1400 out->SetStringPiece(kPROF, proof.signature); | 1407 out->SetStringPiece(kPROF, proof.signature); |
| 1401 if (params.sct_supported_by_client && enable_serving_sct_) { | 1408 if (params.sct_supported_by_client && enable_serving_sct_) { |
| 1402 if (proof.leaf_cert_scts.empty()) { | 1409 if (proof.leaf_cert_scts.empty()) { |
| 1403 DLOG(WARNING) << "SCT is expected but it is empty. sni: " << params.sni | 1410 QUIC_LOG_EVERY_N_SEC(WARNING, 60) |
| 1404 << " server_address: " << server_address.ToString(); | 1411 << "SCT is expected but it is empty. sni: " << params.sni |
| 1412 << " server_address: " << server_address.ToString(); |
| 1405 } else { | 1413 } else { |
| 1406 out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); | 1414 out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); |
| 1407 } | 1415 } |
| 1408 } | 1416 } |
| 1409 return true; | 1417 return true; |
| 1410 } | 1418 } |
| 1411 | 1419 |
| 1412 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1420 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| 1413 QuicVersion version, | 1421 QuicVersion version, |
| 1414 StringPiece chlo_hash, | 1422 StringPiece chlo_hash, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1510 } | 1518 } |
| 1511 | 1519 |
| 1512 const string compressed = | 1520 const string compressed = |
| 1513 CompressChain(compressed_certs_cache, chain, client_common_set_hashes, | 1521 CompressChain(compressed_certs_cache, chain, client_common_set_hashes, |
| 1514 client_cached_cert_hashes, common_cert_sets); | 1522 client_cached_cert_hashes, common_cert_sets); |
| 1515 | 1523 |
| 1516 message.SetStringPiece(kCertificateTag, compressed); | 1524 message.SetStringPiece(kCertificateTag, compressed); |
| 1517 message.SetStringPiece(kPROF, signature); | 1525 message.SetStringPiece(kPROF, signature); |
| 1518 if (sct_supported_by_client && enable_serving_sct_) { | 1526 if (sct_supported_by_client && enable_serving_sct_) { |
| 1519 if (leaf_cert_sct.empty()) { | 1527 if (leaf_cert_sct.empty()) { |
| 1520 DLOG(WARNING) << "SCT is expected but it is empty."; | 1528 QUIC_LOG_EVERY_N_SEC(WARNING, 60) << "SCT is expected but it is empty."; |
| 1521 } else { | 1529 } else { |
| 1522 message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct); | 1530 message.SetStringPiece(kCertificateSCTTag, leaf_cert_sct); |
| 1523 } | 1531 } |
| 1524 } | 1532 } |
| 1525 | 1533 |
| 1526 cb->Run(true, message); | 1534 cb->Run(true, message); |
| 1527 } | 1535 } |
| 1528 | 1536 |
| 1529 void QuicCryptoServerConfig::BuildRejection( | 1537 void QuicCryptoServerConfig::BuildRejection( |
| 1530 QuicVersion version, | 1538 QuicVersion version, |
| 1531 QuicWallTime now, | 1539 QuicWallTime now, |
| 1532 const Config& config, | 1540 const Config& config, |
| 1533 const CryptoHandshakeMessage& client_hello, | 1541 const CryptoHandshakeMessage& client_hello, |
| 1534 const ClientHelloInfo& info, | 1542 const ClientHelloInfo& info, |
| 1535 const CachedNetworkParameters& cached_network_params, | 1543 const CachedNetworkParameters& cached_network_params, |
| 1536 bool use_stateless_rejects, | 1544 bool use_stateless_rejects, |
| 1537 QuicConnectionId server_designated_connection_id, | 1545 QuicConnectionId server_designated_connection_id, |
| 1538 QuicRandom* rand, | 1546 QuicRandom* rand, |
| 1539 QuicCompressedCertsCache* compressed_certs_cache, | 1547 QuicCompressedCertsCache* compressed_certs_cache, |
| 1540 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, | 1548 QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters> params, |
| 1541 const QuicSignedServerConfig& signed_config, | 1549 const QuicSignedServerConfig& signed_config, |
| 1542 QuicByteCount total_framing_overhead, | 1550 QuicByteCount total_framing_overhead, |
| 1543 QuicByteCount chlo_packet_size, | 1551 QuicByteCount chlo_packet_size, |
| 1544 CryptoHandshakeMessage* out) const { | 1552 CryptoHandshakeMessage* out) const { |
| 1545 if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support && | 1553 if (FLAGS_quic_reloadable_flag_enable_quic_stateless_reject_support && |
| 1546 use_stateless_rejects) { | 1554 use_stateless_rejects) { |
| 1547 DVLOG(1) << "QUIC Crypto server config returning stateless reject " | 1555 QUIC_DVLOG(1) << "QUIC Crypto server config returning stateless reject " |
| 1548 << "with server-designated connection ID " | 1556 << "with server-designated connection ID " |
| 1549 << server_designated_connection_id; | 1557 << server_designated_connection_id; |
| 1550 out->set_tag(kSREJ); | 1558 out->set_tag(kSREJ); |
| 1551 out->SetValue(kRCID, server_designated_connection_id); | 1559 out->SetValue(kRCID, server_designated_connection_id); |
| 1552 } else { | 1560 } else { |
| 1553 out->set_tag(kREJ); | 1561 out->set_tag(kREJ); |
| 1554 } | 1562 } |
| 1555 out->SetStringPiece(kSCFG, config.serialized); | 1563 out->SetStringPiece(kSCFG, config.serialized); |
| 1556 out->SetStringPiece( | 1564 out->SetStringPiece( |
| 1557 kSourceAddressTokenTag, | 1565 kSourceAddressTokenTag, |
| 1558 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip, | 1566 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip, |
| 1559 rand, info.now, &cached_network_params)); | 1567 rand, info.now, &cached_network_params)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 params->sct_supported_by_client && enable_serving_sct_; | 1616 params->sct_supported_by_client && enable_serving_sct_; |
| 1609 const string& cert_sct = signed_config.proof.leaf_cert_scts; | 1617 const string& cert_sct = signed_config.proof.leaf_cert_scts; |
| 1610 const size_t sct_size = should_return_sct ? cert_sct.size() : 0; | 1618 const size_t sct_size = should_return_sct ? cert_sct.size() : 0; |
| 1611 const size_t total_size = | 1619 const size_t total_size = |
| 1612 signed_config.proof.signature.size() + compressed.size() + sct_size; | 1620 signed_config.proof.signature.size() + compressed.size() + sct_size; |
| 1613 if (info.valid_source_address_token || total_size < max_unverified_size) { | 1621 if (info.valid_source_address_token || total_size < max_unverified_size) { |
| 1614 out->SetStringPiece(kCertificateTag, compressed); | 1622 out->SetStringPiece(kCertificateTag, compressed); |
| 1615 out->SetStringPiece(kPROF, signed_config.proof.signature); | 1623 out->SetStringPiece(kPROF, signed_config.proof.signature); |
| 1616 if (should_return_sct) { | 1624 if (should_return_sct) { |
| 1617 if (cert_sct.empty()) { | 1625 if (cert_sct.empty()) { |
| 1618 DLOG(WARNING) << "SCT is expected but it is empty."; | 1626 QUIC_LOG_EVERY_N_SEC(WARNING, 60) << "SCT is expected but it is empty."; |
| 1619 } else { | 1627 } else { |
| 1620 out->SetStringPiece(kCertificateSCTTag, cert_sct); | 1628 out->SetStringPiece(kCertificateSCTTag, cert_sct); |
| 1621 } | 1629 } |
| 1622 } | 1630 } |
| 1623 } else { | 1631 } else { |
| 1624 DLOG(WARNING) << "Sending inchoate REJ for hostname: " << info.sni | 1632 QUIC_LOG_EVERY_N_SEC(WARNING, 60) |
| 1625 << " signature: " << signed_config.proof.signature.size() | 1633 << "Sending inchoate REJ for hostname: " << info.sni |
| 1626 << " cert: " << compressed.size() << " sct:" << sct_size | 1634 << " signature: " << signed_config.proof.signature.size() |
| 1627 << " total: " << total_size | 1635 << " cert: " << compressed.size() << " sct:" << sct_size |
| 1628 << " max: " << max_unverified_size; | 1636 << " total: " << total_size << " max: " << max_unverified_size; |
| 1629 } | 1637 } |
| 1630 } | 1638 } |
| 1631 | 1639 |
| 1632 string QuicCryptoServerConfig::CompressChain( | 1640 string QuicCryptoServerConfig::CompressChain( |
| 1633 QuicCompressedCertsCache* compressed_certs_cache, | 1641 QuicCompressedCertsCache* compressed_certs_cache, |
| 1634 const QuicReferenceCountedPointer<ProofSource::Chain>& chain, | 1642 const QuicReferenceCountedPointer<ProofSource::Chain>& chain, |
| 1635 const string& client_common_set_hashes, | 1643 const string& client_common_set_hashes, |
| 1636 const string& client_cached_cert_hashes, | 1644 const string& client_cached_cert_hashes, |
| 1637 const CommonCertSets* common_sets) { | 1645 const CommonCertSets* common_sets) { |
| 1638 // Check whether the compressed certs is available in the cache. | 1646 // Check whether the compressed certs is available in the cache. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1653 return compressed; | 1661 return compressed; |
| 1654 } | 1662 } |
| 1655 | 1663 |
| 1656 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> | 1664 QuicReferenceCountedPointer<QuicCryptoServerConfig::Config> |
| 1657 QuicCryptoServerConfig::ParseConfigProtobuf( | 1665 QuicCryptoServerConfig::ParseConfigProtobuf( |
| 1658 const std::unique_ptr<QuicServerConfigProtobuf>& protobuf) { | 1666 const std::unique_ptr<QuicServerConfigProtobuf>& protobuf) { |
| 1659 std::unique_ptr<CryptoHandshakeMessage> msg( | 1667 std::unique_ptr<CryptoHandshakeMessage> msg( |
| 1660 CryptoFramer::ParseMessage(protobuf->config())); | 1668 CryptoFramer::ParseMessage(protobuf->config())); |
| 1661 | 1669 |
| 1662 if (msg->tag() != kSCFG) { | 1670 if (msg->tag() != kSCFG) { |
| 1663 LOG(WARNING) << "Server config message has tag " << msg->tag() | 1671 QUIC_LOG(WARNING) << "Server config message has tag " << msg->tag() |
| 1664 << " expected " << kSCFG; | 1672 << " expected " << kSCFG; |
| 1665 return nullptr; | 1673 return nullptr; |
| 1666 } | 1674 } |
| 1667 | 1675 |
| 1668 QuicReferenceCountedPointer<Config> config(new Config); | 1676 QuicReferenceCountedPointer<Config> config(new Config); |
| 1669 config->serialized = protobuf->config(); | 1677 config->serialized = protobuf->config(); |
| 1670 config->source_address_token_boxer = &source_address_token_boxer_; | 1678 config->source_address_token_boxer = &source_address_token_boxer_; |
| 1671 | 1679 |
| 1672 if (protobuf->has_primary_time()) { | 1680 if (protobuf->has_primary_time()) { |
| 1673 config->primary_time = | 1681 config->primary_time = |
| 1674 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); | 1682 QuicWallTime::FromUNIXSeconds(protobuf->primary_time()); |
| 1675 } | 1683 } |
| 1676 | 1684 |
| 1677 config->priority = protobuf->priority(); | 1685 config->priority = protobuf->priority(); |
| 1678 | 1686 |
| 1679 StringPiece scid; | 1687 StringPiece scid; |
| 1680 if (!msg->GetStringPiece(kSCID, &scid)) { | 1688 if (!msg->GetStringPiece(kSCID, &scid)) { |
| 1681 LOG(WARNING) << "Server config message is missing SCID"; | 1689 QUIC_LOG(WARNING) << "Server config message is missing SCID"; |
| 1682 return nullptr; | 1690 return nullptr; |
| 1683 } | 1691 } |
| 1684 config->id = scid.as_string(); | 1692 config->id = scid.as_string(); |
| 1685 | 1693 |
| 1686 const QuicTag* aead_tags; | 1694 const QuicTag* aead_tags; |
| 1687 size_t aead_len; | 1695 size_t aead_len; |
| 1688 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | 1696 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { |
| 1689 LOG(WARNING) << "Server config message is missing AEAD"; | 1697 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; |
| 1690 return nullptr; | 1698 return nullptr; |
| 1691 } | 1699 } |
| 1692 config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); | 1700 config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); |
| 1693 | 1701 |
| 1694 const QuicTag* kexs_tags; | 1702 const QuicTag* kexs_tags; |
| 1695 size_t kexs_len; | 1703 size_t kexs_len; |
| 1696 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | 1704 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { |
| 1697 LOG(WARNING) << "Server config message is missing KEXS"; | 1705 QUIC_LOG(WARNING) << "Server config message is missing KEXS"; |
| 1698 return nullptr; | 1706 return nullptr; |
| 1699 } | 1707 } |
| 1700 | 1708 |
| 1701 const QuicTag* tbkp_tags; | 1709 const QuicTag* tbkp_tags; |
| 1702 size_t tbkp_len; | 1710 size_t tbkp_len; |
| 1703 QuicErrorCode err; | 1711 QuicErrorCode err; |
| 1704 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != | 1712 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != |
| 1705 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && | 1713 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && |
| 1706 err != QUIC_NO_ERROR) { | 1714 err != QUIC_NO_ERROR) { |
| 1707 LOG(WARNING) << "Server config message is missing or has invalid TBKP"; | 1715 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; |
| 1708 return nullptr; | 1716 return nullptr; |
| 1709 } | 1717 } |
| 1710 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); | 1718 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); |
| 1711 | 1719 |
| 1712 StringPiece orbit; | 1720 StringPiece orbit; |
| 1713 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1721 if (!msg->GetStringPiece(kORBT, &orbit)) { |
| 1714 LOG(WARNING) << "Server config message is missing ORBT"; | 1722 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; |
| 1715 return nullptr; | 1723 return nullptr; |
| 1716 } | 1724 } |
| 1717 | 1725 |
| 1718 if (orbit.size() != kOrbitSize) { | 1726 if (orbit.size() != kOrbitSize) { |
| 1719 LOG(WARNING) << "Orbit value in server config is the wrong length." | 1727 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." |
| 1720 " Got " | 1728 " Got " |
| 1721 << orbit.size() << " want " << kOrbitSize; | 1729 << orbit.size() << " want " << kOrbitSize; |
| 1722 return nullptr; | 1730 return nullptr; |
| 1723 } | 1731 } |
| 1724 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); | 1732 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); |
| 1725 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1733 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
| 1726 | 1734 |
| 1727 if (kexs_len != protobuf->key_size()) { | 1735 if (kexs_len != protobuf->key_size()) { |
| 1728 LOG(WARNING) << "Server config has " << kexs_len | 1736 QUIC_LOG(WARNING) << "Server config has " << kexs_len |
| 1729 << " key exchange methods configured, but " | 1737 << " key exchange methods configured, but " |
| 1730 << protobuf->key_size() << " private keys"; | 1738 << protobuf->key_size() << " private keys"; |
| 1731 return nullptr; | 1739 return nullptr; |
| 1732 } | 1740 } |
| 1733 | 1741 |
| 1734 const QuicTag* proof_demand_tags; | 1742 const QuicTag* proof_demand_tags; |
| 1735 size_t num_proof_demand_tags; | 1743 size_t num_proof_demand_tags; |
| 1736 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == | 1744 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == |
| 1737 QUIC_NO_ERROR) { | 1745 QUIC_NO_ERROR) { |
| 1738 for (size_t i = 0; i < num_proof_demand_tags; i++) { | 1746 for (size_t i = 0; i < num_proof_demand_tags; i++) { |
| 1739 if (proof_demand_tags[i] == kCHID) { | 1747 if (proof_demand_tags[i] == kCHID) { |
| 1740 config->channel_id_enabled = true; | 1748 config->channel_id_enabled = true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1751 | 1759 |
| 1752 for (size_t j = 0; j < protobuf->key_size(); j++) { | 1760 for (size_t j = 0; j < protobuf->key_size(); j++) { |
| 1753 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); | 1761 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); |
| 1754 if (key.tag() == tag) { | 1762 if (key.tag() == tag) { |
| 1755 private_key = key.private_key(); | 1763 private_key = key.private_key(); |
| 1756 break; | 1764 break; |
| 1757 } | 1765 } |
| 1758 } | 1766 } |
| 1759 | 1767 |
| 1760 if (private_key.empty()) { | 1768 if (private_key.empty()) { |
| 1761 LOG(WARNING) << "Server config contains key exchange method without " | 1769 QUIC_LOG(WARNING) << "Server config contains key exchange method without " |
| 1762 "corresponding private key: " | 1770 "corresponding private key: " |
| 1763 << tag; | 1771 << tag; |
| 1764 return nullptr; | 1772 return nullptr; |
| 1765 } | 1773 } |
| 1766 | 1774 |
| 1767 std::unique_ptr<KeyExchange> ka; | 1775 std::unique_ptr<KeyExchange> ka; |
| 1768 switch (tag) { | 1776 switch (tag) { |
| 1769 case kC255: | 1777 case kC255: |
| 1770 ka.reset(Curve25519KeyExchange::New(private_key)); | 1778 ka.reset(Curve25519KeyExchange::New(private_key)); |
| 1771 if (!ka.get()) { | 1779 if (!ka.get()) { |
| 1772 LOG(WARNING) << "Server config contained an invalid curve25519" | 1780 QUIC_LOG(WARNING) << "Server config contained an invalid curve25519" |
| 1773 " private key."; | 1781 " private key."; |
| 1774 return nullptr; | 1782 return nullptr; |
| 1775 } | 1783 } |
| 1776 break; | 1784 break; |
| 1777 case kP256: | 1785 case kP256: |
| 1778 ka.reset(P256KeyExchange::New(private_key)); | 1786 ka.reset(P256KeyExchange::New(private_key)); |
| 1779 if (!ka.get()) { | 1787 if (!ka.get()) { |
| 1780 LOG(WARNING) << "Server config contained an invalid P-256" | 1788 QUIC_LOG(WARNING) << "Server config contained an invalid P-256" |
| 1781 " private key."; | 1789 " private key."; |
| 1782 return nullptr; | 1790 return nullptr; |
| 1783 } | 1791 } |
| 1784 break; | 1792 break; |
| 1785 default: | 1793 default: |
| 1786 LOG(WARNING) << "Server config message contains unknown key exchange " | 1794 QUIC_LOG(WARNING) |
| 1787 "method: " | 1795 << "Server config message contains unknown key exchange " |
| 1788 << tag; | 1796 "method: " |
| 1797 << tag; |
| 1789 return nullptr; | 1798 return nullptr; |
| 1790 } | 1799 } |
| 1791 | 1800 |
| 1792 for (const auto& key_exchange : config->key_exchanges) { | 1801 for (const auto& key_exchange : config->key_exchanges) { |
| 1793 if (key_exchange->tag() == tag) { | 1802 if (key_exchange->tag() == tag) { |
| 1794 LOG(WARNING) << "Duplicate key exchange in config: " << tag; | 1803 QUIC_LOG(WARNING) << "Duplicate key exchange in config: " << tag; |
| 1795 return nullptr; | 1804 return nullptr; |
| 1796 } | 1805 } |
| 1797 } | 1806 } |
| 1798 | 1807 |
| 1799 config->key_exchanges.push_back(std::move(ka)); | 1808 config->key_exchanges.push_back(std::move(ka)); |
| 1800 } | 1809 } |
| 1801 | 1810 |
| 1802 uint64_t expiry_seconds; | 1811 uint64_t expiry_seconds; |
| 1803 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { | 1812 if (msg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) { |
| 1804 LOG(WARNING) << "Server config message is missing EXPY"; | 1813 QUIC_LOG(WARNING) << "Server config message is missing EXPY"; |
| 1805 return nullptr; | 1814 return nullptr; |
| 1806 } | 1815 } |
| 1807 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); | 1816 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); |
| 1808 | 1817 |
| 1809 return config; | 1818 return config; |
| 1810 } | 1819 } |
| 1811 | 1820 |
| 1812 void QuicCryptoServerConfig::SetEphemeralKeySource( | 1821 void QuicCryptoServerConfig::SetEphemeralKeySource( |
| 1813 EphemeralKeySource* ephemeral_key_source) { | 1822 EphemeralKeySource* ephemeral_key_source) { |
| 1814 ephemeral_key_source_.reset(ephemeral_key_source); | 1823 ephemeral_key_source_.reset(ephemeral_key_source); |
| (...skipping 210 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 |