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 |