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

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

Issue 1411063004: Remove insecure QUIC support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: enough! Created 5 years, 1 month 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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 delete this; 202 delete this;
203 } 203 }
204 204
205 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() 205 QuicCryptoServerConfig::ConfigOptions::ConfigOptions()
206 : expiry_time(QuicWallTime::Zero()), 206 : expiry_time(QuicWallTime::Zero()),
207 channel_id_enabled(false), 207 channel_id_enabled(false),
208 p256(false) {} 208 p256(false) {}
209 209
210 QuicCryptoServerConfig::QuicCryptoServerConfig( 210 QuicCryptoServerConfig::QuicCryptoServerConfig(
211 StringPiece source_address_token_secret, 211 StringPiece source_address_token_secret,
212 QuicRandom* rand) 212 QuicRandom* server_nonce_entropy,
213 ProofSource* proof_source)
213 : replay_protection_(true), 214 : replay_protection_(true),
214 configs_lock_(), 215 configs_lock_(),
215 primary_config_(nullptr), 216 primary_config_(nullptr),
216 next_config_promotion_time_(QuicWallTime::Zero()), 217 next_config_promotion_time_(QuicWallTime::Zero()),
217 server_nonce_strike_register_lock_(), 218 server_nonce_strike_register_lock_(),
219 proof_source_(proof_source),
218 strike_register_no_startup_period_(false), 220 strike_register_no_startup_period_(false),
219 strike_register_max_entries_(1 << 10), 221 strike_register_max_entries_(1 << 10),
220 strike_register_window_secs_(600), 222 strike_register_window_secs_(600),
221 source_address_token_future_secs_(3600), 223 source_address_token_future_secs_(3600),
222 source_address_token_lifetime_secs_(86400), 224 source_address_token_lifetime_secs_(86400),
223 server_nonce_strike_register_max_entries_(1 << 10), 225 server_nonce_strike_register_max_entries_(1 << 10),
224 server_nonce_strike_register_window_secs_(120) { 226 server_nonce_strike_register_window_secs_(120) {
227 DCHECK(proof_source_.get());
225 default_source_address_token_boxer_.SetKey( 228 default_source_address_token_boxer_.SetKey(
226 DeriveSourceAddressTokenKey(source_address_token_secret)); 229 DeriveSourceAddressTokenKey(source_address_token_secret));
227 230
228 // Generate a random key and orbit for server nonces. 231 // Generate a random key and orbit for server nonces.
229 rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_)); 232 server_nonce_entropy->RandBytes(server_nonce_orbit_,
233 sizeof(server_nonce_orbit_));
230 const size_t key_size = server_nonce_boxer_.GetKeySize(); 234 const size_t key_size = server_nonce_boxer_.GetKeySize();
231 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); 235 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]);
232 rand->RandBytes(key_bytes.get(), key_size); 236 server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
233 237
234 server_nonce_boxer_.SetKey( 238 server_nonce_boxer_.SetKey(
235 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size)); 239 StringPiece(reinterpret_cast<char*>(key_bytes.get()), key_size));
236 } 240 }
237 241
238 QuicCryptoServerConfig::~QuicCryptoServerConfig() { 242 QuicCryptoServerConfig::~QuicCryptoServerConfig() {
239 primary_config_ = nullptr; 243 primary_config_ = nullptr;
240 } 244 }
241 245
242 // static 246 // static
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 if (validate_chlo_result.error_code != QUIC_NO_ERROR) { 600 if (validate_chlo_result.error_code != QUIC_NO_ERROR) {
597 *error_details = validate_chlo_result.error_details; 601 *error_details = validate_chlo_result.error_details;
598 return validate_chlo_result.error_code; 602 return validate_chlo_result.error_code;
599 } 603 }
600 604
601 out->Clear(); 605 out->Clear();
602 606
603 bool x509_supported = false; 607 bool x509_supported = false;
604 bool x509_ecdsa_supported = false; 608 bool x509_ecdsa_supported = false;
605 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 609 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
606 if (proof_source_.get() && !crypto_proof->certs && 610 DCHECK(proof_source_.get());
611 if (!crypto_proof->certs &&
607 !proof_source_->GetProof(server_ip, info.sni.as_string(), 612 !proof_source_->GetProof(server_ip, info.sni.as_string(),
608 primary_config->serialized, x509_ecdsa_supported, 613 primary_config->serialized, x509_ecdsa_supported,
609 &crypto_proof->certs, 614 &crypto_proof->certs,
610 &crypto_proof->signature)) { 615 &crypto_proof->signature)) {
611 return QUIC_HANDSHAKE_FAILED; 616 return QUIC_HANDSHAKE_FAILED;
612 } 617 }
613 618
614 if (!info.reject_reasons.empty() || !requested_config.get()) { 619 if (!info.reject_reasons.empty() || !requested_config.get()) {
615 BuildRejection(*primary_config, client_hello, info, 620 BuildRejection(*primary_config, client_hello, info,
616 validate_chlo_result.cached_network_params, 621 validate_chlo_result.cached_network_params,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), 677 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id),
673 sizeof(connection_id)); 678 sizeof(connection_id));
674 hkdf_suffix.append(client_hello_serialized.data(), 679 hkdf_suffix.append(client_hello_serialized.data(),
675 client_hello_serialized.length()); 680 client_hello_serialized.length());
676 hkdf_suffix.append(requested_config->serialized); 681 hkdf_suffix.append(requested_config->serialized);
677 // The addition of x509_supported in this if statement is so that an insecure 682 // The addition of x509_supported in this if statement is so that an insecure
678 // quic client talking to a secure quic server will not result in the secure 683 // quic client talking to a secure quic server will not result in the secure
679 // quic server adding the cert to the kdf. 684 // quic server adding the cert to the kdf.
680 // TODO(nharper): Should a server that is configured to be secure (i.e. one 685 // TODO(nharper): Should a server that is configured to be secure (i.e. one
681 // that has a proof_source_) be accepting responses from an insecure client? 686 // that has a proof_source_) be accepting responses from an insecure client?
682 if (version > QUIC_VERSION_25 && proof_source_.get() && x509_supported) { 687 DCHECK(proof_source_.get());
688 if (version > QUIC_VERSION_25 && x509_supported) {
683 if (crypto_proof->certs->empty()) { 689 if (crypto_proof->certs->empty()) {
684 *error_details = "Failed to get certs"; 690 *error_details = "Failed to get certs";
685 return QUIC_CRYPTO_INTERNAL_ERROR; 691 return QUIC_CRYPTO_INTERNAL_ERROR;
686 } 692 }
687 hkdf_suffix.append(crypto_proof->certs->at(0)); 693 hkdf_suffix.append(crypto_proof->certs->at(0));
688 } 694 }
689 695
690 StringPiece cetv_ciphertext; 696 StringPiece cetv_ciphertext;
691 if (requested_config->channel_id_enabled && 697 if (requested_config->channel_id_enabled &&
692 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { 698 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 helper.ValidationComplete(QUIC_NO_ERROR, ""); 1007 helper.ValidationComplete(QUIC_NO_ERROR, "");
1002 return; 1008 return;
1003 } 1009 }
1004 found_error = true; 1010 found_error = true;
1005 } 1011 }
1006 1012
1007 if (version > QUIC_VERSION_25) { 1013 if (version > QUIC_VERSION_25) {
1008 bool x509_supported = false; 1014 bool x509_supported = false;
1009 bool x509_ecdsa_supported = false; 1015 bool x509_ecdsa_supported = false;
1010 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 1016 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
1011 if (proof_source_.get() && 1017 if (!proof_source_->GetProof(server_ip, info->sni.as_string(),
1012 !proof_source_->GetProof(server_ip, info->sni.as_string(),
1013 requested_config->serialized, 1018 requested_config->serialized,
1014 x509_ecdsa_supported, &crypto_proof->certs, 1019 x509_ecdsa_supported, &crypto_proof->certs,
1015 &crypto_proof->signature)) { 1020 &crypto_proof->signature)) {
1016 found_error = true; 1021 found_error = true;
1017 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); 1022 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
1018 } 1023 }
1019 1024
1020 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { 1025 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) {
1021 found_error = true; 1026 found_error = true;
1022 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); 1027 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 CryptoHandshakeMessage* out) const { 1125 CryptoHandshakeMessage* out) const {
1121 base::AutoLock locked(configs_lock_); 1126 base::AutoLock locked(configs_lock_);
1122 out->set_tag(kSCUP); 1127 out->set_tag(kSCUP);
1123 out->SetStringPiece(kSCFG, primary_config_->serialized); 1128 out->SetStringPiece(kSCFG, primary_config_->serialized);
1124 out->SetStringPiece( 1129 out->SetStringPiece(
1125 kSourceAddressTokenTag, 1130 kSourceAddressTokenTag,
1126 NewSourceAddressToken(*primary_config_.get(), 1131 NewSourceAddressToken(*primary_config_.get(),
1127 previous_source_address_tokens, client_ip, rand, 1132 previous_source_address_tokens, client_ip, rand,
1128 clock->WallNow(), cached_network_params)); 1133 clock->WallNow(), cached_network_params));
1129 1134
1130 if (proof_source_ == nullptr) {
1131 // Insecure QUIC, can send SCFG without proof.
1132 return true;
1133 }
1134
1135 const vector<string>* certs; 1135 const vector<string>* certs;
1136 string signature; 1136 string signature;
1137 if (!proof_source_->GetProof( 1137 if (!proof_source_->GetProof(
1138 server_ip, params.sni, primary_config_->serialized, 1138 server_ip, params.sni, primary_config_->serialized,
1139 params.x509_ecdsa_supported, &certs, &signature)) { 1139 params.x509_ecdsa_supported, &certs, &signature)) {
1140 DVLOG(1) << "Server: failed to get proof."; 1140 DVLOG(1) << "Server: failed to get proof.";
1141 return false; 1141 return false;
1142 } 1142 }
1143 1143
1144 const string compressed = CertCompressor::CompressChain( 1144 const string compressed = CertCompressor::CompressChain(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 out->SetVector(kRREJ, info.reject_reasons); 1184 out->SetVector(kRREJ, info.reject_reasons);
1185 1185
1186 // The client may have requested a certificate chain. 1186 // The client may have requested a certificate chain.
1187 bool x509_supported = false; 1187 bool x509_supported = false;
1188 ParseProofDemand(client_hello, &x509_supported, 1188 ParseProofDemand(client_hello, &x509_supported,
1189 &params->x509_ecdsa_supported); 1189 &params->x509_ecdsa_supported);
1190 if (!x509_supported) { 1190 if (!x509_supported) {
1191 return; 1191 return;
1192 } 1192 }
1193 1193
1194 if (!proof_source_.get()) {
1195 return;
1196 }
1197
1198 StringPiece client_common_set_hashes; 1194 StringPiece client_common_set_hashes;
1199 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { 1195 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
1200 params->client_common_set_hashes = client_common_set_hashes.as_string(); 1196 params->client_common_set_hashes = client_common_set_hashes.as_string();
1201 } 1197 }
1202 1198
1203 StringPiece client_cached_cert_hashes; 1199 StringPiece client_cached_cert_hashes;
1204 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { 1200 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
1205 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); 1201 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
1206 } 1202 }
1207 1203
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 return nullptr; 1387 return nullptr;
1392 } 1388 }
1393 } 1389 }
1394 1390
1395 config->key_exchanges.push_back(ka.release()); 1391 config->key_exchanges.push_back(ka.release());
1396 } 1392 }
1397 1393
1398 return config; 1394 return config;
1399 } 1395 }
1400 1396
1401 void QuicCryptoServerConfig::SetProofSource(ProofSource* proof_source) {
1402 proof_source_.reset(proof_source);
1403 }
1404
1405 void QuicCryptoServerConfig::SetEphemeralKeySource( 1397 void QuicCryptoServerConfig::SetEphemeralKeySource(
1406 EphemeralKeySource* ephemeral_key_source) { 1398 EphemeralKeySource* ephemeral_key_source) {
1407 ephemeral_key_source_.reset(ephemeral_key_source); 1399 ephemeral_key_source_.reset(ephemeral_key_source);
1408 } 1400 }
1409 1401
1410 void QuicCryptoServerConfig::SetStrikeRegisterClient( 1402 void QuicCryptoServerConfig::SetStrikeRegisterClient(
1411 StrikeRegisterClient* strike_register_client) { 1403 StrikeRegisterClient* strike_register_client) {
1412 base::AutoLock locker(strike_register_client_lock_); 1404 base::AutoLock locker(strike_register_client_lock_);
1413 DCHECK(!strike_register_client_.get()); 1405 DCHECK(!strike_register_client_.get());
1414 strike_register_client_.reset(strike_register_client); 1406 strike_register_client_.reset(strike_register_client);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 continue; 1489 continue;
1498 } 1490 }
1499 1491
1500 *(source_address_tokens.add_tokens()) = token; 1492 *(source_address_tokens.add_tokens()) = token;
1501 } 1493 }
1502 1494
1503 return config.source_address_token_boxer->Box( 1495 return config.source_address_token_boxer->Box(
1504 rand, source_address_tokens.SerializeAsString()); 1496 rand, source_address_tokens.SerializeAsString());
1505 } 1497 }
1506 1498
1507 bool QuicCryptoServerConfig::HasProofSource() const {
1508 return proof_source_ != nullptr;
1509 }
1510
1511 int QuicCryptoServerConfig::NumberOfConfigs() const { 1499 int QuicCryptoServerConfig::NumberOfConfigs() const {
1512 base::AutoLock locked(configs_lock_); 1500 base::AutoLock locked(configs_lock_);
1513 return configs_.size(); 1501 return configs_.size();
1514 } 1502 }
1515 1503
1516 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken( 1504 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
1517 const Config& config, 1505 const Config& config,
1518 StringPiece token, 1506 StringPiece token,
1519 SourceAddressTokens* tokens) const { 1507 SourceAddressTokens* tokens) const {
1520 string storage; 1508 string storage;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 case STRIKE_REGISTER_FAILURE: 1658 case STRIKE_REGISTER_FAILURE:
1671 default: 1659 default:
1672 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error; 1660 LOG(DFATAL) << "Unexpected server nonce error: " << nonce_error;
1673 return SERVER_NONCE_NOT_UNIQUE_FAILURE; 1661 return SERVER_NONCE_NOT_UNIQUE_FAILURE;
1674 } 1662 }
1675 } 1663 }
1676 1664
1677 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( 1665 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
1678 const CryptoHandshakeMessage& client_hello, 1666 const CryptoHandshakeMessage& client_hello,
1679 const QuicCryptoProof& crypto_proof) const { 1667 const QuicCryptoProof& crypto_proof) const {
1680 // If the server doesn't use https, then the client won't send XLCT and
1681 // proof_source_ will be null, so in this case return true.
1682 if (!proof_source_.get()) {
1683 return true;
1684 }
1685 if (crypto_proof.certs->empty()) { 1668 if (crypto_proof.certs->empty()) {
1686 return false; 1669 return false;
1687 } 1670 }
1688 1671
1689 uint64 hash_from_client; 1672 uint64 hash_from_client;
1690 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { 1673 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
1691 return false; 1674 return false;
1692 } 1675 }
1693 return CryptoUtils::ComputeLeafCertHash(crypto_proof.certs->at(0)) == 1676 return CryptoUtils::ComputeLeafCertHash(crypto_proof.certs->at(0)) ==
1694 hash_from_client; 1677 hash_from_client;
1695 } 1678 }
1696 1679
1697 void QuicCryptoServerConfig::ParseProofDemand( 1680 void QuicCryptoServerConfig::ParseProofDemand(
1698 const CryptoHandshakeMessage& client_hello, 1681 const CryptoHandshakeMessage& client_hello,
1699 bool* x509_supported, 1682 bool* x509_supported,
1700 bool* x509_ecdsa_supported) const { 1683 bool* x509_ecdsa_supported) const {
1701 const QuicTag* their_proof_demands; 1684 const QuicTag* their_proof_demands;
1702 size_t num_their_proof_demands; 1685 size_t num_their_proof_demands;
1703 1686
1704 if (proof_source_.get() == nullptr || 1687 if (client_hello.GetTaglist(kPDMD, &their_proof_demands,
1705 client_hello.GetTaglist(kPDMD, &their_proof_demands,
1706 &num_their_proof_demands) != QUIC_NO_ERROR) { 1688 &num_their_proof_demands) != QUIC_NO_ERROR) {
1707 return; 1689 return;
1708 } 1690 }
1709 1691
1710 *x509_supported = false; 1692 *x509_supported = false;
1711 for (size_t i = 0; i < num_their_proof_demands; i++) { 1693 for (size_t i = 0; i < num_their_proof_demands; i++) {
1712 switch (their_proof_demands[i]) { 1694 switch (their_proof_demands[i]) {
1713 case kX509: 1695 case kX509:
1714 *x509_supported = true; 1696 *x509_supported = true;
1715 *x509_ecdsa_supported = true; 1697 *x509_ecdsa_supported = true;
1716 break; 1698 break;
1717 case kX59R: 1699 case kX59R:
1718 *x509_supported = true; 1700 *x509_supported = true;
1719 break; 1701 break;
1720 } 1702 }
1721 } 1703 }
1722 } 1704 }
1723 1705
1724 QuicCryptoServerConfig::Config::Config() 1706 QuicCryptoServerConfig::Config::Config()
1725 : channel_id_enabled(false), 1707 : channel_id_enabled(false),
1726 is_primary(false), 1708 is_primary(false),
1727 primary_time(QuicWallTime::Zero()), 1709 primary_time(QuicWallTime::Zero()),
1728 priority(0), 1710 priority(0),
1729 source_address_token_boxer(nullptr) {} 1711 source_address_token_boxer(nullptr) {}
1730 1712
1731 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1713 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1732 1714
1733 } // namespace net 1715 } // 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