| 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/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "net/quic/crypto/cert_compressor.h" | 9 #include "net/quic/crypto/cert_compressor.h" |
| 10 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" | 10 #include "net/quic/crypto/chacha20_poly1305_encrypter.h" |
| 11 #include "net/quic/crypto/channel_id.h" | 11 #include "net/quic/crypto/channel_id.h" |
| 12 #include "net/quic/crypto/common_cert_set.h" | 12 #include "net/quic/crypto/common_cert_set.h" |
| 13 #include "net/quic/crypto/crypto_framer.h" | 13 #include "net/quic/crypto/crypto_framer.h" |
| 14 #include "net/quic/crypto/crypto_utils.h" | 14 #include "net/quic/crypto/crypto_utils.h" |
| 15 #include "net/quic/crypto/curve25519_key_exchange.h" | 15 #include "net/quic/crypto/curve25519_key_exchange.h" |
| 16 #include "net/quic/crypto/key_exchange.h" | 16 #include "net/quic/crypto/key_exchange.h" |
| 17 #include "net/quic/crypto/p256_key_exchange.h" | 17 #include "net/quic/crypto/p256_key_exchange.h" |
| 18 #include "net/quic/crypto/proof_verifier.h" | 18 #include "net/quic/crypto/proof_verifier.h" |
| 19 #include "net/quic/crypto/quic_encrypter.h" | 19 #include "net/quic/crypto/quic_encrypter.h" |
| 20 #include "net/quic/quic_session_key.h" | 20 #include "net/quic/quic_server_id.h" |
| 21 #include "net/quic/quic_utils.h" | 21 #include "net/quic/quic_utils.h" |
| 22 | 22 |
| 23 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
| 24 #include "base/win/windows_version.h" | 24 #include "base/win/windows_version.h" |
| 25 #endif | 25 #endif |
| 26 | 26 |
| 27 using base::StringPiece; | 27 using base::StringPiece; |
| 28 using std::find; | 28 using std::find; |
| 29 using std::make_pair; | 29 using std::make_pair; |
| 30 using std::map; | 30 using std::map; |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 | 254 |
| 255 // Authenticated encryption algorithms. Prefer ChaCha20 by default. | 255 // Authenticated encryption algorithms. Prefer ChaCha20 by default. |
| 256 aead.clear(); | 256 aead.clear(); |
| 257 if (ChaCha20Poly1305Encrypter::IsSupported()) { | 257 if (ChaCha20Poly1305Encrypter::IsSupported()) { |
| 258 aead.push_back(kCC12); | 258 aead.push_back(kCC12); |
| 259 } | 259 } |
| 260 aead.push_back(kAESG); | 260 aead.push_back(kAESG); |
| 261 } | 261 } |
| 262 | 262 |
| 263 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( | 263 QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate( |
| 264 const QuicSessionKey& server_key) { | 264 const QuicServerId& server_id) { |
| 265 CachedStateMap::const_iterator it = cached_states_.find(server_key); | 265 CachedStateMap::const_iterator it = cached_states_.find(server_id); |
| 266 if (it != cached_states_.end()) { | 266 if (it != cached_states_.end()) { |
| 267 return it->second; | 267 return it->second; |
| 268 } | 268 } |
| 269 | 269 |
| 270 CachedState* cached = new CachedState; | 270 CachedState* cached = new CachedState; |
| 271 cached_states_.insert(make_pair(server_key, cached)); | 271 cached_states_.insert(make_pair(server_id, cached)); |
| 272 PopulateFromCanonicalConfig(server_key, cached); | 272 PopulateFromCanonicalConfig(server_id, cached); |
| 273 return cached; | 273 return cached; |
| 274 } | 274 } |
| 275 | 275 |
| 276 void QuicCryptoClientConfig::FillInchoateClientHello( | 276 void QuicCryptoClientConfig::FillInchoateClientHello( |
| 277 const QuicSessionKey& server_key, | 277 const QuicServerId& server_id, |
| 278 const QuicVersion preferred_version, | 278 const QuicVersion preferred_version, |
| 279 const CachedState* cached, | 279 const CachedState* cached, |
| 280 QuicCryptoNegotiatedParameters* out_params, | 280 QuicCryptoNegotiatedParameters* out_params, |
| 281 CryptoHandshakeMessage* out) const { | 281 CryptoHandshakeMessage* out) const { |
| 282 out->set_tag(kCHLO); | 282 out->set_tag(kCHLO); |
| 283 out->set_minimum_size(kClientHelloMinimumSize); | 283 out->set_minimum_size(kClientHelloMinimumSize); |
| 284 | 284 |
| 285 // Server name indication. We only send SNI if it's a valid domain name, as | 285 // Server name indication. We only send SNI if it's a valid domain name, as |
| 286 // per the spec. | 286 // per the spec. |
| 287 if (CryptoUtils::IsValidSNI(server_key.host())) { | 287 if (CryptoUtils::IsValidSNI(server_id.host())) { |
| 288 out->SetStringPiece(kSNI, server_key.host()); | 288 out->SetStringPiece(kSNI, server_id.host()); |
| 289 } | 289 } |
| 290 out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); | 290 out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); |
| 291 | 291 |
| 292 if (!cached->source_address_token().empty()) { | 292 if (!cached->source_address_token().empty()) { |
| 293 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); | 293 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); |
| 294 } | 294 } |
| 295 | 295 |
| 296 if (server_key.is_https()) { | 296 if (server_id.is_https()) { |
| 297 // Don't request ECDSA proofs on platforms that do not support ECDSA | 297 // Don't request ECDSA proofs on platforms that do not support ECDSA |
| 298 // certificates. | 298 // certificates. |
| 299 bool disableECDSA = false; | 299 bool disableECDSA = false; |
| 300 #if defined(OS_WIN) | 300 #if defined(OS_WIN) |
| 301 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 301 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 302 disableECDSA = true; | 302 disableECDSA = true; |
| 303 #endif | 303 #endif |
| 304 if (disableECDSA) { | 304 if (disableECDSA) { |
| 305 out->SetTaglist(kPDMD, kX59R, 0); | 305 out->SetTaglist(kPDMD, kX59R, 0); |
| 306 } else { | 306 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 323 hashes.reserve(certs.size()); | 323 hashes.reserve(certs.size()); |
| 324 for (vector<string>::const_iterator i = certs.begin(); | 324 for (vector<string>::const_iterator i = certs.begin(); |
| 325 i != certs.end(); ++i) { | 325 i != certs.end(); ++i) { |
| 326 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); | 326 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); |
| 327 } | 327 } |
| 328 out->SetVector(kCCRT, hashes); | 328 out->SetVector(kCCRT, hashes); |
| 329 } | 329 } |
| 330 } | 330 } |
| 331 | 331 |
| 332 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 332 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
| 333 const QuicSessionKey& server_key, | 333 const QuicServerId& server_id, |
| 334 QuicConnectionId connection_id, | 334 QuicConnectionId connection_id, |
| 335 const QuicVersion preferred_version, | 335 const QuicVersion preferred_version, |
| 336 uint32 initial_flow_control_window_bytes, | 336 uint32 initial_flow_control_window_bytes, |
| 337 const CachedState* cached, | 337 const CachedState* cached, |
| 338 QuicWallTime now, | 338 QuicWallTime now, |
| 339 QuicRandom* rand, | 339 QuicRandom* rand, |
| 340 QuicCryptoNegotiatedParameters* out_params, | 340 QuicCryptoNegotiatedParameters* out_params, |
| 341 CryptoHandshakeMessage* out, | 341 CryptoHandshakeMessage* out, |
| 342 string* error_details) const { | 342 string* error_details) const { |
| 343 DCHECK(error_details != NULL); | 343 DCHECK(error_details != NULL); |
| 344 | 344 |
| 345 FillInchoateClientHello(server_key, preferred_version, cached, | 345 FillInchoateClientHello(server_id, preferred_version, cached, |
| 346 out_params, out); | 346 out_params, out); |
| 347 | 347 |
| 348 // Set initial receive window for flow control. | 348 // Set initial receive window for flow control. |
| 349 out->SetValue(kIFCW, initial_flow_control_window_bytes); | 349 out->SetValue(kIFCW, initial_flow_control_window_bytes); |
| 350 | 350 |
| 351 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); | 351 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); |
| 352 if (!scfg) { | 352 if (!scfg) { |
| 353 // This should never happen as our caller should have checked | 353 // This should never happen as our caller should have checked |
| 354 // cached->IsComplete() before calling this function. | 354 // cached->IsComplete() before calling this function. |
| 355 *error_details = "Handshake not ready"; | 355 *error_details = "Handshake not ready"; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 const QuicData& client_hello_serialized = out->GetSerialized(); | 463 const QuicData& client_hello_serialized = out->GetSerialized(); |
| 464 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 464 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
| 465 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 465 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
| 466 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 466 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
| 467 sizeof(connection_id)); | 467 sizeof(connection_id)); |
| 468 hkdf_input.append(client_hello_serialized.data(), | 468 hkdf_input.append(client_hello_serialized.data(), |
| 469 client_hello_serialized.length()); | 469 client_hello_serialized.length()); |
| 470 hkdf_input.append(cached->server_config()); | 470 hkdf_input.append(cached->server_config()); |
| 471 | 471 |
| 472 string key, signature; | 472 string key, signature; |
| 473 if (!channel_id_signer_->Sign(server_key.host(), hkdf_input, | 473 if (!channel_id_signer_->Sign(server_id.host(), hkdf_input, |
| 474 &key, &signature)) { | 474 &key, &signature)) { |
| 475 *error_details = "Channel ID signature failed"; | 475 *error_details = "Channel ID signature failed"; |
| 476 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; | 476 return QUIC_INVALID_CHANNEL_ID_SIGNATURE; |
| 477 } | 477 } |
| 478 | 478 |
| 479 cetv.SetStringPiece(kCIDK, key); | 479 cetv.SetStringPiece(kCIDK, key); |
| 480 cetv.SetStringPiece(kCIDS, signature); | 480 cetv.SetStringPiece(kCIDS, signature); |
| 481 | 481 |
| 482 CrypterPair crypters; | 482 CrypterPair crypters; |
| 483 if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, | 483 if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 | 676 |
| 677 ChannelIDSigner* QuicCryptoClientConfig::channel_id_signer() const { | 677 ChannelIDSigner* QuicCryptoClientConfig::channel_id_signer() const { |
| 678 return channel_id_signer_.get(); | 678 return channel_id_signer_.get(); |
| 679 } | 679 } |
| 680 | 680 |
| 681 void QuicCryptoClientConfig::SetChannelIDSigner(ChannelIDSigner* signer) { | 681 void QuicCryptoClientConfig::SetChannelIDSigner(ChannelIDSigner* signer) { |
| 682 channel_id_signer_.reset(signer); | 682 channel_id_signer_.reset(signer); |
| 683 } | 683 } |
| 684 | 684 |
| 685 void QuicCryptoClientConfig::InitializeFrom( | 685 void QuicCryptoClientConfig::InitializeFrom( |
| 686 const QuicSessionKey& server_key, | 686 const QuicServerId& server_id, |
| 687 const QuicSessionKey& canonical_server_key, | 687 const QuicServerId& canonical_server_id, |
| 688 QuicCryptoClientConfig* canonical_crypto_config) { | 688 QuicCryptoClientConfig* canonical_crypto_config) { |
| 689 CachedState* canonical_cached = | 689 CachedState* canonical_cached = |
| 690 canonical_crypto_config->LookupOrCreate(canonical_server_key); | 690 canonical_crypto_config->LookupOrCreate(canonical_server_id); |
| 691 if (!canonical_cached->proof_valid()) { | 691 if (!canonical_cached->proof_valid()) { |
| 692 return; | 692 return; |
| 693 } | 693 } |
| 694 CachedState* cached = LookupOrCreate(server_key); | 694 CachedState* cached = LookupOrCreate(server_id); |
| 695 cached->InitializeFrom(*canonical_cached); | 695 cached->InitializeFrom(*canonical_cached); |
| 696 } | 696 } |
| 697 | 697 |
| 698 void QuicCryptoClientConfig::AddCanonicalSuffix(const string& suffix) { | 698 void QuicCryptoClientConfig::AddCanonicalSuffix(const string& suffix) { |
| 699 canoncial_suffixes_.push_back(suffix); | 699 canoncial_suffixes_.push_back(suffix); |
| 700 } | 700 } |
| 701 | 701 |
| 702 void QuicCryptoClientConfig::PreferAesGcm() { | 702 void QuicCryptoClientConfig::PreferAesGcm() { |
| 703 DCHECK(!aead.empty()); | 703 DCHECK(!aead.empty()); |
| 704 if (aead.size() <= 1) { | 704 if (aead.size() <= 1) { |
| 705 return; | 705 return; |
| 706 } | 706 } |
| 707 QuicTagVector::iterator pos = find(aead.begin(), aead.end(), kAESG); | 707 QuicTagVector::iterator pos = find(aead.begin(), aead.end(), kAESG); |
| 708 if (pos != aead.end()) { | 708 if (pos != aead.end()) { |
| 709 aead.erase(pos); | 709 aead.erase(pos); |
| 710 aead.insert(aead.begin(), kAESG); | 710 aead.insert(aead.begin(), kAESG); |
| 711 } | 711 } |
| 712 } | 712 } |
| 713 | 713 |
| 714 void QuicCryptoClientConfig::PopulateFromCanonicalConfig( | 714 void QuicCryptoClientConfig::PopulateFromCanonicalConfig( |
| 715 const QuicSessionKey& server_key, | 715 const QuicServerId& server_id, |
| 716 CachedState* server_state) { | 716 CachedState* server_state) { |
| 717 DCHECK(server_state->IsEmpty()); | 717 DCHECK(server_state->IsEmpty()); |
| 718 unsigned i = 0; | 718 unsigned i = 0; |
| 719 for (; i < canoncial_suffixes_.size(); ++i) { | 719 for (; i < canoncial_suffixes_.size(); ++i) { |
| 720 if (EndsWith(server_key.host(), canoncial_suffixes_[i], false)) { | 720 if (EndsWith(server_id.host(), canoncial_suffixes_[i], false)) { |
| 721 break; | 721 break; |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 if (i == canoncial_suffixes_.size()) | 724 if (i == canoncial_suffixes_.size()) |
| 725 return; | 725 return; |
| 726 | 726 |
| 727 QuicSessionKey suffix_server_key(canoncial_suffixes_[i], server_key.port(), | 727 QuicServerId suffix_server_id(canoncial_suffixes_[i], server_id.port(), |
| 728 server_key.is_https(), | 728 server_id.is_https(), |
| 729 server_key.privacy_mode()); | 729 server_id.privacy_mode()); |
| 730 if (!ContainsKey(canonical_server_map_, suffix_server_key)) { | 730 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { |
| 731 // This is the first host we've seen which matches the suffix, so make it | 731 // This is the first host we've seen which matches the suffix, so make it |
| 732 // canonical. | 732 // canonical. |
| 733 canonical_server_map_[suffix_server_key] = server_key; | 733 canonical_server_map_[suffix_server_id] = server_id; |
| 734 return; | 734 return; |
| 735 } | 735 } |
| 736 | 736 |
| 737 const QuicSessionKey& canonical_server_key = | 737 const QuicServerId& canonical_server_id = |
| 738 canonical_server_map_[suffix_server_key]; | 738 canonical_server_map_[suffix_server_id]; |
| 739 CachedState* canonical_state = cached_states_[canonical_server_key]; | 739 CachedState* canonical_state = cached_states_[canonical_server_id]; |
| 740 if (!canonical_state->proof_valid()) { | 740 if (!canonical_state->proof_valid()) { |
| 741 return; | 741 return; |
| 742 } | 742 } |
| 743 | 743 |
| 744 // Update canonical version to point at the "most recent" entry. | 744 // Update canonical version to point at the "most recent" entry. |
| 745 canonical_server_map_[suffix_server_key] = server_key; | 745 canonical_server_map_[suffix_server_id] = server_id; |
| 746 | 746 |
| 747 server_state->InitializeFrom(*canonical_state); | 747 server_state->InitializeFrom(*canonical_state); |
| 748 } | 748 } |
| 749 | 749 |
| 750 } // namespace net | 750 } // namespace net |
| OLD | NEW |