Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: net/quic/crypto/quic_crypto_client_config.cc

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

Powered by Google App Engine
This is Rietveld 408576698