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/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // Tracks the state of the QUIC server information loaded from the disk cache. | 43 // Tracks the state of the QUIC server information loaded from the disk cache. |
44 void RecordDiskCacheServerConfigState( | 44 void RecordDiskCacheServerConfigState( |
45 QuicCryptoClientConfig::CachedState::ServerConfigState state) { | 45 QuicCryptoClientConfig::CachedState::ServerConfigState state) { |
46 UMA_HISTOGRAM_ENUMERATION( | 46 UMA_HISTOGRAM_ENUMERATION( |
47 "Net.QuicServerInfo.DiskCacheState", state, | 47 "Net.QuicServerInfo.DiskCacheState", state, |
48 QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT); | 48 QuicCryptoClientConfig::CachedState::SERVER_CONFIG_COUNT); |
49 } | 49 } |
50 | 50 |
51 } // namespace | 51 } // namespace |
52 | 52 |
53 QuicCryptoClientConfig::QuicCryptoClientConfig() | 53 QuicCryptoClientConfig::QuicCryptoClientConfig(ProofVerifier* proof_verifier) |
54 : disable_ecdsa_(false) { | 54 : proof_verifier_(proof_verifier), disable_ecdsa_(false) { |
| 55 DCHECK(proof_verifier_.get()); |
55 SetDefaults(); | 56 SetDefaults(); |
56 } | 57 } |
57 | 58 |
58 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 59 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
59 STLDeleteValues(&cached_states_); | 60 STLDeleteValues(&cached_states_); |
60 } | 61 } |
61 | 62 |
62 QuicCryptoClientConfig::CachedState::CachedState() | 63 QuicCryptoClientConfig::CachedState::CachedState() |
63 : server_config_valid_(false), | 64 : server_config_valid_(false), |
64 generation_counter_(0) {} | 65 generation_counter_(0) {} |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); | 402 out->SetValue(kVER, QuicVersionToQuicTag(preferred_version)); |
402 | 403 |
403 if (!user_agent_id_.empty()) { | 404 if (!user_agent_id_.empty()) { |
404 out->SetStringPiece(kUAID, user_agent_id_); | 405 out->SetStringPiece(kUAID, user_agent_id_); |
405 } | 406 } |
406 | 407 |
407 if (!cached->source_address_token().empty()) { | 408 if (!cached->source_address_token().empty()) { |
408 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); | 409 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); |
409 } | 410 } |
410 | 411 |
411 if (server_id.is_https()) { | 412 if (disable_ecdsa_) { |
412 if (disable_ecdsa_) { | 413 out->SetTaglist(kPDMD, kX59R, 0); |
413 out->SetTaglist(kPDMD, kX59R, 0); | 414 } else { |
414 } else { | 415 out->SetTaglist(kPDMD, kX509, 0); |
415 out->SetTaglist(kPDMD, kX509, 0); | |
416 } | |
417 } | 416 } |
418 | 417 |
419 if (common_cert_sets) { | 418 if (common_cert_sets) { |
420 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); | 419 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); |
421 } | 420 } |
422 | 421 |
423 const vector<string>& certs = cached->certs(); | 422 const vector<string>& certs = cached->certs(); |
424 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the | 423 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the |
425 // client config is being used for multiple connections, another connection | 424 // client config is being used for multiple connections, another connection |
426 // doesn't update the cached certificates and cause us to be unable to | 425 // doesn't update the cached certificates and cause us to be unable to |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 } | 532 } |
534 | 533 |
535 if (!out_params->client_key_exchange->CalculateSharedKey( | 534 if (!out_params->client_key_exchange->CalculateSharedKey( |
536 public_value, &out_params->initial_premaster_secret)) { | 535 public_value, &out_params->initial_premaster_secret)) { |
537 *error_details = "Key exchange failure"; | 536 *error_details = "Key exchange failure"; |
538 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 537 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
539 } | 538 } |
540 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); | 539 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); |
541 | 540 |
542 const vector<string>& certs = cached->certs(); | 541 const vector<string>& certs = cached->certs(); |
543 if (preferred_version > QUIC_VERSION_25 && proof_verifier()) { | 542 if (preferred_version > QUIC_VERSION_25) { |
544 if (certs.empty()) { | 543 if (certs.empty()) { |
545 *error_details = "No certs to calculate XLCT"; | 544 *error_details = "No certs to calculate XLCT"; |
546 return QUIC_CRYPTO_INTERNAL_ERROR; | 545 return QUIC_CRYPTO_INTERNAL_ERROR; |
547 } | 546 } |
548 out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0])); | 547 out->SetValue(kXLCT, CryptoUtils::ComputeLeafCertHash(certs[0])); |
549 } | 548 } |
550 | 549 |
551 if (channel_id_key) { | 550 if (channel_id_key) { |
552 // In order to calculate the encryption key for the CETV block we need to | 551 // In order to calculate the encryption key for the CETV block we need to |
553 // serialise the client hello as it currently is (i.e. without the CETV | 552 // serialise the client hello as it currently is (i.e. without the CETV |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 // Set the following members of out_params: | 609 // Set the following members of out_params: |
611 // out_params->hkdf_input_suffix | 610 // out_params->hkdf_input_suffix |
612 // out_params->initial_crypters | 611 // out_params->initial_crypters |
613 out_params->hkdf_input_suffix.clear(); | 612 out_params->hkdf_input_suffix.clear(); |
614 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), | 613 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&connection_id), |
615 sizeof(connection_id)); | 614 sizeof(connection_id)); |
616 const QuicData& client_hello_serialized = out->GetSerialized(); | 615 const QuicData& client_hello_serialized = out->GetSerialized(); |
617 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), | 616 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), |
618 client_hello_serialized.length()); | 617 client_hello_serialized.length()); |
619 out_params->hkdf_input_suffix.append(cached->server_config()); | 618 out_params->hkdf_input_suffix.append(cached->server_config()); |
620 if (preferred_version > QUIC_VERSION_25 && proof_verifier()) { | 619 if (preferred_version > QUIC_VERSION_25) { |
621 if (certs.empty()) { | 620 if (certs.empty()) { |
622 *error_details = "No certs found to include in KDF"; | 621 *error_details = "No certs found to include in KDF"; |
623 return QUIC_CRYPTO_INTERNAL_ERROR; | 622 return QUIC_CRYPTO_INTERNAL_ERROR; |
624 } | 623 } |
625 out_params->hkdf_input_suffix.append(certs[0]); | 624 out_params->hkdf_input_suffix.append(certs[0]); |
626 } | 625 } |
627 | 626 |
628 string hkdf_input; | 627 string hkdf_input; |
629 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 628 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
630 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); | 629 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 if (has_proof && has_cert) { | 678 if (has_proof && has_cert) { |
680 vector<string> certs; | 679 vector<string> certs; |
681 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, | 680 if (!CertCompressor::DecompressChain(cert_bytes, cached_certs, |
682 common_cert_sets, &certs)) { | 681 common_cert_sets, &certs)) { |
683 *error_details = "Certificate data invalid"; | 682 *error_details = "Certificate data invalid"; |
684 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 683 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
685 } | 684 } |
686 | 685 |
687 cached->SetProof(certs, proof); | 686 cached->SetProof(certs, proof); |
688 } else { | 687 } else { |
689 if (proof_verifier() != nullptr) { | 688 // Secure QUIC: clear existing proof as we have been sent a new SCFG |
690 // Secure QUIC: clear existing proof as we have been sent a new SCFG | 689 // without matching proof/certs. |
691 // without matching proof/certs. | 690 cached->ClearProof(); |
692 cached->ClearProof(); | |
693 } | |
694 | 691 |
695 if (has_proof && !has_cert) { | 692 if (has_proof && !has_cert) { |
696 *error_details = "Certificate missing"; | 693 *error_details = "Certificate missing"; |
697 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 694 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
698 } | 695 } |
699 | 696 |
700 if (!has_proof && has_cert) { | 697 if (!has_proof && has_cert) { |
701 *error_details = "Proof missing"; | 698 *error_details = "Proof missing"; |
702 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 699 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
703 } | 700 } |
704 } | 701 } |
705 | 702 |
706 return QUIC_NO_ERROR; | 703 return QUIC_NO_ERROR; |
707 } | 704 } |
708 | 705 |
709 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( | 706 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( |
710 const CryptoHandshakeMessage& rej, | 707 const CryptoHandshakeMessage& rej, |
711 QuicWallTime now, | 708 QuicWallTime now, |
712 CachedState* cached, | 709 CachedState* cached, |
713 bool is_https, | |
714 QuicCryptoNegotiatedParameters* out_params, | 710 QuicCryptoNegotiatedParameters* out_params, |
715 string* error_details) { | 711 string* error_details) { |
716 DCHECK(error_details != nullptr); | 712 DCHECK(error_details != nullptr); |
717 | 713 |
718 if ((rej.tag() != kREJ) && (rej.tag() != kSREJ)) { | 714 if ((rej.tag() != kREJ) && (rej.tag() != kSREJ)) { |
719 *error_details = "Message is not REJ or SREJ"; | 715 *error_details = "Message is not REJ or SREJ"; |
720 return QUIC_CRYPTO_INTERNAL_ERROR; | 716 return QUIC_CRYPTO_INTERNAL_ERROR; |
721 } | 717 } |
722 | 718 |
723 QuicErrorCode error = CacheNewServerConfig(rej, now, out_params->cached_certs, | 719 QuicErrorCode error = CacheNewServerConfig(rej, now, out_params->cached_certs, |
(...skipping 16 matching lines...) Expand all Loading... |
740 for (size_t i = 0; i < num_reject_reasons; ++i) { | 736 for (size_t i = 0; i < num_reject_reasons; ++i) { |
741 // HANDSHAKE_OK is 0 and don't report that as error. | 737 // HANDSHAKE_OK is 0 and don't report that as error. |
742 if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) { | 738 if (reject_reasons[i] == HANDSHAKE_OK || reject_reasons[i] >= 32) { |
743 continue; | 739 continue; |
744 } | 740 } |
745 HandshakeFailureReason reason = | 741 HandshakeFailureReason reason = |
746 static_cast<HandshakeFailureReason>(reject_reasons[i]); | 742 static_cast<HandshakeFailureReason>(reject_reasons[i]); |
747 packed_error |= 1 << (reason - 1); | 743 packed_error |= 1 << (reason - 1); |
748 } | 744 } |
749 DVLOG(1) << "Reasons for rejection: " << packed_error; | 745 DVLOG(1) << "Reasons for rejection: " << packed_error; |
750 if (is_https) { | 746 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure", |
751 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Secure", | 747 packed_error); |
752 packed_error); | |
753 } else { | |
754 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.Insecure", | |
755 packed_error); | |
756 } | |
757 } | 748 } |
758 | 749 |
759 if (rej.tag() == kSREJ) { | 750 if (rej.tag() == kSREJ) { |
760 QuicConnectionId connection_id; | 751 QuicConnectionId connection_id; |
761 if (rej.GetUint64(kRCID, &connection_id) != QUIC_NO_ERROR) { | 752 if (rej.GetUint64(kRCID, &connection_id) != QUIC_NO_ERROR) { |
762 *error_details = "Missing kRCID"; | 753 *error_details = "Missing kRCID"; |
763 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 754 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
764 } | 755 } |
765 cached->add_server_designated_connection_id(connection_id); | 756 cached->add_server_designated_connection_id(connection_id); |
766 if (!nonce.empty()) { | 757 if (!nonce.empty()) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 } | 862 } |
872 | 863 |
873 return CacheNewServerConfig(server_config_update, now, | 864 return CacheNewServerConfig(server_config_update, now, |
874 out_params->cached_certs, cached, error_details); | 865 out_params->cached_certs, cached, error_details); |
875 } | 866 } |
876 | 867 |
877 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { | 868 ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { |
878 return proof_verifier_.get(); | 869 return proof_verifier_.get(); |
879 } | 870 } |
880 | 871 |
881 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { | |
882 proof_verifier_.reset(verifier); | |
883 } | |
884 | |
885 ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const { | 872 ChannelIDSource* QuicCryptoClientConfig::channel_id_source() const { |
886 return channel_id_source_.get(); | 873 return channel_id_source_.get(); |
887 } | 874 } |
888 | 875 |
889 void QuicCryptoClientConfig::SetChannelIDSource(ChannelIDSource* source) { | 876 void QuicCryptoClientConfig::SetChannelIDSource(ChannelIDSource* source) { |
890 channel_id_source_.reset(source); | 877 channel_id_source_.reset(source); |
891 } | 878 } |
892 | 879 |
893 void QuicCryptoClientConfig::InitializeFrom( | 880 void QuicCryptoClientConfig::InitializeFrom( |
894 const QuicServerId& server_id, | 881 const QuicServerId& server_id, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 if (base::EndsWith(server_id.host(), canonical_suffixes_[i], | 919 if (base::EndsWith(server_id.host(), canonical_suffixes_[i], |
933 base::CompareCase::INSENSITIVE_ASCII)) { | 920 base::CompareCase::INSENSITIVE_ASCII)) { |
934 break; | 921 break; |
935 } | 922 } |
936 } | 923 } |
937 if (i == canonical_suffixes_.size()) { | 924 if (i == canonical_suffixes_.size()) { |
938 return false; | 925 return false; |
939 } | 926 } |
940 | 927 |
941 QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(), | 928 QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(), |
942 server_id.is_https(), | |
943 server_id.privacy_mode()); | 929 server_id.privacy_mode()); |
944 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { | 930 if (!ContainsKey(canonical_server_map_, suffix_server_id)) { |
945 // This is the first host we've seen which matches the suffix, so make it | 931 // This is the first host we've seen which matches the suffix, so make it |
946 // canonical. | 932 // canonical. |
947 canonical_server_map_[suffix_server_id] = server_id; | 933 canonical_server_map_[suffix_server_id] = server_id; |
948 return false; | 934 return false; |
949 } | 935 } |
950 | 936 |
951 const QuicServerId& canonical_server_id = | 937 const QuicServerId& canonical_server_id = |
952 canonical_server_map_[suffix_server_id]; | 938 canonical_server_map_[suffix_server_id]; |
953 CachedState* canonical_state = cached_states_[canonical_server_id]; | 939 CachedState* canonical_state = cached_states_[canonical_server_id]; |
954 if (!canonical_state->proof_valid()) { | 940 if (!canonical_state->proof_valid()) { |
955 return false; | 941 return false; |
956 } | 942 } |
957 | 943 |
958 // Update canonical version to point at the "most recent" entry. | 944 // Update canonical version to point at the "most recent" entry. |
959 canonical_server_map_[suffix_server_id] = server_id; | 945 canonical_server_map_[suffix_server_id] = server_id; |
960 | 946 |
961 server_state->InitializeFrom(*canonical_state); | 947 server_state->InitializeFrom(*canonical_state); |
962 return true; | 948 return true; |
963 } | 949 } |
964 | 950 |
965 } // namespace net | 951 } // namespace net |
OLD | NEW |