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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |