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

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: enough! Created 5 years, 1 month 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), 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/crypto/quic_crypto_client_config.h ('k') | net/quic/crypto/quic_crypto_client_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698