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/core/crypto/quic_crypto_client_config.h" | 5 #include "net/quic/core/crypto/quic_crypto_client_config.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 SetProofInvalid(); | 185 SetProofInvalid(); |
186 scfg_.reset(new_scfg_storage.release()); | 186 scfg_.reset(new_scfg_storage.release()); |
187 } | 187 } |
188 return SERVER_CONFIG_VALID; | 188 return SERVER_CONFIG_VALID; |
189 } | 189 } |
190 | 190 |
191 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { | 191 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { |
192 server_config_.clear(); | 192 server_config_.clear(); |
193 scfg_.reset(); | 193 scfg_.reset(); |
194 SetProofInvalid(); | 194 SetProofInvalid(); |
195 queue<QuicConnectionId> empty_queue; | 195 std::queue<QuicConnectionId> empty_queue; |
196 swap(server_designated_connection_ids_, empty_queue); | 196 swap(server_designated_connection_ids_, empty_queue); |
197 } | 197 } |
198 | 198 |
199 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, | 199 void QuicCryptoClientConfig::CachedState::SetProof( |
200 StringPiece cert_sct, | 200 const std::vector<string>& certs, |
201 StringPiece chlo_hash, | 201 StringPiece cert_sct, |
202 StringPiece signature) { | 202 StringPiece chlo_hash, |
| 203 StringPiece signature) { |
203 bool has_changed = signature != server_config_sig_ || | 204 bool has_changed = signature != server_config_sig_ || |
204 chlo_hash != chlo_hash_ || certs_.size() != certs.size(); | 205 chlo_hash != chlo_hash_ || certs_.size() != certs.size(); |
205 | 206 |
206 if (!has_changed) { | 207 if (!has_changed) { |
207 for (size_t i = 0; i < certs_.size(); i++) { | 208 for (size_t i = 0; i < certs_.size(); i++) { |
208 if (certs_[i] != certs[i]) { | 209 if (certs_[i] != certs[i]) { |
209 has_changed = true; | 210 has_changed = true; |
210 break; | 211 break; |
211 } | 212 } |
212 } | 213 } |
(...skipping 15 matching lines...) Expand all Loading... |
228 server_config_.clear(); | 229 server_config_.clear(); |
229 source_address_token_.clear(); | 230 source_address_token_.clear(); |
230 certs_.clear(); | 231 certs_.clear(); |
231 cert_sct_.clear(); | 232 cert_sct_.clear(); |
232 chlo_hash_.clear(); | 233 chlo_hash_.clear(); |
233 server_config_sig_.clear(); | 234 server_config_sig_.clear(); |
234 server_config_valid_ = false; | 235 server_config_valid_ = false; |
235 proof_verify_details_.reset(); | 236 proof_verify_details_.reset(); |
236 scfg_.reset(); | 237 scfg_.reset(); |
237 ++generation_counter_; | 238 ++generation_counter_; |
238 queue<QuicConnectionId> empty_queue; | 239 std::queue<QuicConnectionId> empty_queue; |
239 swap(server_designated_connection_ids_, empty_queue); | 240 swap(server_designated_connection_ids_, empty_queue); |
240 } | 241 } |
241 | 242 |
242 void QuicCryptoClientConfig::CachedState::ClearProof() { | 243 void QuicCryptoClientConfig::CachedState::ClearProof() { |
243 SetProofInvalid(); | 244 SetProofInvalid(); |
244 certs_.clear(); | 245 certs_.clear(); |
245 cert_sct_.clear(); | 246 cert_sct_.clear(); |
246 chlo_hash_.clear(); | 247 chlo_hash_.clear(); |
247 server_config_sig_.clear(); | 248 server_config_sig_.clear(); |
248 } | 249 } |
249 | 250 |
250 void QuicCryptoClientConfig::CachedState::SetProofValid() { | 251 void QuicCryptoClientConfig::CachedState::SetProofValid() { |
251 server_config_valid_ = true; | 252 server_config_valid_ = true; |
252 } | 253 } |
253 | 254 |
254 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { | 255 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { |
255 server_config_valid_ = false; | 256 server_config_valid_ = false; |
256 ++generation_counter_; | 257 ++generation_counter_; |
257 } | 258 } |
258 | 259 |
259 bool QuicCryptoClientConfig::CachedState::Initialize( | 260 bool QuicCryptoClientConfig::CachedState::Initialize( |
260 StringPiece server_config, | 261 StringPiece server_config, |
261 StringPiece source_address_token, | 262 StringPiece source_address_token, |
262 const vector<string>& certs, | 263 const std::vector<string>& certs, |
263 StringPiece cert_sct, | 264 const string& cert_sct, |
264 StringPiece chlo_hash, | 265 StringPiece chlo_hash, |
265 StringPiece signature, | 266 StringPiece signature, |
266 QuicWallTime now, | 267 QuicWallTime now, |
267 QuicWallTime expiration_time) { | 268 QuicWallTime expiration_time) { |
268 DCHECK(server_config_.empty()); | 269 DCHECK(server_config_.empty()); |
269 | 270 |
270 if (server_config.empty()) { | 271 if (server_config.empty()) { |
271 RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY); | 272 RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY); |
272 return false; | 273 return false; |
273 } | 274 } |
274 | 275 |
275 string error_details; | 276 string error_details; |
276 ServerConfigState state = | 277 ServerConfigState state = |
277 SetServerConfig(server_config, now, expiration_time, &error_details); | 278 SetServerConfig(server_config, now, expiration_time, &error_details); |
278 RecordDiskCacheServerConfigState(state); | 279 RecordDiskCacheServerConfigState(state); |
279 if (state != SERVER_CONFIG_VALID) { | 280 if (state != SERVER_CONFIG_VALID) { |
280 DVLOG(1) << "SetServerConfig failed with " << error_details; | 281 DVLOG(1) << "SetServerConfig failed with " << error_details; |
281 return false; | 282 return false; |
282 } | 283 } |
283 | 284 |
| 285 chlo_hash.CopyToString(&chlo_hash_); |
284 signature.CopyToString(&server_config_sig_); | 286 signature.CopyToString(&server_config_sig_); |
285 source_address_token.CopyToString(&source_address_token_); | 287 source_address_token.CopyToString(&source_address_token_); |
286 cert_sct.CopyToString(&cert_sct_); | |
287 chlo_hash.CopyToString(&chlo_hash_); | |
288 certs_ = certs; | 288 certs_ = certs; |
| 289 cert_sct_ = cert_sct; |
289 return true; | 290 return true; |
290 } | 291 } |
291 | 292 |
292 const string& QuicCryptoClientConfig::CachedState::server_config() const { | 293 const string& QuicCryptoClientConfig::CachedState::server_config() const { |
293 return server_config_; | 294 return server_config_; |
294 } | 295 } |
295 | 296 |
296 const string& QuicCryptoClientConfig::CachedState::source_address_token() | 297 const string& QuicCryptoClientConfig::CachedState::source_address_token() |
297 const { | 298 const { |
298 return source_address_token_; | 299 return source_address_token_; |
299 } | 300 } |
300 | 301 |
301 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { | 302 const std::vector<string>& QuicCryptoClientConfig::CachedState::certs() const { |
302 return certs_; | 303 return certs_; |
303 } | 304 } |
304 | 305 |
305 const string& QuicCryptoClientConfig::CachedState::cert_sct() const { | 306 const string& QuicCryptoClientConfig::CachedState::cert_sct() const { |
306 return cert_sct_; | 307 return cert_sct_; |
307 } | 308 } |
308 | 309 |
309 const string& QuicCryptoClientConfig::CachedState::chlo_hash() const { | 310 const string& QuicCryptoClientConfig::CachedState::chlo_hash() const { |
310 return chlo_hash_; | 311 return chlo_hash_; |
311 } | 312 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 out->SetStringPiece(kNONP, StringPiece(proof_nonce, arraysize(proof_nonce))); | 462 out->SetStringPiece(kNONP, StringPiece(proof_nonce, arraysize(proof_nonce))); |
462 | 463 |
463 out->SetVector(kPDMD, QuicTagVector{kX509}); | 464 out->SetVector(kPDMD, QuicTagVector{kX509}); |
464 | 465 |
465 if (common_cert_sets) { | 466 if (common_cert_sets) { |
466 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); | 467 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); |
467 } | 468 } |
468 | 469 |
469 out->SetStringPiece(kCertificateSCTTag, ""); | 470 out->SetStringPiece(kCertificateSCTTag, ""); |
470 | 471 |
471 const vector<string>& certs = cached->certs(); | 472 const std::vector<string>& certs = cached->certs(); |
472 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the | 473 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the |
473 // client config is being used for multiple connections, another connection | 474 // client config is being used for multiple connections, another connection |
474 // doesn't update the cached certificates and cause us to be unable to | 475 // doesn't update the cached certificates and cause us to be unable to |
475 // process the server's compressed certificate chain. | 476 // process the server's compressed certificate chain. |
476 out_params->cached_certs = certs; | 477 out_params->cached_certs = certs; |
477 if (!certs.empty()) { | 478 if (!certs.empty()) { |
478 vector<uint64_t> hashes; | 479 std::vector<uint64_t> hashes; |
479 hashes.reserve(certs.size()); | 480 hashes.reserve(certs.size()); |
480 for (vector<string>::const_iterator i = certs.begin(); i != certs.end(); | 481 for (std::vector<string>::const_iterator i = certs.begin(); |
481 ++i) { | 482 i != certs.end(); ++i) { |
482 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); | 483 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); |
483 } | 484 } |
484 out->SetVector(kCCRT, hashes); | 485 out->SetVector(kCCRT, hashes); |
485 } | 486 } |
486 } | 487 } |
487 | 488 |
488 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 489 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
489 const QuicServerId& server_id, | 490 const QuicServerId& server_id, |
490 QuicConnectionId connection_id, | 491 QuicConnectionId connection_id, |
491 const QuicVersion actual_version, | 492 const QuicVersion actual_version, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 return QUIC_CRYPTO_INTERNAL_ERROR; | 606 return QUIC_CRYPTO_INTERNAL_ERROR; |
606 } | 607 } |
607 | 608 |
608 if (!out_params->client_key_exchange->CalculateSharedKey( | 609 if (!out_params->client_key_exchange->CalculateSharedKey( |
609 public_value, &out_params->initial_premaster_secret)) { | 610 public_value, &out_params->initial_premaster_secret)) { |
610 *error_details = "Key exchange failure"; | 611 *error_details = "Key exchange failure"; |
611 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 612 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
612 } | 613 } |
613 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); | 614 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); |
614 | 615 |
615 const vector<string>& certs = cached->certs(); | 616 const std::vector<string>& certs = cached->certs(); |
616 if (certs.empty()) { | 617 if (certs.empty()) { |
617 *error_details = "No certs to calculate XLCT"; | 618 *error_details = "No certs to calculate XLCT"; |
618 return QUIC_CRYPTO_INTERNAL_ERROR; | 619 return QUIC_CRYPTO_INTERNAL_ERROR; |
619 } | 620 } |
620 out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0])); | 621 out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0])); |
621 | 622 |
622 if (channel_id_key) { | 623 if (channel_id_key) { |
623 // In order to calculate the encryption key for the CETV block we need to | 624 // In order to calculate the encryption key for the CETV block we need to |
624 // serialise the client hello as it currently is (i.e. without the CETV | 625 // serialise the client hello as it currently is (i.e. without the CETV |
625 // block). For this, the client hello is serialized without padding. | 626 // block). For this, the client hello is serialized without padding. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 } | 720 } |
720 | 721 |
721 return QUIC_NO_ERROR; | 722 return QUIC_NO_ERROR; |
722 } | 723 } |
723 | 724 |
724 QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( | 725 QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( |
725 const CryptoHandshakeMessage& message, | 726 const CryptoHandshakeMessage& message, |
726 QuicWallTime now, | 727 QuicWallTime now, |
727 QuicVersion version, | 728 QuicVersion version, |
728 StringPiece chlo_hash, | 729 StringPiece chlo_hash, |
729 const vector<string>& cached_certs, | 730 const std::vector<string>& cached_certs, |
730 CachedState* cached, | 731 CachedState* cached, |
731 string* error_details) { | 732 string* error_details) { |
732 DCHECK(error_details != nullptr); | 733 DCHECK(error_details != nullptr); |
733 | 734 |
734 StringPiece scfg; | 735 StringPiece scfg; |
735 if (!message.GetStringPiece(kSCFG, &scfg)) { | 736 if (!message.GetStringPiece(kSCFG, &scfg)) { |
736 *error_details = "Missing SCFG"; | 737 *error_details = "Missing SCFG"; |
737 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 738 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
738 } | 739 } |
739 | 740 |
(...skipping 16 matching lines...) Expand all Loading... |
756 | 757 |
757 StringPiece token; | 758 StringPiece token; |
758 if (message.GetStringPiece(kSourceAddressTokenTag, &token)) { | 759 if (message.GetStringPiece(kSourceAddressTokenTag, &token)) { |
759 cached->set_source_address_token(token); | 760 cached->set_source_address_token(token); |
760 } | 761 } |
761 | 762 |
762 StringPiece proof, cert_bytes, cert_sct; | 763 StringPiece proof, cert_bytes, cert_sct; |
763 bool has_proof = message.GetStringPiece(kPROF, &proof); | 764 bool has_proof = message.GetStringPiece(kPROF, &proof); |
764 bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes); | 765 bool has_cert = message.GetStringPiece(kCertificateTag, &cert_bytes); |
765 if (has_proof && has_cert) { | 766 if (has_proof && has_cert) { |
766 vector<string> certs; | 767 std::vector<string> certs; |
767 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, | 768 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, |
768 common_cert_sets, &certs)) { | 769 common_cert_sets, &certs)) { |
769 *error_details = "Certificate data invalid"; | 770 *error_details = "Certificate data invalid"; |
770 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 771 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
771 } | 772 } |
772 | 773 |
773 message.GetStringPiece(kCertificateSCTTag, &cert_sct); | 774 message.GetStringPiece(kCertificateSCTTag, &cert_sct); |
774 cached->SetProof(certs, cert_sct, chlo_hash, proof); | 775 cached->SetProof(certs, cert_sct, chlo_hash, proof); |
775 } else { | 776 } else { |
776 // Secure QUIC: clear existing proof as we have been sent a new SCFG | 777 // Secure QUIC: clear existing proof as we have been sent a new SCFG |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 } | 989 } |
989 | 990 |
990 // Update canonical version to point at the "most recent" entry. | 991 // Update canonical version to point at the "most recent" entry. |
991 canonical_server_map_[suffix_server_id] = server_id; | 992 canonical_server_map_[suffix_server_id] = server_id; |
992 | 993 |
993 server_state->InitializeFrom(*canonical_state); | 994 server_state->InitializeFrom(*canonical_state); |
994 return true; | 995 return true; |
995 } | 996 } |
996 | 997 |
997 } // namespace net | 998 } // namespace net |
OLD | NEW |