| 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_client_config.h" | 5 #include "net/quic/crypto/quic_crypto_client_config.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "net/quic/crypto/cert_compressor.h" | 10 #include "net/quic/crypto/cert_compressor.h" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { | 184 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() { |
| 185 server_config_.clear(); | 185 server_config_.clear(); |
| 186 scfg_.reset(); | 186 scfg_.reset(); |
| 187 SetProofInvalid(); | 187 SetProofInvalid(); |
| 188 queue<QuicConnectionId> empty_queue; | 188 queue<QuicConnectionId> empty_queue; |
| 189 swap(server_designated_connection_ids_, empty_queue); | 189 swap(server_designated_connection_ids_, empty_queue); |
| 190 } | 190 } |
| 191 | 191 |
| 192 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, | 192 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, |
| 193 StringPiece cert_sct, | 193 StringPiece cert_sct, |
| 194 StringPiece chlo_hash, |
| 194 StringPiece signature) { | 195 StringPiece signature) { |
| 195 bool has_changed = | 196 bool has_changed = signature != server_config_sig_ || |
| 196 signature != server_config_sig_ || certs_.size() != certs.size(); | 197 chlo_hash != chlo_hash_ || certs_.size() != certs.size(); |
| 197 | 198 |
| 198 if (!has_changed) { | 199 if (!has_changed) { |
| 199 for (size_t i = 0; i < certs_.size(); i++) { | 200 for (size_t i = 0; i < certs_.size(); i++) { |
| 200 if (certs_[i] != certs[i]) { | 201 if (certs_[i] != certs[i]) { |
| 201 has_changed = true; | 202 has_changed = true; |
| 202 break; | 203 break; |
| 203 } | 204 } |
| 204 } | 205 } |
| 205 } | 206 } |
| 206 | 207 |
| 207 if (!has_changed) { | 208 if (!has_changed) { |
| 208 return; | 209 return; |
| 209 } | 210 } |
| 210 | 211 |
| 211 // If the proof has changed then it needs to be revalidated. | 212 // If the proof has changed then it needs to be revalidated. |
| 212 SetProofInvalid(); | 213 SetProofInvalid(); |
| 213 certs_ = certs; | 214 certs_ = certs; |
| 214 cert_sct_ = cert_sct.as_string(); | 215 cert_sct_ = cert_sct.as_string(); |
| 216 chlo_hash_ = chlo_hash.as_string(); |
| 215 server_config_sig_ = signature.as_string(); | 217 server_config_sig_ = signature.as_string(); |
| 216 } | 218 } |
| 217 | 219 |
| 218 void QuicCryptoClientConfig::CachedState::Clear() { | 220 void QuicCryptoClientConfig::CachedState::Clear() { |
| 219 server_config_.clear(); | 221 server_config_.clear(); |
| 220 source_address_token_.clear(); | 222 source_address_token_.clear(); |
| 221 certs_.clear(); | 223 certs_.clear(); |
| 222 cert_sct_.clear(); | 224 cert_sct_.clear(); |
| 225 chlo_hash_.clear(); |
| 223 server_config_sig_.clear(); | 226 server_config_sig_.clear(); |
| 224 server_config_valid_ = false; | 227 server_config_valid_ = false; |
| 225 proof_verify_details_.reset(); | 228 proof_verify_details_.reset(); |
| 226 scfg_.reset(); | 229 scfg_.reset(); |
| 227 ++generation_counter_; | 230 ++generation_counter_; |
| 228 queue<QuicConnectionId> empty_queue; | 231 queue<QuicConnectionId> empty_queue; |
| 229 swap(server_designated_connection_ids_, empty_queue); | 232 swap(server_designated_connection_ids_, empty_queue); |
| 230 } | 233 } |
| 231 | 234 |
| 232 void QuicCryptoClientConfig::CachedState::ClearProof() { | 235 void QuicCryptoClientConfig::CachedState::ClearProof() { |
| 233 SetProofInvalid(); | 236 SetProofInvalid(); |
| 234 certs_.clear(); | 237 certs_.clear(); |
| 235 cert_sct_.clear(); | 238 cert_sct_.clear(); |
| 239 chlo_hash_.clear(); |
| 236 server_config_sig_.clear(); | 240 server_config_sig_.clear(); |
| 237 } | 241 } |
| 238 | 242 |
| 239 void QuicCryptoClientConfig::CachedState::SetProofValid() { | 243 void QuicCryptoClientConfig::CachedState::SetProofValid() { |
| 240 server_config_valid_ = true; | 244 server_config_valid_ = true; |
| 241 } | 245 } |
| 242 | 246 |
| 243 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { | 247 void QuicCryptoClientConfig::CachedState::SetProofInvalid() { |
| 244 server_config_valid_ = false; | 248 server_config_valid_ = false; |
| 245 ++generation_counter_; | 249 ++generation_counter_; |
| 246 } | 250 } |
| 247 | 251 |
| 248 bool QuicCryptoClientConfig::CachedState::Initialize( | 252 bool QuicCryptoClientConfig::CachedState::Initialize( |
| 249 StringPiece server_config, | 253 StringPiece server_config, |
| 250 StringPiece source_address_token, | 254 StringPiece source_address_token, |
| 251 const vector<string>& certs, | 255 const vector<string>& certs, |
| 252 const string& cert_sct, | 256 const string& cert_sct, |
| 257 StringPiece chlo_hash, |
| 253 StringPiece signature, | 258 StringPiece signature, |
| 254 QuicWallTime now) { | 259 QuicWallTime now) { |
| 255 DCHECK(server_config_.empty()); | 260 DCHECK(server_config_.empty()); |
| 256 | 261 |
| 257 if (server_config.empty()) { | 262 if (server_config.empty()) { |
| 258 RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY); | 263 RecordDiskCacheServerConfigState(SERVER_CONFIG_EMPTY); |
| 259 return false; | 264 return false; |
| 260 } | 265 } |
| 261 | 266 |
| 262 string error_details; | 267 string error_details; |
| 263 ServerConfigState state = SetServerConfig(server_config, now, &error_details); | 268 ServerConfigState state = SetServerConfig(server_config, now, &error_details); |
| 264 RecordDiskCacheServerConfigState(state); | 269 RecordDiskCacheServerConfigState(state); |
| 265 if (state != SERVER_CONFIG_VALID) { | 270 if (state != SERVER_CONFIG_VALID) { |
| 266 DVLOG(1) << "SetServerConfig failed with " << error_details; | 271 DVLOG(1) << "SetServerConfig failed with " << error_details; |
| 267 return false; | 272 return false; |
| 268 } | 273 } |
| 269 | 274 |
| 275 chlo_hash.CopyToString(&chlo_hash_); |
| 270 signature.CopyToString(&server_config_sig_); | 276 signature.CopyToString(&server_config_sig_); |
| 271 source_address_token.CopyToString(&source_address_token_); | 277 source_address_token.CopyToString(&source_address_token_); |
| 272 certs_ = certs; | 278 certs_ = certs; |
| 273 cert_sct_ = cert_sct; | 279 cert_sct_ = cert_sct; |
| 274 return true; | 280 return true; |
| 275 } | 281 } |
| 276 | 282 |
| 277 const string& QuicCryptoClientConfig::CachedState::server_config() const { | 283 const string& QuicCryptoClientConfig::CachedState::server_config() const { |
| 278 return server_config_; | 284 return server_config_; |
| 279 } | 285 } |
| 280 | 286 |
| 281 const string& QuicCryptoClientConfig::CachedState::source_address_token() | 287 const string& QuicCryptoClientConfig::CachedState::source_address_token() |
| 282 const { | 288 const { |
| 283 return source_address_token_; | 289 return source_address_token_; |
| 284 } | 290 } |
| 285 | 291 |
| 286 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { | 292 const vector<string>& QuicCryptoClientConfig::CachedState::certs() const { |
| 287 return certs_; | 293 return certs_; |
| 288 } | 294 } |
| 289 | 295 |
| 290 const string& QuicCryptoClientConfig::CachedState::cert_sct() const { | 296 const string& QuicCryptoClientConfig::CachedState::cert_sct() const { |
| 291 return cert_sct_; | 297 return cert_sct_; |
| 292 } | 298 } |
| 293 | 299 |
| 300 const string& QuicCryptoClientConfig::CachedState::chlo_hash() const { |
| 301 return chlo_hash_; |
| 302 } |
| 303 |
| 294 const string& QuicCryptoClientConfig::CachedState::signature() const { | 304 const string& QuicCryptoClientConfig::CachedState::signature() const { |
| 295 return server_config_sig_; | 305 return server_config_sig_; |
| 296 } | 306 } |
| 297 | 307 |
| 298 bool QuicCryptoClientConfig::CachedState::proof_valid() const { | 308 bool QuicCryptoClientConfig::CachedState::proof_valid() const { |
| 299 return server_config_valid_; | 309 return server_config_valid_; |
| 300 } | 310 } |
| 301 | 311 |
| 302 uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const { | 312 uint64_t QuicCryptoClientConfig::CachedState::generation_counter() const { |
| 303 return generation_counter_; | 313 return generation_counter_; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 323 } | 333 } |
| 324 | 334 |
| 325 void QuicCryptoClientConfig::CachedState::InitializeFrom( | 335 void QuicCryptoClientConfig::CachedState::InitializeFrom( |
| 326 const QuicCryptoClientConfig::CachedState& other) { | 336 const QuicCryptoClientConfig::CachedState& other) { |
| 327 DCHECK(server_config_.empty()); | 337 DCHECK(server_config_.empty()); |
| 328 DCHECK(!server_config_valid_); | 338 DCHECK(!server_config_valid_); |
| 329 server_config_ = other.server_config_; | 339 server_config_ = other.server_config_; |
| 330 source_address_token_ = other.source_address_token_; | 340 source_address_token_ = other.source_address_token_; |
| 331 certs_ = other.certs_; | 341 certs_ = other.certs_; |
| 332 cert_sct_ = other.cert_sct_; | 342 cert_sct_ = other.cert_sct_; |
| 343 chlo_hash_ = other.chlo_hash_; |
| 333 server_config_sig_ = other.server_config_sig_; | 344 server_config_sig_ = other.server_config_sig_; |
| 334 server_config_valid_ = other.server_config_valid_; | 345 server_config_valid_ = other.server_config_valid_; |
| 335 server_designated_connection_ids_ = other.server_designated_connection_ids_; | 346 server_designated_connection_ids_ = other.server_designated_connection_ids_; |
| 336 if (other.proof_verify_details_.get() != nullptr) { | 347 if (other.proof_verify_details_.get() != nullptr) { |
| 337 proof_verify_details_.reset(other.proof_verify_details_->Clone()); | 348 proof_verify_details_.reset(other.proof_verify_details_->Clone()); |
| 338 } | 349 } |
| 339 ++generation_counter_; | 350 ++generation_counter_; |
| 340 } | 351 } |
| 341 | 352 |
| 342 QuicConnectionId | 353 QuicConnectionId |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 *error_details = "Symmetric key setup failed"; | 713 *error_details = "Symmetric key setup failed"; |
| 703 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 714 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
| 704 } | 715 } |
| 705 | 716 |
| 706 return QUIC_NO_ERROR; | 717 return QUIC_NO_ERROR; |
| 707 } | 718 } |
| 708 | 719 |
| 709 QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( | 720 QuicErrorCode QuicCryptoClientConfig::CacheNewServerConfig( |
| 710 const CryptoHandshakeMessage& message, | 721 const CryptoHandshakeMessage& message, |
| 711 QuicWallTime now, | 722 QuicWallTime now, |
| 712 const QuicVersion version, | 723 QuicVersion version, |
| 724 StringPiece chlo_hash, |
| 713 const vector<string>& cached_certs, | 725 const vector<string>& cached_certs, |
| 714 CachedState* cached, | 726 CachedState* cached, |
| 715 string* error_details) { | 727 string* error_details) { |
| 716 DCHECK(error_details != nullptr); | 728 DCHECK(error_details != nullptr); |
| 717 | 729 |
| 718 StringPiece scfg; | 730 StringPiece scfg; |
| 719 if (!message.GetStringPiece(kSCFG, &scfg)) { | 731 if (!message.GetStringPiece(kSCFG, &scfg)) { |
| 720 *error_details = "Missing SCFG"; | 732 *error_details = "Missing SCFG"; |
| 721 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 733 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
| 722 } | 734 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 744 vector<string> certs; | 756 vector<string> certs; |
| 745 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, | 757 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, |
| 746 common_cert_sets, &certs)) { | 758 common_cert_sets, &certs)) { |
| 747 *error_details = "Certificate data invalid"; | 759 *error_details = "Certificate data invalid"; |
| 748 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 760 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 749 } | 761 } |
| 750 | 762 |
| 751 if (version > QUIC_VERSION_29) { | 763 if (version > QUIC_VERSION_29) { |
| 752 message.GetStringPiece(kCertificateSCTTag, &cert_sct); | 764 message.GetStringPiece(kCertificateSCTTag, &cert_sct); |
| 753 } | 765 } |
| 754 cached->SetProof(certs, cert_sct, proof); | 766 cached->SetProof(certs, cert_sct, chlo_hash, proof); |
| 755 } else { | 767 } else { |
| 756 // Secure QUIC: clear existing proof as we have been sent a new SCFG | 768 // Secure QUIC: clear existing proof as we have been sent a new SCFG |
| 757 // without matching proof/certs. | 769 // without matching proof/certs. |
| 758 cached->ClearProof(); | 770 cached->ClearProof(); |
| 759 | 771 |
| 760 if (has_proof && !has_cert) { | 772 if (has_proof && !has_cert) { |
| 761 *error_details = "Certificate missing"; | 773 *error_details = "Certificate missing"; |
| 762 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 774 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 763 } | 775 } |
| 764 | 776 |
| 765 if (!has_proof && has_cert) { | 777 if (!has_proof && has_cert) { |
| 766 *error_details = "Proof missing"; | 778 *error_details = "Proof missing"; |
| 767 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 779 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
| 768 } | 780 } |
| 769 } | 781 } |
| 770 | 782 |
| 771 return QUIC_NO_ERROR; | 783 return QUIC_NO_ERROR; |
| 772 } | 784 } |
| 773 | 785 |
| 774 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( | 786 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( |
| 775 const CryptoHandshakeMessage& rej, | 787 const CryptoHandshakeMessage& rej, |
| 776 QuicWallTime now, | 788 QuicWallTime now, |
| 777 const QuicVersion version, | 789 const QuicVersion version, |
| 790 StringPiece chlo_hash, |
| 778 CachedState* cached, | 791 CachedState* cached, |
| 779 QuicCryptoNegotiatedParameters* out_params, | 792 QuicCryptoNegotiatedParameters* out_params, |
| 780 string* error_details) { | 793 string* error_details) { |
| 781 DCHECK(error_details != nullptr); | 794 DCHECK(error_details != nullptr); |
| 782 | 795 |
| 783 if ((rej.tag() != kREJ) && (rej.tag() != kSREJ)) { | 796 if ((rej.tag() != kREJ) && (rej.tag() != kSREJ)) { |
| 784 *error_details = "Message is not REJ or SREJ"; | 797 *error_details = "Message is not REJ or SREJ"; |
| 785 return QUIC_CRYPTO_INTERNAL_ERROR; | 798 return QUIC_CRYPTO_INTERNAL_ERROR; |
| 786 } | 799 } |
| 787 | 800 |
| 788 QuicErrorCode error = CacheNewServerConfig( | 801 QuicErrorCode error = |
| 789 rej, now, version, out_params->cached_certs, cached, error_details); | 802 CacheNewServerConfig(rej, now, version, chlo_hash, |
| 803 out_params->cached_certs, cached, error_details); |
| 790 if (error != QUIC_NO_ERROR) { | 804 if (error != QUIC_NO_ERROR) { |
| 791 return error; | 805 return error; |
| 792 } | 806 } |
| 793 | 807 |
| 794 StringPiece nonce; | 808 StringPiece nonce; |
| 795 if (rej.GetStringPiece(kServerNonceTag, &nonce)) { | 809 if (rej.GetStringPiece(kServerNonceTag, &nonce)) { |
| 796 out_params->server_nonce = nonce.as_string(); | 810 out_params->server_nonce = nonce.as_string(); |
| 797 } | 811 } |
| 798 | 812 |
| 799 if (rej.tag() == kSREJ) { | 813 if (rej.tag() == kSREJ) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 886 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; |
| 873 } | 887 } |
| 874 | 888 |
| 875 return QUIC_NO_ERROR; | 889 return QUIC_NO_ERROR; |
| 876 } | 890 } |
| 877 | 891 |
| 878 QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate( | 892 QuicErrorCode QuicCryptoClientConfig::ProcessServerConfigUpdate( |
| 879 const CryptoHandshakeMessage& server_config_update, | 893 const CryptoHandshakeMessage& server_config_update, |
| 880 QuicWallTime now, | 894 QuicWallTime now, |
| 881 const QuicVersion version, | 895 const QuicVersion version, |
| 896 StringPiece chlo_hash, |
| 882 CachedState* cached, | 897 CachedState* cached, |
| 883 QuicCryptoNegotiatedParameters* out_params, | 898 QuicCryptoNegotiatedParameters* out_params, |
| 884 string* error_details) { | 899 string* error_details) { |
| 885 DCHECK(error_details != nullptr); | 900 DCHECK(error_details != nullptr); |
| 886 | 901 |
| 887 if (server_config_update.tag() != kSCUP) { | 902 if (server_config_update.tag() != kSCUP) { |
| 888 *error_details = "ServerConfigUpdate must have kSCUP tag."; | 903 *error_details = "ServerConfigUpdate must have kSCUP tag."; |
| 889 return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; | 904 return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; |
| 890 } | 905 } |
| 891 return CacheNewServerConfig(server_config_update, now, version, | 906 return CacheNewServerConfig(server_config_update, now, version, chlo_hash, |
| 892 out_params->cached_certs, cached, error_details); | 907 out_params->cached_certs, cached, error_details); |
| 893 } | 908 } |
| 894 | 909 |
| 895 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { | 910 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { |
| 896 return proof_verifier_.get(); | 911 return proof_verifier_.get(); |
| 897 } | 912 } |
| 898 | 913 |
| 899 ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const { | 914 ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const { |
| 900 return channel_id_source_.get(); | 915 return channel_id_source_.get(); |
| 901 } | 916 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 } | 984 } |
| 970 | 985 |
| 971 // Update canonical version to point at the "most recent" entry. | 986 // Update canonical version to point at the "most recent" entry. |
| 972 canonical_server_map_[suffix_server_id] = server_id; | 987 canonical_server_map_[suffix_server_id] = server_id; |
| 973 | 988 |
| 974 server_state->InitializeFrom(*canonical_state); | 989 server_state->InitializeFrom(*canonical_state); |
| 975 return true; | 990 return true; |
| 976 } | 991 } |
| 977 | 992 |
| 978 } // namespace net | 993 } // namespace net |
| OLD | NEW |