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 |