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

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

Issue 1808793002: Use cached compressed certs if available to reduce load of compressing certs. Flag protected by qui… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 const ValidateClientHelloResultCallback::Result& validate_chlo_result, 547 const ValidateClientHelloResultCallback::Result& validate_chlo_result,
548 QuicConnectionId connection_id, 548 QuicConnectionId connection_id,
549 const IPAddress& server_ip, 549 const IPAddress& server_ip,
550 const IPEndPoint& client_address, 550 const IPEndPoint& client_address,
551 QuicVersion version, 551 QuicVersion version,
552 const QuicVersionVector& supported_versions, 552 const QuicVersionVector& supported_versions,
553 bool use_stateless_rejects, 553 bool use_stateless_rejects,
554 QuicConnectionId server_designated_connection_id, 554 QuicConnectionId server_designated_connection_id,
555 const QuicClock* clock, 555 const QuicClock* clock,
556 QuicRandom* rand, 556 QuicRandom* rand,
557 QuicCompressedCertsCache* compressed_certs_cache,
557 QuicCryptoNegotiatedParameters* params, 558 QuicCryptoNegotiatedParameters* params,
558 QuicCryptoProof* crypto_proof, 559 QuicCryptoProof* crypto_proof,
559 CryptoHandshakeMessage* out, 560 CryptoHandshakeMessage* out,
560 string* error_details) const { 561 string* error_details) const {
561 DCHECK(error_details); 562 DCHECK(error_details);
562 563
563 const CryptoHandshakeMessage& client_hello = 564 const CryptoHandshakeMessage& client_hello =
564 validate_chlo_result.client_hello; 565 validate_chlo_result.client_hello;
565 const ClientHelloInfo& info = validate_chlo_result.info; 566 const ClientHelloInfo& info = validate_chlo_result.info;
566 567
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && 623 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) &&
623 cert_sct.empty()) { 624 cert_sct.empty()) {
624 params->sct_supported_by_client = true; 625 params->sct_supported_by_client = true;
625 } 626 }
626 } 627 }
627 628
628 if (!info.reject_reasons.empty() || !requested_config.get()) { 629 if (!info.reject_reasons.empty() || !requested_config.get()) {
629 BuildRejection(version, *primary_config, client_hello, info, 630 BuildRejection(version, *primary_config, client_hello, info,
630 validate_chlo_result.cached_network_params, 631 validate_chlo_result.cached_network_params,
631 use_stateless_rejects, server_designated_connection_id, rand, 632 use_stateless_rejects, server_designated_connection_id, rand,
632 params, *crypto_proof, out); 633 compressed_certs_cache, params, *crypto_proof, out);
633 return QUIC_NO_ERROR; 634 return QUIC_NO_ERROR;
634 } 635 }
635 636
636 const QuicTag* their_aeads; 637 const QuicTag* their_aeads;
637 const QuicTag* their_key_exchanges; 638 const QuicTag* their_key_exchanges;
638 size_t num_their_aeads, num_their_key_exchanges; 639 size_t num_their_aeads, num_their_key_exchanges;
639 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != 640 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) !=
640 QUIC_NO_ERROR || 641 QUIC_NO_ERROR ||
641 client_hello.GetTaglist(kKEXS, &their_key_exchanges, 642 client_hello.GetTaglist(kKEXS, &their_key_exchanges,
642 &num_their_key_exchanges) != QUIC_NO_ERROR || 643 &num_their_key_exchanges) != QUIC_NO_ERROR ||
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 helper.StartedAsyncCallback(); 1144 helper.StartedAsyncCallback();
1144 } 1145 }
1145 1146
1146 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( 1147 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
1147 QuicVersion version, 1148 QuicVersion version,
1148 const SourceAddressTokens& previous_source_address_tokens, 1149 const SourceAddressTokens& previous_source_address_tokens,
1149 const IPAddress& server_ip, 1150 const IPAddress& server_ip,
1150 const IPAddress& client_ip, 1151 const IPAddress& client_ip,
1151 const QuicClock* clock, 1152 const QuicClock* clock,
1152 QuicRandom* rand, 1153 QuicRandom* rand,
1154 QuicCompressedCertsCache* compressed_certs_cache,
1153 const QuicCryptoNegotiatedParameters& params, 1155 const QuicCryptoNegotiatedParameters& params,
1154 const CachedNetworkParameters* cached_network_params, 1156 const CachedNetworkParameters* cached_network_params,
1155 CryptoHandshakeMessage* out) const { 1157 CryptoHandshakeMessage* out) const {
1156 base::AutoLock locked(configs_lock_); 1158 base::AutoLock locked(configs_lock_);
1157 out->set_tag(kSCUP); 1159 out->set_tag(kSCUP);
1158 out->SetStringPiece(kSCFG, primary_config_->serialized); 1160 out->SetStringPiece(kSCFG, primary_config_->serialized);
1159 out->SetStringPiece( 1161 out->SetStringPiece(
1160 kSourceAddressTokenTag, 1162 kSourceAddressTokenTag,
1161 NewSourceAddressToken(*primary_config_.get(), 1163 NewSourceAddressToken(*primary_config_.get(),
1162 previous_source_address_tokens, client_ip, rand, 1164 previous_source_address_tokens, client_ip, rand,
1163 clock->WallNow(), cached_network_params)); 1165 clock->WallNow(), cached_network_params));
1164 1166
1165 scoped_refptr<ProofSource::Chain> chain; 1167 scoped_refptr<ProofSource::Chain> chain;
1166 string signature; 1168 string signature;
1167 string cert_sct; 1169 string cert_sct;
1168 if (!proof_source_->GetProof(server_ip, params.sni, 1170 if (!proof_source_->GetProof(server_ip, params.sni,
1169 primary_config_->serialized, version, 1171 primary_config_->serialized, version,
1170 params.client_nonce, params.x509_ecdsa_supported, 1172 params.client_nonce, params.x509_ecdsa_supported,
1171 &chain, &signature, &cert_sct)) { 1173 &chain, &signature, &cert_sct)) {
1172 DVLOG(1) << "Server: failed to get proof."; 1174 DVLOG(1) << "Server: failed to get proof.";
1173 return false; 1175 return false;
1174 } 1176 }
1175 1177
1176 const string compressed = CertCompressor::CompressChain( 1178 const string compressed = CompressChain(
1177 chain->certs, params.client_common_set_hashes, 1179 compressed_certs_cache, chain, params.client_common_set_hashes,
1178 params.client_cached_cert_hashes, primary_config_->common_cert_sets); 1180 params.client_cached_cert_hashes, primary_config_->common_cert_sets);
1179 1181
1180 out->SetStringPiece(kCertificateTag, compressed); 1182 out->SetStringPiece(kCertificateTag, compressed);
1181 out->SetStringPiece(kPROF, signature); 1183 out->SetStringPiece(kPROF, signature);
1182 if (params.sct_supported_by_client && version > QUIC_VERSION_29 && 1184 if (params.sct_supported_by_client && version > QUIC_VERSION_29 &&
1183 enable_serving_sct_) { 1185 enable_serving_sct_) {
1184 if (cert_sct.empty()) { 1186 if (cert_sct.empty()) {
1185 DLOG(WARNING) << "SCT is expected but it is empty."; 1187 DLOG(WARNING) << "SCT is expected but it is empty.";
1186 } else { 1188 } else {
1187 out->SetStringPiece(kCertificateSCTTag, cert_sct); 1189 out->SetStringPiece(kCertificateSCTTag, cert_sct);
1188 } 1190 }
1189 } 1191 }
1190 return true; 1192 return true;
1191 } 1193 }
1192 1194
1193 void QuicCryptoServerConfig::BuildRejection( 1195 void QuicCryptoServerConfig::BuildRejection(
1194 QuicVersion version, 1196 QuicVersion version,
1195 const Config& config, 1197 const Config& config,
1196 const CryptoHandshakeMessage& client_hello, 1198 const CryptoHandshakeMessage& client_hello,
1197 const ClientHelloInfo& info, 1199 const ClientHelloInfo& info,
1198 const CachedNetworkParameters& cached_network_params, 1200 const CachedNetworkParameters& cached_network_params,
1199 bool use_stateless_rejects, 1201 bool use_stateless_rejects,
1200 QuicConnectionId server_designated_connection_id, 1202 QuicConnectionId server_designated_connection_id,
1201 QuicRandom* rand, 1203 QuicRandom* rand,
1204 QuicCompressedCertsCache* compressed_certs_cache,
1202 QuicCryptoNegotiatedParameters* params, 1205 QuicCryptoNegotiatedParameters* params,
1203 const QuicCryptoProof& crypto_proof, 1206 const QuicCryptoProof& crypto_proof,
1204 CryptoHandshakeMessage* out) const { 1207 CryptoHandshakeMessage* out) const {
1205 if (FLAGS_enable_quic_stateless_reject_support && use_stateless_rejects) { 1208 if (FLAGS_enable_quic_stateless_reject_support && use_stateless_rejects) {
1206 DVLOG(1) << "QUIC Crypto server config returning stateless reject " 1209 DVLOG(1) << "QUIC Crypto server config returning stateless reject "
1207 << "with server-designated connection ID " 1210 << "with server-designated connection ID "
1208 << server_designated_connection_id; 1211 << server_designated_connection_id;
1209 out->set_tag(kSREJ); 1212 out->set_tag(kSREJ);
1210 out->SetValue(kRCID, server_designated_connection_id); 1213 out->SetValue(kRCID, server_designated_connection_id);
1211 } else { 1214 } else {
(...skipping 23 matching lines...) Expand all
1235 StringPiece client_common_set_hashes; 1238 StringPiece client_common_set_hashes;
1236 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { 1239 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) {
1237 params->client_common_set_hashes = client_common_set_hashes.as_string(); 1240 params->client_common_set_hashes = client_common_set_hashes.as_string();
1238 } 1241 }
1239 1242
1240 StringPiece client_cached_cert_hashes; 1243 StringPiece client_cached_cert_hashes;
1241 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { 1244 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) {
1242 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); 1245 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string();
1243 } 1246 }
1244 1247
1245 const string compressed = CertCompressor::CompressChain( 1248 const string compressed =
1246 crypto_proof.chain->certs, params->client_common_set_hashes, 1249 CompressChain(compressed_certs_cache, crypto_proof.chain,
1247 params->client_cached_cert_hashes, config.common_cert_sets); 1250 params->client_common_set_hashes,
1251 params->client_cached_cert_hashes, config.common_cert_sets);
1248 1252
1249 // kREJOverheadBytes is a very rough estimate of how much of a REJ 1253 // kREJOverheadBytes is a very rough estimate of how much of a REJ
1250 // message is taken up by things other than the certificates. 1254 // message is taken up by things other than the certificates.
1251 // STK: 56 bytes 1255 // STK: 56 bytes
1252 // SNO: 56 bytes 1256 // SNO: 56 bytes
1253 // SCFG 1257 // SCFG
1254 // SCID: 16 bytes 1258 // SCID: 16 bytes
1255 // PUBS: 38 bytes 1259 // PUBS: 38 bytes
1256 const size_t kREJOverheadBytes = 166; 1260 const size_t kREJOverheadBytes = 166;
1257 // max_unverified_size is the number of bytes that the certificate chain, 1261 // max_unverified_size is the number of bytes that the certificate chain,
(...skipping 14 matching lines...) Expand all
1272 if (should_return_sct) { 1276 if (should_return_sct) {
1273 if (crypto_proof.cert_sct.empty()) { 1277 if (crypto_proof.cert_sct.empty()) {
1274 DLOG(WARNING) << "SCT is expected but it is empty."; 1278 DLOG(WARNING) << "SCT is expected but it is empty.";
1275 } else { 1279 } else {
1276 out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct); 1280 out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct);
1277 } 1281 }
1278 } 1282 }
1279 } 1283 }
1280 } 1284 }
1281 1285
1286 const string QuicCryptoServerConfig::CompressChain(
1287 QuicCompressedCertsCache* compressed_certs_cache,
1288 const scoped_refptr<ProofSource::Chain>& chain,
1289 const string& client_common_set_hashes,
1290 const string& client_cached_cert_hashes,
1291 const CommonCertSets* common_sets) const {
1292 // Check whether the compressed certs is available in the cache.
1293 if (FLAGS_quic_use_cached_compressed_certs) {
1294 DCHECK(compressed_certs_cache);
1295 const string* cached_value = compressed_certs_cache->GetCompressedCert(
1296 chain, client_common_set_hashes, client_cached_cert_hashes);
1297 if (cached_value) {
1298 return *cached_value;
1299 }
1300 }
1301
1302 const string compressed =
1303 CertCompressor::CompressChain(chain->certs, client_common_set_hashes,
1304 client_common_set_hashes, common_sets);
1305
1306 // Insert the newly compressed cert to cache.
1307 if (FLAGS_quic_use_cached_compressed_certs) {
1308 compressed_certs_cache->Insert(chain, client_common_set_hashes,
1309 client_cached_cert_hashes, compressed);
1310 }
1311 return compressed;
1312 }
1313
1282 scoped_refptr<QuicCryptoServerConfig::Config> 1314 scoped_refptr<QuicCryptoServerConfig::Config>
1283 QuicCryptoServerConfig::ParseConfigProtobuf( 1315 QuicCryptoServerConfig::ParseConfigProtobuf(
1284 QuicServerConfigProtobuf* protobuf) { 1316 QuicServerConfigProtobuf* protobuf) {
1285 scoped_ptr<CryptoHandshakeMessage> msg( 1317 scoped_ptr<CryptoHandshakeMessage> msg(
1286 CryptoFramer::ParseMessage(protobuf->config())); 1318 CryptoFramer::ParseMessage(protobuf->config()));
1287 1319
1288 if (msg->tag() != kSCFG) { 1320 if (msg->tag() != kSCFG) {
1289 LOG(WARNING) << "Server config message has tag " << msg->tag() 1321 LOG(WARNING) << "Server config message has tag " << msg->tag()
1290 << " expected " << kSCFG; 1322 << " expected " << kSCFG;
1291 return nullptr; 1323 return nullptr;
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 priority(0), 1812 priority(0),
1781 source_address_token_boxer(nullptr) {} 1813 source_address_token_boxer(nullptr) {}
1782 1814
1783 QuicCryptoServerConfig::Config::~Config() { 1815 QuicCryptoServerConfig::Config::~Config() {
1784 STLDeleteElements(&key_exchanges); 1816 STLDeleteElements(&key_exchanges);
1785 } 1817 }
1786 1818
1787 QuicCryptoProof::QuicCryptoProof() {} 1819 QuicCryptoProof::QuicCryptoProof() {}
1788 QuicCryptoProof::~QuicCryptoProof() {} 1820 QuicCryptoProof::~QuicCryptoProof() {}
1789 } // namespace net 1821 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698