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

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

Issue 1421853006: Landing Recent QUIC changes until: Fri Oct 30 22:23:58 2015 +0000 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix comments 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
« no previous file with comments | « net/quic/crypto/quic_crypto_server_config.h ('k') | net/quic/quic_chromium_client_session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 primary_config_(nullptr), 216 primary_config_(nullptr),
217 next_config_promotion_time_(QuicWallTime::Zero()), 217 next_config_promotion_time_(QuicWallTime::Zero()),
218 server_nonce_strike_register_lock_(), 218 server_nonce_strike_register_lock_(),
219 proof_source_(proof_source), 219 proof_source_(proof_source),
220 strike_register_no_startup_period_(false), 220 strike_register_no_startup_period_(false),
221 strike_register_max_entries_(1 << 10), 221 strike_register_max_entries_(1 << 10),
222 strike_register_window_secs_(600), 222 strike_register_window_secs_(600),
223 source_address_token_future_secs_(3600), 223 source_address_token_future_secs_(3600),
224 source_address_token_lifetime_secs_(86400), 224 source_address_token_lifetime_secs_(86400),
225 server_nonce_strike_register_max_entries_(1 << 10), 225 server_nonce_strike_register_max_entries_(1 << 10),
226 server_nonce_strike_register_window_secs_(120) { 226 server_nonce_strike_register_window_secs_(120),
227 enable_serving_sct_(false) {
227 DCHECK(proof_source_.get()); 228 DCHECK(proof_source_.get());
228 default_source_address_token_boxer_.SetKey( 229 default_source_address_token_boxer_.SetKey(
229 DeriveSourceAddressTokenKey(source_address_token_secret)); 230 DeriveSourceAddressTokenKey(source_address_token_secret));
230 231
231 // Generate a random key and orbit for server nonces. 232 // Generate a random key and orbit for server nonces.
232 server_nonce_entropy->RandBytes(server_nonce_orbit_, 233 server_nonce_entropy->RandBytes(server_nonce_orbit_,
233 sizeof(server_nonce_orbit_)); 234 sizeof(server_nonce_orbit_));
234 const size_t key_size = server_nonce_boxer_.GetKeySize(); 235 const size_t key_size = server_nonce_boxer_.GetKeySize();
235 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]); 236 scoped_ptr<uint8[]> key_bytes(new uint8[key_size]);
236 server_nonce_entropy->RandBytes(key_bytes.get(), key_size); 237 server_nonce_entropy->RandBytes(key_bytes.get(), key_size);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 605
605 out->Clear(); 606 out->Clear();
606 607
607 bool x509_supported = false; 608 bool x509_supported = false;
608 bool x509_ecdsa_supported = false; 609 bool x509_ecdsa_supported = false;
609 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 610 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
610 DCHECK(proof_source_.get()); 611 DCHECK(proof_source_.get());
611 if (!crypto_proof->certs && 612 if (!crypto_proof->certs &&
612 !proof_source_->GetProof(server_ip, info.sni.as_string(), 613 !proof_source_->GetProof(server_ip, info.sni.as_string(),
613 primary_config->serialized, x509_ecdsa_supported, 614 primary_config->serialized, x509_ecdsa_supported,
614 &crypto_proof->certs, 615 &crypto_proof->certs, &crypto_proof->signature,
615 &crypto_proof->signature)) { 616 &crypto_proof->cert_sct)) {
616 return QUIC_HANDSHAKE_FAILED; 617 return QUIC_HANDSHAKE_FAILED;
617 } 618 }
618 619
620 if (version > QUIC_VERSION_29) {
621 StringPiece cert_sct;
622 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) &&
623 cert_sct.empty()) {
624 params->sct_supported_by_client = true;
625 }
626 }
627
619 if (!info.reject_reasons.empty() || !requested_config.get()) { 628 if (!info.reject_reasons.empty() || !requested_config.get()) {
620 BuildRejection(*primary_config, client_hello, info, 629 BuildRejection(version, *primary_config, client_hello, info,
621 validate_chlo_result.cached_network_params, 630 validate_chlo_result.cached_network_params,
622 use_stateless_rejects, server_designated_connection_id, rand, 631 use_stateless_rejects, server_designated_connection_id, rand,
623 params, *crypto_proof, out); 632 params, *crypto_proof, out);
624 return QUIC_NO_ERROR; 633 return QUIC_NO_ERROR;
625 } 634 }
626 635
627 const QuicTag* their_aeads; 636 const QuicTag* their_aeads;
628 const QuicTag* their_key_exchanges; 637 const QuicTag* their_key_exchanges;
629 size_t num_their_aeads, num_their_key_exchanges; 638 size_t num_their_aeads, num_their_key_exchanges;
630 if (client_hello.GetTaglist(kAEAD, &their_aeads, 639 if (client_hello.GetTaglist(kAEAD, &their_aeads,
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 helper.ValidationComplete(QUIC_NO_ERROR, ""); 1016 helper.ValidationComplete(QUIC_NO_ERROR, "");
1008 return; 1017 return;
1009 } 1018 }
1010 found_error = true; 1019 found_error = true;
1011 } 1020 }
1012 1021
1013 if (version > QUIC_VERSION_25) { 1022 if (version > QUIC_VERSION_25) {
1014 bool x509_supported = false; 1023 bool x509_supported = false;
1015 bool x509_ecdsa_supported = false; 1024 bool x509_ecdsa_supported = false;
1016 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); 1025 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported);
1017 if (!proof_source_->GetProof(server_ip, info->sni.as_string(), 1026 if (!proof_source_->GetProof(
1018 requested_config->serialized, 1027 server_ip, info->sni.as_string(), requested_config->serialized,
1019 x509_ecdsa_supported, &crypto_proof->certs, 1028 x509_ecdsa_supported, &crypto_proof->certs,
1020 &crypto_proof->signature)) { 1029 &crypto_proof->signature, &crypto_proof->cert_sct)) {
1021 found_error = true; 1030 found_error = true;
1022 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); 1031 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE);
1023 } 1032 }
1024 1033
1025 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { 1034 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) {
1026 found_error = true; 1035 found_error = true;
1027 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); 1036 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE);
1028 } 1037 }
1029 } 1038 }
1030 1039
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 } 1117 }
1109 1118
1110 strike_register_client->VerifyNonceIsValidAndUnique( 1119 strike_register_client->VerifyNonceIsValidAndUnique(
1111 info->client_nonce, 1120 info->client_nonce,
1112 info->now, 1121 info->now,
1113 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); 1122 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb));
1114 helper.StartedAsyncCallback(); 1123 helper.StartedAsyncCallback();
1115 } 1124 }
1116 1125
1117 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( 1126 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
1127 QuicVersion version,
1118 const SourceAddressTokens& previous_source_address_tokens, 1128 const SourceAddressTokens& previous_source_address_tokens,
1119 const IPAddressNumber& server_ip, 1129 const IPAddressNumber& server_ip,
1120 const IPAddressNumber& client_ip, 1130 const IPAddressNumber& client_ip,
1121 const QuicClock* clock, 1131 const QuicClock* clock,
1122 QuicRandom* rand, 1132 QuicRandom* rand,
1123 const QuicCryptoNegotiatedParameters& params, 1133 const QuicCryptoNegotiatedParameters& params,
1124 const CachedNetworkParameters* cached_network_params, 1134 const CachedNetworkParameters* cached_network_params,
1125 CryptoHandshakeMessage* out) const { 1135 CryptoHandshakeMessage* out) const {
1126 base::AutoLock locked(configs_lock_); 1136 base::AutoLock locked(configs_lock_);
1127 out->set_tag(kSCUP); 1137 out->set_tag(kSCUP);
1128 out->SetStringPiece(kSCFG, primary_config_->serialized); 1138 out->SetStringPiece(kSCFG, primary_config_->serialized);
1129 out->SetStringPiece( 1139 out->SetStringPiece(
1130 kSourceAddressTokenTag, 1140 kSourceAddressTokenTag,
1131 NewSourceAddressToken(*primary_config_.get(), 1141 NewSourceAddressToken(*primary_config_.get(),
1132 previous_source_address_tokens, client_ip, rand, 1142 previous_source_address_tokens, client_ip, rand,
1133 clock->WallNow(), cached_network_params)); 1143 clock->WallNow(), cached_network_params));
1134 1144
1135 const vector<string>* certs; 1145 const vector<string>* certs;
1136 string signature; 1146 string signature;
1147 string cert_sct;
1137 if (!proof_source_->GetProof( 1148 if (!proof_source_->GetProof(
1138 server_ip, params.sni, primary_config_->serialized, 1149 server_ip, params.sni, primary_config_->serialized,
1139 params.x509_ecdsa_supported, &certs, &signature)) { 1150 params.x509_ecdsa_supported, &certs, &signature, &cert_sct)) {
1140 DVLOG(1) << "Server: failed to get proof."; 1151 DVLOG(1) << "Server: failed to get proof.";
1141 return false; 1152 return false;
1142 } 1153 }
1143 1154
1144 const string compressed = CertCompressor::CompressChain( 1155 const string compressed = CertCompressor::CompressChain(
1145 *certs, params.client_common_set_hashes, params.client_cached_cert_hashes, 1156 *certs, params.client_common_set_hashes, params.client_cached_cert_hashes,
1146 primary_config_->common_cert_sets); 1157 primary_config_->common_cert_sets);
1147 1158
1148 out->SetStringPiece(kCertificateTag, compressed); 1159 out->SetStringPiece(kCertificateTag, compressed);
1149 out->SetStringPiece(kPROF, signature); 1160 out->SetStringPiece(kPROF, signature);
1161 if (params.sct_supported_by_client && version > QUIC_VERSION_29 &&
1162 enable_serving_sct_) {
1163 if (cert_sct.empty()) {
1164 DLOG(WARNING) << "SCT is expected but it is empty.";
1165 } else {
1166 out->SetStringPiece(kCertificateSCTTag, cert_sct);
1167 }
1168 }
1150 return true; 1169 return true;
1151 } 1170 }
1152 1171
1153 void QuicCryptoServerConfig::BuildRejection( 1172 void QuicCryptoServerConfig::BuildRejection(
1173 QuicVersion version,
1154 const Config& config, 1174 const Config& config,
1155 const CryptoHandshakeMessage& client_hello, 1175 const CryptoHandshakeMessage& client_hello,
1156 const ClientHelloInfo& info, 1176 const ClientHelloInfo& info,
1157 const CachedNetworkParameters& cached_network_params, 1177 const CachedNetworkParameters& cached_network_params,
1158 bool use_stateless_rejects, 1178 bool use_stateless_rejects,
1159 QuicConnectionId server_designated_connection_id, 1179 QuicConnectionId server_designated_connection_id,
1160 QuicRandom* rand, 1180 QuicRandom* rand,
1161 QuicCryptoNegotiatedParameters* params, 1181 QuicCryptoNegotiatedParameters* params,
1162 const QuicCryptoProof& crypto_proof, 1182 const QuicCryptoProof& crypto_proof,
1163 CryptoHandshakeMessage* out) const { 1183 CryptoHandshakeMessage* out) const {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 // kREJOverheadBytes is a very rough estimate of how much of a REJ 1228 // kREJOverheadBytes is a very rough estimate of how much of a REJ
1209 // message is taken up by things other than the certificates. 1229 // message is taken up by things other than the certificates.
1210 // STK: 56 bytes 1230 // STK: 56 bytes
1211 // SNO: 56 bytes 1231 // SNO: 56 bytes
1212 // SCFG 1232 // SCFG
1213 // SCID: 16 bytes 1233 // SCID: 16 bytes
1214 // PUBS: 38 bytes 1234 // PUBS: 38 bytes
1215 const size_t kREJOverheadBytes = 166; 1235 const size_t kREJOverheadBytes = 166;
1216 // kMultiplier is the multiple of the CHLO message size that a REJ message 1236 // kMultiplier is the multiple of the CHLO message size that a REJ message
1217 // must stay under when the client doesn't present a valid source-address 1237 // must stay under when the client doesn't present a valid source-address
1218 // token. 1238 // token. This is used to protect QUIC from amplification attacks.
1219 const size_t kMultiplier = 2; 1239 const size_t kMultiplier = 2;
1220 // max_unverified_size is the number of bytes that the certificate chain 1240 // max_unverified_size is the number of bytes that the certificate chain,
1221 // and signature can consume before we will demand a valid source-address 1241 // signature, and (optionally) signed certificate timestamp can consume before
1222 // token. 1242 // we will demand a valid source-address token.
1223 const size_t max_unverified_size = 1243 const size_t max_unverified_size =
1224 client_hello.size() * kMultiplier - kREJOverheadBytes; 1244 client_hello.size() * kMultiplier - kREJOverheadBytes;
1225 static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes, 1245 static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes,
1226 "overhead calculation may overflow"); 1246 "overhead calculation may underflow");
1247 bool should_return_sct = params->sct_supported_by_client &&
1248 version > QUIC_VERSION_29 && enable_serving_sct_;
1249 const size_t sct_size = should_return_sct ? crypto_proof.cert_sct.size() : 0;
1227 if (info.valid_source_address_token || 1250 if (info.valid_source_address_token ||
1228 crypto_proof.signature.size() + compressed.size() < max_unverified_size) { 1251 crypto_proof.signature.size() + compressed.size() + sct_size <
1252 max_unverified_size) {
1229 out->SetStringPiece(kCertificateTag, compressed); 1253 out->SetStringPiece(kCertificateTag, compressed);
1230 out->SetStringPiece(kPROF, crypto_proof.signature); 1254 out->SetStringPiece(kPROF, crypto_proof.signature);
1255 if (should_return_sct) {
1256 if (crypto_proof.cert_sct.empty()) {
1257 DLOG(WARNING) << "SCT is expected but it is empty.";
1258 } else {
1259 out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct);
1260 }
1261 }
1231 } 1262 }
1232 } 1263 }
1233 1264
1234 scoped_refptr<QuicCryptoServerConfig::Config> 1265 scoped_refptr<QuicCryptoServerConfig::Config>
1235 QuicCryptoServerConfig::ParseConfigProtobuf( 1266 QuicCryptoServerConfig::ParseConfigProtobuf(
1236 QuicServerConfigProtobuf* protobuf) { 1267 QuicServerConfigProtobuf* protobuf) {
1237 scoped_ptr<CryptoHandshakeMessage> msg( 1268 scoped_ptr<CryptoHandshakeMessage> msg(
1238 CryptoFramer::ParseMessage(protobuf->config())); 1269 CryptoFramer::ParseMessage(protobuf->config()));
1239 1270
1240 if (msg->tag() != kSCFG) { 1271 if (msg->tag() != kSCFG) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 DCHECK(!server_nonce_strike_register_.get()); 1476 DCHECK(!server_nonce_strike_register_.get());
1446 server_nonce_strike_register_max_entries_ = max_entries; 1477 server_nonce_strike_register_max_entries_ = max_entries;
1447 } 1478 }
1448 1479
1449 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs( 1480 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs(
1450 uint32 window_secs) { 1481 uint32 window_secs) {
1451 DCHECK(!server_nonce_strike_register_.get()); 1482 DCHECK(!server_nonce_strike_register_.get());
1452 server_nonce_strike_register_window_secs_ = window_secs; 1483 server_nonce_strike_register_window_secs_ = window_secs;
1453 } 1484 }
1454 1485
1486 void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
1487 enable_serving_sct_ = enable_serving_sct;
1488 }
1489
1455 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( 1490 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
1456 PrimaryConfigChangedCallback* cb) { 1491 PrimaryConfigChangedCallback* cb) {
1457 base::AutoLock locked(configs_lock_); 1492 base::AutoLock locked(configs_lock_);
1458 primary_config_changed_cb_.reset(cb); 1493 primary_config_changed_cb_.reset(cb);
1459 } 1494 }
1460 1495
1461 string QuicCryptoServerConfig::NewSourceAddressToken( 1496 string QuicCryptoServerConfig::NewSourceAddressToken(
1462 const Config& config, 1497 const Config& config,
1463 const SourceAddressTokens& previous_tokens, 1498 const SourceAddressTokens& previous_tokens,
1464 const IPAddressNumber& ip, 1499 const IPAddressNumber& ip,
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 QuicCryptoServerConfig::Config::Config() 1741 QuicCryptoServerConfig::Config::Config()
1707 : channel_id_enabled(false), 1742 : channel_id_enabled(false),
1708 is_primary(false), 1743 is_primary(false),
1709 primary_time(QuicWallTime::Zero()), 1744 primary_time(QuicWallTime::Zero()),
1710 priority(0), 1745 priority(0),
1711 source_address_token_boxer(nullptr) {} 1746 source_address_token_boxer(nullptr) {}
1712 1747
1713 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1748 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1714 1749
1715 } // namespace net 1750 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/quic_crypto_server_config.h ('k') | net/quic/quic_chromium_client_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698