Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: net/quic/crypto/quic_crypto_server_config.cc

Issue 1397983007: relnote: remove insecure QUIC support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rch_insecure_quic
Patch Set: Compile fix Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/quic_crypto_server_config.h" 5 #include "net/quic/crypto/quic_crypto_server_config.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <algorithm> 8 #include <algorithm>
9 9
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 delete this; 208 delete this;
209 } 209 }
210 210
211 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() 211 QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
212 : expiry_time(QuicWallTime::Zero()), 212 : expiry_time(QuicWallTime::Zero()),
213 channel_id_enabled(false), 213 channel_id_enabled(false),
214 p256(false) {} 214 p256(false) {}
215 215
216 QuicCryptoServerConfig::QuicCryptoServerConfig( 216 QuicCryptoServerConfig::QuicCryptoServerConfig(
217 StringPiece source_address_token_secret, 217 StringPiece source_address_token_secret,
218 QuicRandom* rand) 218 QuicRandom* server_nonce_entropy,
219 ProofSource* proof_source)
219 : replay_protection_(true), 220 : replay_protection_(true),
220 configs_lock_(), 221 configs_lock_(),
221 primary_config_(nullptr), 222 primary_config_(nullptr),
222 next_config_promotion_time_(QuicWallTime::Zero()), 223 next_config_promotion_time_(QuicWallTime::Zero()),
223 server_nonce_strike_register_lock_(), 224 server_nonce_strike_register_lock_(),
225 proof_source_(proof_source),
224 strike_register_no_startup_period_(false), 226 strike_register_no_startup_period_(false),
225 strike_register_max_entries_(1 << 10), 227 strike_register_max_entries_(1 << 10),
226 strike_register_window_secs_(600), 228 strike_register_window_secs_(600),
227 source_address_token_future_secs_(3600), 229 source_address_token_future_secs_(3600),
228 source_address_token_lifetime_secs_(86400), 230 source_address_token_lifetime_secs_(86400),
229 server_nonce_strike_register_max_entries_(1 << 10), 231 server_nonce_strike_register_max_entries_(1 << 10),
230 server_nonce_strike_register_window_secs_(120) { 232 server_nonce_strike_register_window_secs_(120) {
233 DCHECK(proof_source_.get());
231 default_source_address_token_boxer_.SetKey( 234 default_source_address_token_boxer_.SetKey(
232 DeriveSourceAddressTokenKey(source_address_token_secret)); 235 DeriveSourceAddressTokenKey(source_address_token_secret));
233 236
234 // Generate a random key and orbit for server nonces. 237 // Generate a random key and orbit for server nonces.
235 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); 238 server_nonce_entropy->RandBytes(server_nonce_orbit_,
239 sizeof(server_nonce_orbit_));
236 const size_t key_size = server_nonce_boxer_.GetKeySize(); 240 const size_t key_size = server_nonce_boxer_.GetKeySize();
237 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); 241 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]);
238 rand->RandBytes(key_bytes.get(), key_size); 242 server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
239 243
240 server_nonce_boxer_.SetKey( 244 server_nonce_boxer_.SetKey(
241 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); 245 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size));
242 } 246 }
243 247
244 QuicCryptoServerConfig::~QuicCryptoServerConfig() { 248 QuicCryptoServerConfig::~QuicCryptoServerConfig() {
245 primary_config_ = nullptr; 249 primary_config_ = nullptr;
246 } 250 }
247 251
248 // static 252 // static
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { 606 if (validate_chlo_result.error_code != QUIC_NO_ERROR) {
603 *error_details = validate_chlo_result.error_details; 607 *error_details = validate_chlo_result.error_details;
604 return validate_chlo_result.error_code; 608 return validate_chlo_result.error_code;
605 } 609 }
606 610
607 out->Clear(); 611 out->Clear();
608 612
609 bool x509_supported = false; 613 bool x509_supported = false;
610 bool x509_ecdsa_supported = false; 614 bool x509_ecdsa_supported = false;
611 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 615 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
612 if (proof_source_.get() && !crypto_proof->certs && 616 DCHECK(proof_source_.get());
617 if (!crypto_proof->certs &&
613 !proof_source_->GetProof(server_ip, info.sni.as_string(), 618 !proof_source_->GetProof(server_ip, info.sni.as_string(),
614 primary_config->serialized, x509_ecdsa_supported, 619 primary_config->serialized, x509_ecdsa_supported,
615 &crypto_proof->certs, 620 &crypto_proof->certs,
616 &crypto_proof->signature)) { 621 &crypto_proof->signature)) {
617 return QUIC_HANDSHAKE_FAILED; 622 return QUIC_HANDSHAKE_FAILED;
618 } 623 }
619 624
620 if (!info.valid_source_address_token || 625 if (!info.valid_source_address_token ||
621 !info.client_nonce_well_formed || 626 !info.client_nonce_well_formed ||
622 !info.unique || 627 !info.unique ||
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), 686 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id),
682 sizeof(connection_id)); 687 sizeof(connection_id));
683 hkdf_suffix.append(client_hello_serialized.data(), 688 hkdf_suffix.append(client_hello_serialized.data(),
684 client_hello_serialized.length()); 689 client_hello_serialized.length());
685 hkdf_suffix.append(requested_config->serialized); 690 hkdf_suffix.append(requested_config->serialized);
686 // The addition of x509_supported in this if statement is so that an insecure 691 // The addition of x509_supported in this if statement is so that an insecure
687 // quic client talking to a secure quic server will not result in the secure 692 // quic client talking to a secure quic server will not result in the secure
688 // quic server adding the cert to the kdf. 693 // quic server adding the cert to the kdf.
689 // TODO(nharper): Should a server that is configured to be secure (i.e. one 694 // TODO(nharper): Should a server that is configured to be secure (i.e. one
690 // that has a proof_source_) be accepting responses from an insecure client? 695 // that has a proof_source_) be accepting responses from an insecure client?
691 if (version > QUIC_VERSION_25 && proof_source_.get() && x509_supported) { 696 DCHECK(proof_source_.get());
697 if (version > QUIC_VERSION_25 && x509_supported) {
692 if (crypto_proof->certs->empty()) { 698 if (crypto_proof->certs->empty()) {
693 *error_details = "Failed to get certs"; 699 *error_details = "Failed to get certs";
694 return QUIC_CRYPTO_INTERNAL_ERROR; 700 return QUIC_CRYPTO_INTERNAL_ERROR;
695 } 701 }
696 hkdf_suffix.append(crypto_proof->certs->at(0)); 702 hkdf_suffix.append(crypto_proof->certs->at(0));
697 } 703 }
698 704
699 StringPiece cetv_ciphertext; 705 StringPiece cetv_ciphertext;
700 if (requested_config->channel_id_enabled && 706 if (requested_config->channel_id_enabled &&
701 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { 707 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 helper.ValidationComplete(QUIC_NO_ERROR, ""); 1016 helper.ValidationComplete(QUIC_NO_ERROR, "");
1011 return; 1017 return;
1012 } 1018 }
1013 found_error = true; 1019 found_error = true;
1014 } 1020 }
1015 1021
1016 if (version > QUIC_VERSION_25) { 1022 if (version > QUIC_VERSION_25) {
1017 bool x509_supported = false; 1023 bool x509_supported = false;
1018 bool x509_ecdsa_supported = false; 1024 bool x509_ecdsa_supported = false;
1019 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 1025 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
1020 if (proof_source_.get() && 1026 if (!proof_source_->GetProof(server_ip, info->sni.as_string(),
1021 !proof_source_->GetProof(server_ip, info->sni.as_string(),
1022 requested_config->serialized, 1027 requested_config->serialized,
1023 x509_ecdsa_supported, &crypto_proof->certs, 1028 x509_ecdsa_supported, &crypto_proof->certs,
1024 &crypto_proof->signature)) { 1029 &crypto_proof->signature)) {
1025 found_error = true; 1030 found_error = true;
1026 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); 1031 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
1027 } 1032 }
1028 1033
1029 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { 1034 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) {
1030 found_error = true; 1035 found_error = true;
1031 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); 1036 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 CryptoHandshakeMessage* out) const { 1127 CryptoHandshakeMessage* out) const {
1123 base::AutoLock locked(configs_lock_); 1128 base::AutoLock locked(configs_lock_);
1124 out->set_tag(kSCUP); 1129 out->set_tag(kSCUP);
1125 out->SetStringPiece(kSCFG, primary_config_->serialized); 1130 out->SetStringPiece(kSCFG, primary_config_->serialized);
1126 out->SetStringPiece( 1131 out->SetStringPiece(
1127 kSourceAddressTokenTag, 1132 kSourceAddressTokenTag,
1128 NewSourceAddressToken(*primary_config_.get(), 1133 NewSourceAddressToken(*primary_config_.get(),
1129 previous_source_address_tokens, client_ip, rand, 1134 previous_source_address_tokens, client_ip, rand,
1130 clock->WallNow(), cached_network_params)); 1135 clock->WallNow(), cached_network_params));
1131 1136
1132 if (proof_source_ == nullptr) {
1133 // Insecure QUIC, can send SCFG without proof.
1134 return true;
1135 }
1136
1137 const vector<string>* certs; 1137 const vector<string>* certs;
1138 string signature; 1138 string signature;
1139 if (!proof_source_->GetProof( 1139 if (!proof_source_->GetProof(
1140 server_ip, params.sni, primary_config_->serialized, 1140 server_ip, params.sni, primary_config_->serialized,
1141 params.x509_ecdsa_supported, &certs, &signature)) { 1141 params.x509_ecdsa_supported, &certs, &signature)) {
1142 DVLOG(1) << "Server: failed to get proof."; 1142 DVLOG(1) << "Server: failed to get proof.";
1143 return false; 1143 return false;
1144 } 1144 }
1145 1145
1146 const string compressed = CertCompressor::CompressChain( 1146 const string compressed = CertCompressor::CompressChain(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 out->SetVector(kRREJ, info.reject_reasons); 1186 out->SetVector(kRREJ, info.reject_reasons);
1187 1187
1188 // The client may have requested a certificate chain. 1188 // The client may have requested a certificate chain.
1189 bool x509_supported = false; 1189 bool x509_supported = false;
1190 ParseProofDemand(client_hello, &x509_supported, 1190 ParseProofDemand(client_hello, &x509_supported,
1191 &params->x509_ecdsa_supported); 1191 &params->x509_ecdsa_supported);
1192 if (!x509_supported) { 1192 if (!x509_supported) {
1193 return; 1193 return;
1194 } 1194 }
1195 1195
1196 if (!proof_source_.get()) {
1197 return;
1198 }
1199
1200 StringPiece client_common_set_hashes; 1196 StringPiece client_common_set_hashes;
1201 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { 1197 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
1202 params->client_common_set_hashes = client_common_set_hashes.as_string(); 1198 params->client_common_set_hashes = client_common_set_hashes.as_string();
1203 } 1199 }
1204 1200
1205 StringPiece client_cached_cert_hashes; 1201 StringPiece client_cached_cert_hashes;
1206 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { 1202 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
1207 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); 1203 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
1208 } 1204 }
1209 1205
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 return nullptr; 1389 return nullptr;
1394 } 1390 }
1395 } 1391 }
1396 1392
1397 config->key_exchanges.push_back(ka.release()); 1393 config->key_exchanges.push_back(ka.release());
1398 } 1394 }
1399 1395
1400 return config; 1396 return config;
1401 } 1397 }
1402 1398
1403 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) {
1404 proof_source_.reset(proof_source);
1405 }
1406
1407 void QuicCryptoServerConfig::SetEphemeralKeySource( 1399 void QuicCryptoServerConfig::SetEphemeralKeySource(
1408 EphemeralKeySource* ephemeral_key_source) { 1400 EphemeralKeySource* ephemeral_key_source) {
1409 ephemeral_key_source_.reset(ephemeral_key_source); 1401 ephemeral_key_source_.reset(ephemeral_key_source);
1410 } 1402 }
1411 1403
1412 void QuicCryptoServerConfig::SetStrikeRegisterClient( 1404 void QuicCryptoServerConfig::SetStrikeRegisterClient(
1413 StrikeRegisterClient* strike_register_client) { 1405 StrikeRegisterClient* strike_register_client) {
1414 base::AutoLock locker(strike_register_client_lock_); 1406 base::AutoLock locker(strike_register_client_lock_);
1415 DCHECK(!strike_register_client_.get()); 1407 DCHECK(!strike_register_client_.get());
1416 strike_register_client_.reset(strike_register_client); 1408 strike_register_client_.reset(strike_register_client);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 continue; 1491 continue;
1500 } 1492 }
1501 1493
1502 *(source_address_tokens.add_tokens()) = token; 1494 *(source_address_tokens.add_tokens()) = token;
1503 } 1495 }
1504 1496
1505 return config.source_address_token_boxer->Box( 1497 return config.source_address_token_boxer->Box(
1506 rand, source_address_tokens.SerializeAsString()); 1498 rand, source_address_tokens.SerializeAsString());
1507 } 1499 }
1508 1500
1509 bool QuicCryptoServerConfig::HasProofSource() const {
1510 return proof_source_ != nullptr;
1511 }
1512
1513 int QuicCryptoServerConfig::NumberOfConfigs() const { 1501 int QuicCryptoServerConfig::NumberOfConfigs() const {
1514 base::AutoLock locked(configs_lock_); 1502 base::AutoLock locked(configs_lock_);
1515 return configs_.size(); 1503 return configs_.size();
1516 } 1504 }
1517 1505
1518 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( 1506 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
1519 const Config& config, 1507 const Config& config,
1520 StringPiece token, 1508 StringPiece token,
1521 SourceAddressTokens* tokens) const { 1509 SourceAddressTokens* tokens) const {
1522 string storage; 1510 string storage;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 case STRIKE_REGISTER_FAILURE: 1660 case STRIKE_REGISTER_FAILURE:
1673 default: 1661 default:
1674 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error; 1662 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error;
1675 return SERVER_NONCE_NOT_UNIQUE_FAILURE; 1663 return SERVER_NONCE_NOT_UNIQUE_FAILURE;
1676 } 1664 }
1677 } 1665 }
1678 1666
1679 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( 1667 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
1680 const CryptoHandshakeMessage& client_hello, 1668 const CryptoHandshakeMessage& client_hello,
1681 const QuicCryptoProof& crypto_proof) const { 1669 const QuicCryptoProof& crypto_proof) const {
1682 // If the server doesn't use https, then the client won't send XLCT and
1683 // proof_source_ will be null, so in this case return true.
1684 if (!proof_source_.get()) {
1685 return true;
1686 }
1687 if (crypto_proof.certs->empty()) { 1670 if (crypto_proof.certs->empty()) {
1688 return false; 1671 return false;
1689 } 1672 }
1690 1673
1691 uint64 hash_from_client; 1674 uint64 hash_from_client;
1692 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { 1675 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
1693 return false; 1676 return false;
1694 } 1677 }
1695 return CryptoUtils::ComputeLeafCertHash(crypto_proof.certs->at(0)) == 1678 return CryptoUtils::ComputeLeafCertHash(crypto_proof.certs->at(0)) ==
1696 hash_from_client; 1679 hash_from_client;
1697 } 1680 }
1698 1681
1699 void QuicCryptoServerConfig::ParseProofDemand( 1682 void QuicCryptoServerConfig::ParseProofDemand(
1700 const CryptoHandshakeMessage& client_hello, 1683 const CryptoHandshakeMessage& client_hello,
1701 bool* x509_supported, 1684 bool* x509_supported,
1702 bool* x509_ecdsa_supported) const { 1685 bool* x509_ecdsa_supported) const {
1703 const QuicTag* their_proof_demands; 1686 const QuicTag* their_proof_demands;
1704 size_t num_their_proof_demands; 1687 size_t num_their_proof_demands;
1705 1688
1706 if (proof_source_.get() == nullptr || 1689 if (client_hello.GetTaglist(kPDMD, &their_proof_demands,
1707 client_hello.GetTaglist(kPDMD, &their_proof_demands,
1708 &num_their_proof_demands) != QUIC_NO_ERROR) { 1690 &num_their_proof_demands) != QUIC_NO_ERROR) {
1709 return; 1691 return;
1710 } 1692 }
1711 1693
1712 *x509_supported = false; 1694 *x509_supported = false;
1713 for (size_t i = 0; i < num_their_proof_demands; i++) { 1695 for (size_t i = 0; i < num_their_proof_demands; i++) {
1714 switch (their_proof_demands[i]) { 1696 switch (their_proof_demands[i]) {
1715 case kX509: 1697 case kX509:
1716 *x509_supported = true; 1698 *x509_supported = true;
1717 *x509_ecdsa_supported = true; 1699 *x509_ecdsa_supported = true;
1718 break; 1700 break;
1719 case kX59R: 1701 case kX59R:
1720 *x509_supported = true; 1702 *x509_supported = true;
1721 break; 1703 break;
1722 } 1704 }
1723 } 1705 }
1724 } 1706 }
1725 1707
1726 QuicCryptoServerConfig::Config::Config() 1708 QuicCryptoServerConfig::Config::Config()
1727 : channel_id_enabled(false), 1709 : channel_id_enabled(false),
1728 is_primary(false), 1710 is_primary(false),
1729 primary_time(QuicWallTime::Zero()), 1711 primary_time(QuicWallTime::Zero()),
1730 priority(0), 1712 priority(0),
1731 source_address_token_boxer(nullptr) {} 1713 source_address_token_boxer(nullptr) {}
1732 1714
1733 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1715 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1734 1716
1735 } // namespace net 1717 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/quic_crypto_server_config.h ('k') | net/quic/crypto/quic_crypto_server_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698