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/core/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/core/crypto/quic_crypto_server_config.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 : client_hello(in_client_hello), | 196 : client_hello(in_client_hello), |
197 info(in_client_ip, in_now), | 197 info(in_client_ip, in_now), |
198 error_code(QUIC_NO_ERROR) {} | 198 error_code(QUIC_NO_ERROR) {} |
199 | 199 |
200 ValidateClientHelloResultCallback::Result::~Result() {} | 200 ValidateClientHelloResultCallback::Result::~Result() {} |
201 | 201 |
202 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {} | 202 ValidateClientHelloResultCallback::ValidateClientHelloResultCallback() {} |
203 | 203 |
204 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {} | 204 ValidateClientHelloResultCallback::~ValidateClientHelloResultCallback() {} |
205 | 205 |
| 206 ProcessClientHelloResultCallback::ProcessClientHelloResultCallback() {} |
| 207 |
| 208 ProcessClientHelloResultCallback::~ProcessClientHelloResultCallback() {} |
| 209 |
206 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() | 210 QuicCryptoServerConfig::ConfigOptions::ConfigOptions() |
207 : expiry_time(QuicWallTime::Zero()), | 211 : expiry_time(QuicWallTime::Zero()), |
208 channel_id_enabled(false), | 212 channel_id_enabled(false), |
209 p256(false) {} | 213 p256(false) {} |
210 | 214 |
211 QuicCryptoServerConfig::ConfigOptions::ConfigOptions( | 215 QuicCryptoServerConfig::ConfigOptions::ConfigOptions( |
212 const ConfigOptions& other) = default; | 216 const ConfigOptions& other) = default; |
213 | 217 |
214 QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {} | 218 QuicCryptoServerConfig::ConfigOptions::~ConfigOptions() {} |
215 | 219 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 crypto_proof->cert_sct = ""; | 549 crypto_proof->cert_sct = ""; |
546 } | 550 } |
547 EvaluateClientHello(server_ip, version, primary_orbit, requested_config, | 551 EvaluateClientHello(server_ip, version, primary_orbit, requested_config, |
548 primary_config, crypto_proof, result, | 552 primary_config, crypto_proof, result, |
549 std::move(done_cb)); | 553 std::move(done_cb)); |
550 } else { | 554 } else { |
551 done_cb->Run(result, /* details = */ nullptr); | 555 done_cb->Run(result, /* details = */ nullptr); |
552 } | 556 } |
553 } | 557 } |
554 | 558 |
555 QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( | 559 class ProcessClientHelloHelper { |
| 560 public: |
| 561 explicit ProcessClientHelloHelper( |
| 562 std::unique_ptr<ProcessClientHelloResultCallback>* done_cb) |
| 563 : done_cb_(done_cb) {} |
| 564 |
| 565 ~ProcessClientHelloHelper() { |
| 566 QUIC_BUG_IF(done_cb_ != nullptr) |
| 567 << "Deleting ProcessClientHelloHelper with a pending callback."; |
| 568 } |
| 569 |
| 570 void Fail(QuicErrorCode error, const string& error_details) { |
| 571 (*done_cb_)->Run(error, error_details, nullptr, nullptr); |
| 572 DetachCallback(); |
| 573 } |
| 574 |
| 575 void Succeed(std::unique_ptr<CryptoHandshakeMessage> message, |
| 576 std::unique_ptr<DiversificationNonce> diversification_nonce) { |
| 577 (*done_cb_)->Run(QUIC_NO_ERROR, string(), std::move(message), |
| 578 std::move(diversification_nonce)); |
| 579 DetachCallback(); |
| 580 } |
| 581 |
| 582 void DetachCallback() { |
| 583 QUIC_BUG_IF(done_cb_ == nullptr) << "Callback already detached."; |
| 584 done_cb_ = nullptr; |
| 585 } |
| 586 |
| 587 private: |
| 588 std::unique_ptr<ProcessClientHelloResultCallback>* done_cb_; |
| 589 }; |
| 590 |
| 591 void QuicCryptoServerConfig::ProcessClientHello( |
556 scoped_refptr<ValidateClientHelloResultCallback::Result> | 592 scoped_refptr<ValidateClientHelloResultCallback::Result> |
557 validate_chlo_result, | 593 validate_chlo_result, |
558 bool reject_only, | 594 bool reject_only, |
559 QuicConnectionId connection_id, | 595 QuicConnectionId connection_id, |
560 const IPAddress& server_ip, | 596 const IPAddress& server_ip, |
561 const IPEndPoint& client_address, | 597 const IPEndPoint& client_address, |
562 QuicVersion version, | 598 QuicVersion version, |
563 const QuicVersionVector& supported_versions, | 599 const QuicVersionVector& supported_versions, |
564 bool use_stateless_rejects, | 600 bool use_stateless_rejects, |
565 QuicConnectionId server_designated_connection_id, | 601 QuicConnectionId server_designated_connection_id, |
566 const QuicClock* clock, | 602 const QuicClock* clock, |
567 QuicRandom* rand, | 603 QuicRandom* rand, |
568 QuicCompressedCertsCache* compressed_certs_cache, | 604 QuicCompressedCertsCache* compressed_certs_cache, |
569 QuicCryptoNegotiatedParameters* params, | 605 QuicCryptoNegotiatedParameters* params, |
570 QuicCryptoProof* crypto_proof, | 606 QuicCryptoProof* crypto_proof, |
571 QuicByteCount total_framing_overhead, | 607 QuicByteCount total_framing_overhead, |
572 QuicByteCount chlo_packet_size, | 608 QuicByteCount chlo_packet_size, |
573 CryptoHandshakeMessage* out, | 609 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { |
574 DiversificationNonce* out_diversification_nonce, | 610 DCHECK(done_cb); |
575 string* error_details) const { | 611 |
576 DCHECK(error_details); | 612 ProcessClientHelloHelper helper(&done_cb); |
577 | 613 |
578 const CryptoHandshakeMessage& client_hello = | 614 const CryptoHandshakeMessage& client_hello = |
579 validate_chlo_result->client_hello; | 615 validate_chlo_result->client_hello; |
580 const ClientHelloInfo& info = validate_chlo_result->info; | 616 const ClientHelloInfo& info = validate_chlo_result->info; |
581 | 617 |
| 618 string error_details; |
582 QuicErrorCode valid = CryptoUtils::ValidateClientHello( | 619 QuicErrorCode valid = CryptoUtils::ValidateClientHello( |
583 client_hello, version, supported_versions, error_details); | 620 client_hello, version, supported_versions, &error_details); |
584 if (valid != QUIC_NO_ERROR) | 621 if (valid != QUIC_NO_ERROR) { |
585 return valid; | 622 helper.Fail(valid, error_details); |
| 623 return; |
| 624 } |
586 | 625 |
587 StringPiece requested_scid; | 626 StringPiece requested_scid; |
588 client_hello.GetStringPiece(kSCID, &requested_scid); | 627 client_hello.GetStringPiece(kSCID, &requested_scid); |
589 const QuicWallTime now(clock->WallNow()); | 628 const QuicWallTime now(clock->WallNow()); |
590 | 629 |
591 scoped_refptr<Config> requested_config; | 630 scoped_refptr<Config> requested_config; |
592 scoped_refptr<Config> primary_config; | 631 scoped_refptr<Config> primary_config; |
| 632 bool no_primary_config = false; |
593 { | 633 { |
594 base::AutoLock locked(configs_lock_); | 634 base::AutoLock locked(configs_lock_); |
595 | 635 |
596 if (!primary_config_.get()) { | 636 if (!primary_config_) { |
597 *error_details = "No configurations loaded"; | 637 no_primary_config = true; |
598 return QUIC_CRYPTO_INTERNAL_ERROR; | 638 } else { |
| 639 if (!next_config_promotion_time_.IsZero() && |
| 640 next_config_promotion_time_.IsAfter(now)) { |
| 641 SelectNewPrimaryConfig(now); |
| 642 DCHECK(primary_config_.get()); |
| 643 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
| 644 } |
| 645 |
| 646 // Use the config that the client requested in order to do key-agreement. |
| 647 // Otherwise give it a copy of |primary_config_| to use. |
| 648 primary_config = crypto_proof->config; |
| 649 requested_config = GetConfigWithScid(requested_scid); |
599 } | 650 } |
600 | 651 } |
601 if (!next_config_promotion_time_.IsZero() && | 652 if (no_primary_config) { |
602 next_config_promotion_time_.IsAfter(now)) { | 653 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded"); |
603 SelectNewPrimaryConfig(now); | 654 return; |
604 DCHECK(primary_config_.get()); | |
605 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | |
606 } | |
607 | |
608 // Use the config that the client requested in order to do key-agreement. | |
609 // Otherwise give it a copy of |primary_config_| to use. | |
610 primary_config = crypto_proof->config; | |
611 requested_config = GetConfigWithScid(requested_scid); | |
612 } | 655 } |
613 | 656 |
614 if (validate_chlo_result->error_code != QUIC_NO_ERROR) { | 657 if (validate_chlo_result->error_code != QUIC_NO_ERROR) { |
615 *error_details = validate_chlo_result->error_details; | 658 helper.Fail(validate_chlo_result->error_code, |
616 return validate_chlo_result->error_code; | 659 validate_chlo_result->error_details); |
| 660 return; |
617 } | 661 } |
618 | 662 |
619 out->Clear(); | |
620 | |
621 if (!ClientDemandsX509Proof(client_hello)) { | 663 if (!ClientDemandsX509Proof(client_hello)) { |
622 *error_details = "Missing or invalid PDMD"; | 664 helper.Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD"); |
623 return QUIC_UNSUPPORTED_PROOF_DEMAND; | 665 return; |
624 } | 666 } |
625 DCHECK(proof_source_.get()); | 667 DCHECK(proof_source_.get()); |
626 string chlo_hash; | 668 string chlo_hash; |
627 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); | 669 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
628 // No need to get a new proof if one was already generated. | 670 // No need to get a new proof if one was already generated. |
629 if (!crypto_proof->chain && | 671 if (!crypto_proof->chain) { |
630 !proof_source_->GetProof(server_ip, info.sni.as_string(), | 672 if (!proof_source_->GetProof(server_ip, info.sni.as_string(), |
631 primary_config->serialized, version, chlo_hash, | 673 primary_config->serialized, version, chlo_hash, |
632 &crypto_proof->chain, &crypto_proof->signature, | 674 &crypto_proof->chain, &crypto_proof->signature, |
633 &crypto_proof->cert_sct)) { | 675 &crypto_proof->cert_sct)) { |
634 return QUIC_HANDSHAKE_FAILED; | 676 helper.Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof"); |
| 677 return; |
| 678 } |
635 } | 679 } |
636 | 680 |
| 681 // Note: this split exists to facilitate a future change in which the async |
| 682 // version of GetProof will be called. |
| 683 helper.DetachCallback(); |
| 684 ProcessClientHelloAfterGetProof( |
| 685 *validate_chlo_result, reject_only, connection_id, client_address, |
| 686 version, supported_versions, use_stateless_rejects, |
| 687 server_designated_connection_id, clock, rand, compressed_certs_cache, |
| 688 params, crypto_proof, total_framing_overhead, chlo_packet_size, |
| 689 requested_config, primary_config, std::move(done_cb)); |
| 690 } |
| 691 |
| 692 void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
| 693 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
| 694 bool reject_only, |
| 695 QuicConnectionId connection_id, |
| 696 const IPEndPoint& client_address, |
| 697 QuicVersion version, |
| 698 const QuicVersionVector& supported_versions, |
| 699 bool use_stateless_rejects, |
| 700 QuicConnectionId server_designated_connection_id, |
| 701 const QuicClock* clock, |
| 702 QuicRandom* rand, |
| 703 QuicCompressedCertsCache* compressed_certs_cache, |
| 704 QuicCryptoNegotiatedParameters* params, |
| 705 QuicCryptoProof* crypto_proof, |
| 706 QuicByteCount total_framing_overhead, |
| 707 QuicByteCount chlo_packet_size, |
| 708 const scoped_refptr<Config>& requested_config, |
| 709 const scoped_refptr<Config>& primary_config, |
| 710 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { |
| 711 ProcessClientHelloHelper helper(&done_cb); |
| 712 |
| 713 const CryptoHandshakeMessage& client_hello = |
| 714 validate_chlo_result.client_hello; |
| 715 const ClientHelloInfo& info = validate_chlo_result.info; |
| 716 std::unique_ptr<DiversificationNonce> out_diversification_nonce( |
| 717 new DiversificationNonce); |
| 718 |
637 StringPiece cert_sct; | 719 StringPiece cert_sct; |
638 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && | 720 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && |
639 cert_sct.empty()) { | 721 cert_sct.empty()) { |
640 params->sct_supported_by_client = true; | 722 params->sct_supported_by_client = true; |
641 } | 723 } |
642 | 724 |
| 725 std::unique_ptr<CryptoHandshakeMessage> out(new CryptoHandshakeMessage); |
643 if (!info.reject_reasons.empty() || !requested_config.get()) { | 726 if (!info.reject_reasons.empty() || !requested_config.get()) { |
644 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, | 727 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, |
645 info, validate_chlo_result->cached_network_params, | 728 info, validate_chlo_result.cached_network_params, |
646 use_stateless_rejects, server_designated_connection_id, rand, | 729 use_stateless_rejects, server_designated_connection_id, rand, |
647 compressed_certs_cache, params, *crypto_proof, | 730 compressed_certs_cache, params, *crypto_proof, |
648 total_framing_overhead, chlo_packet_size, out); | 731 total_framing_overhead, chlo_packet_size, out.get()); |
649 if (FLAGS_quic_export_rej_for_all_rejects && | 732 if (FLAGS_quic_export_rej_for_all_rejects && |
650 rejection_observer_ != nullptr) { | 733 rejection_observer_ != nullptr) { |
651 rejection_observer_->OnRejectionBuilt(info.reject_reasons, out); | 734 rejection_observer_->OnRejectionBuilt(info.reject_reasons, out.get()); |
652 } | 735 } |
653 return QUIC_NO_ERROR; | 736 helper.Succeed(std::move(out), std::move(out_diversification_nonce)); |
| 737 return; |
654 } | 738 } |
655 | 739 |
656 if (reject_only) { | 740 if (reject_only) { |
657 return QUIC_NO_ERROR; | 741 helper.Succeed(std::move(out), std::move(out_diversification_nonce)); |
| 742 return; |
658 } | 743 } |
659 | 744 |
660 const QuicTag* their_aeads; | 745 const QuicTag* their_aeads; |
661 const QuicTag* their_key_exchanges; | 746 const QuicTag* their_key_exchanges; |
662 size_t num_their_aeads, num_their_key_exchanges; | 747 size_t num_their_aeads, num_their_key_exchanges; |
663 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != | 748 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != |
664 QUIC_NO_ERROR || | 749 QUIC_NO_ERROR || |
665 client_hello.GetTaglist(kKEXS, &their_key_exchanges, | 750 client_hello.GetTaglist(kKEXS, &their_key_exchanges, |
666 &num_their_key_exchanges) != QUIC_NO_ERROR || | 751 &num_their_key_exchanges) != QUIC_NO_ERROR || |
667 num_their_aeads != 1 || num_their_key_exchanges != 1) { | 752 num_their_aeads != 1 || num_their_key_exchanges != 1) { |
668 *error_details = "Missing or invalid AEAD or KEXS"; | 753 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
669 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 754 "Missing or invalid AEAD or KEXS"); |
| 755 return; |
670 } | 756 } |
671 | 757 |
672 size_t key_exchange_index; | 758 size_t key_exchange_index; |
673 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, | 759 if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, |
674 num_their_aeads, QuicUtils::LOCAL_PRIORITY, | 760 num_their_aeads, QuicUtils::LOCAL_PRIORITY, |
675 ¶ms->aead, nullptr) || | 761 ¶ms->aead, nullptr) || |
676 !QuicUtils::FindMutualTag(requested_config->kexs, their_key_exchanges, | 762 !QuicUtils::FindMutualTag(requested_config->kexs, their_key_exchanges, |
677 num_their_key_exchanges, | 763 num_their_key_exchanges, |
678 QuicUtils::LOCAL_PRIORITY, | 764 QuicUtils::LOCAL_PRIORITY, |
679 ¶ms->key_exchange, &key_exchange_index)) { | 765 ¶ms->key_exchange, &key_exchange_index)) { |
680 *error_details = "Unsupported AEAD or KEXS"; | 766 helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS"); |
681 return QUIC_CRYPTO_NO_SUPPORT; | 767 return; |
682 } | 768 } |
683 | 769 |
684 if (!requested_config->tb_key_params.empty()) { | 770 if (!requested_config->tb_key_params.empty()) { |
685 const QuicTag* their_tbkps; | 771 const QuicTag* their_tbkps; |
686 size_t num_their_tbkps; | 772 size_t num_their_tbkps; |
687 switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) { | 773 switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) { |
688 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | 774 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
689 break; | 775 break; |
690 case QUIC_NO_ERROR: | 776 case QUIC_NO_ERROR: |
691 if (QuicUtils::FindMutualTag( | 777 if (QuicUtils::FindMutualTag( |
692 requested_config->tb_key_params, their_tbkps, num_their_tbkps, | 778 requested_config->tb_key_params, their_tbkps, num_their_tbkps, |
693 QuicUtils::LOCAL_PRIORITY, ¶ms->token_binding_key_param, | 779 QuicUtils::LOCAL_PRIORITY, ¶ms->token_binding_key_param, |
694 nullptr)) { | 780 nullptr)) { |
695 break; | 781 break; |
696 } | 782 } |
697 default: | 783 default: |
698 *error_details = "Invalid Token Binding key parameter"; | 784 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
699 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 785 "Invalid Token Binding key parameter"); |
| 786 return; |
700 } | 787 } |
701 } | 788 } |
702 | 789 |
703 StringPiece public_value; | 790 StringPiece public_value; |
704 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { | 791 if (!client_hello.GetStringPiece(kPUBS, &public_value)) { |
705 *error_details = "Missing public value"; | 792 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Missing public value"); |
706 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 793 return; |
707 } | 794 } |
708 | 795 |
709 const KeyExchange* key_exchange = | 796 const KeyExchange* key_exchange = |
710 requested_config->key_exchanges[key_exchange_index]; | 797 requested_config->key_exchanges[key_exchange_index]; |
711 if (!key_exchange->CalculateSharedKey(public_value, | 798 if (!key_exchange->CalculateSharedKey(public_value, |
712 ¶ms->initial_premaster_secret)) { | 799 ¶ms->initial_premaster_secret)) { |
713 *error_details = "Invalid public value"; | 800 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "Invalid public value"); |
714 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 801 return; |
715 } | 802 } |
716 | 803 |
717 if (!info.sni.empty()) { | 804 if (!info.sni.empty()) { |
718 std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); | 805 std::unique_ptr<char[]> sni_tmp(new char[info.sni.length() + 1]); |
719 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); | 806 memcpy(sni_tmp.get(), info.sni.data(), info.sni.length()); |
720 sni_tmp[info.sni.length()] = 0; | 807 sni_tmp[info.sni.length()] = 0; |
721 params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get()); | 808 params->sni = CryptoUtils::NormalizeHostname(sni_tmp.get()); |
722 } | 809 } |
723 | 810 |
724 string hkdf_suffix; | 811 string hkdf_suffix; |
725 const QuicData& client_hello_serialized = client_hello.GetSerialized(); | 812 const QuicData& client_hello_serialized = client_hello.GetSerialized(); |
726 hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() + | 813 hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() + |
727 requested_config->serialized.size()); | 814 requested_config->serialized.size()); |
728 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), | 815 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), |
729 sizeof(connection_id)); | 816 sizeof(connection_id)); |
730 hkdf_suffix.append(client_hello_serialized.data(), | 817 hkdf_suffix.append(client_hello_serialized.data(), |
731 client_hello_serialized.length()); | 818 client_hello_serialized.length()); |
732 hkdf_suffix.append(requested_config->serialized); | 819 hkdf_suffix.append(requested_config->serialized); |
733 DCHECK(proof_source_.get()); | 820 DCHECK(proof_source_.get()); |
734 if (crypto_proof->chain->certs.empty()) { | 821 if (crypto_proof->chain->certs.empty()) { |
735 *error_details = "Failed to get certs"; | 822 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); |
736 return QUIC_CRYPTO_INTERNAL_ERROR; | 823 return; |
737 } | 824 } |
738 hkdf_suffix.append(crypto_proof->chain->certs.at(0)); | 825 hkdf_suffix.append(crypto_proof->chain->certs.at(0)); |
739 | 826 |
740 StringPiece cetv_ciphertext; | 827 StringPiece cetv_ciphertext; |
741 if (requested_config->channel_id_enabled && | 828 if (requested_config->channel_id_enabled && |
742 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { | 829 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { |
743 CryptoHandshakeMessage client_hello_copy(client_hello); | 830 CryptoHandshakeMessage client_hello_copy(client_hello); |
744 client_hello_copy.Erase(kCETV); | 831 client_hello_copy.Erase(kCETV); |
745 client_hello_copy.Erase(kPAD); | 832 client_hello_copy.Erase(kPAD); |
746 | 833 |
747 const QuicData& client_hello_copy_serialized = | 834 const QuicData& client_hello_copy_serialized = |
748 client_hello_copy.GetSerialized(); | 835 client_hello_copy.GetSerialized(); |
749 string hkdf_input; | 836 string hkdf_input; |
750 hkdf_input.append(QuicCryptoConfig::kCETVLabel, | 837 hkdf_input.append(QuicCryptoConfig::kCETVLabel, |
751 strlen(QuicCryptoConfig::kCETVLabel) + 1); | 838 strlen(QuicCryptoConfig::kCETVLabel) + 1); |
752 hkdf_input.append(reinterpret_cast<char*>(&connection_id), | 839 hkdf_input.append(reinterpret_cast<char*>(&connection_id), |
753 sizeof(connection_id)); | 840 sizeof(connection_id)); |
754 hkdf_input.append(client_hello_copy_serialized.data(), | 841 hkdf_input.append(client_hello_copy_serialized.data(), |
755 client_hello_copy_serialized.length()); | 842 client_hello_copy_serialized.length()); |
756 hkdf_input.append(requested_config->serialized); | 843 hkdf_input.append(requested_config->serialized); |
757 | 844 |
758 CrypterPair crypters; | 845 CrypterPair crypters; |
759 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 846 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, |
760 info.client_nonce, info.server_nonce, | 847 info.client_nonce, info.server_nonce, |
761 hkdf_input, Perspective::IS_SERVER, | 848 hkdf_input, Perspective::IS_SERVER, |
762 CryptoUtils::Diversification::Never(), | 849 CryptoUtils::Diversification::Never(), |
763 &crypters, nullptr /* subkey secret */)) { | 850 &crypters, nullptr /* subkey secret */)) { |
764 *error_details = "Symmetric key setup failed"; | 851 helper.Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, |
765 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 852 "Symmetric key setup failed"); |
| 853 return; |
766 } | 854 } |
767 | 855 |
768 char plaintext[kMaxPacketSize]; | 856 char plaintext[kMaxPacketSize]; |
769 size_t plaintext_length = 0; | 857 size_t plaintext_length = 0; |
770 const bool success = crypters.decrypter->DecryptPacket( | 858 const bool success = crypters.decrypter->DecryptPacket( |
771 kDefaultPathId, 0 /* packet number */, | 859 kDefaultPathId, 0 /* packet number */, |
772 StringPiece() /* associated data */, cetv_ciphertext, plaintext, | 860 StringPiece() /* associated data */, cetv_ciphertext, plaintext, |
773 &plaintext_length, kMaxPacketSize); | 861 &plaintext_length, kMaxPacketSize); |
774 if (!success) { | 862 if (!success) { |
775 *error_details = "CETV decryption failure"; | 863 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
776 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 864 "CETV decryption failure"); |
| 865 return; |
777 } | 866 } |
778 std::unique_ptr<CryptoHandshakeMessage> cetv( | 867 std::unique_ptr<CryptoHandshakeMessage> cetv( |
779 CryptoFramer::ParseMessage(StringPiece(plaintext, plaintext_length))); | 868 CryptoFramer::ParseMessage(StringPiece(plaintext, plaintext_length))); |
780 if (!cetv.get()) { | 869 if (!cetv.get()) { |
781 *error_details = "CETV parse error"; | 870 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, "CETV parse error"); |
782 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 871 return; |
783 } | 872 } |
784 | 873 |
785 StringPiece key, signature; | 874 StringPiece key, signature; |
786 if (cetv->GetStringPiece(kCIDK, &key) && | 875 if (cetv->GetStringPiece(kCIDK, &key) && |
787 cetv->GetStringPiece(kCIDS, &signature)) { | 876 cetv->GetStringPiece(kCIDS, &signature)) { |
788 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { | 877 if (!ChannelIDVerifier::Verify(key, hkdf_input, signature)) { |
789 *error_details = "ChannelID signature failure"; | 878 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
790 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 879 "ChannelID signature failure"); |
| 880 return; |
791 } | 881 } |
792 | 882 |
793 params->channel_id = key.as_string(); | 883 params->channel_id = key.as_string(); |
794 } | 884 } |
795 } | 885 } |
796 | 886 |
797 string hkdf_input; | 887 string hkdf_input; |
798 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; | 888 size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; |
799 hkdf_input.reserve(label_len + hkdf_suffix.size()); | 889 hkdf_input.reserve(label_len + hkdf_suffix.size()); |
800 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); | 890 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
801 hkdf_input.append(hkdf_suffix); | 891 hkdf_input.append(hkdf_suffix); |
802 | 892 |
803 CryptoUtils::Diversification diversification = | 893 CryptoUtils::Diversification diversification = |
804 CryptoUtils::Diversification::Never(); | 894 CryptoUtils::Diversification::Never(); |
805 if (version > QUIC_VERSION_32) { | 895 if (version > QUIC_VERSION_32) { |
806 rand->RandBytes(out_diversification_nonce->data(), | 896 rand->RandBytes(out_diversification_nonce->data(), |
807 out_diversification_nonce->size()); | 897 out_diversification_nonce->size()); |
808 diversification = | 898 diversification = |
809 CryptoUtils::Diversification::Now(out_diversification_nonce); | 899 CryptoUtils::Diversification::Now(out_diversification_nonce.get()); |
810 } | 900 } |
811 | 901 |
812 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, | 902 if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, |
813 info.client_nonce, info.server_nonce, hkdf_input, | 903 info.client_nonce, info.server_nonce, hkdf_input, |
814 Perspective::IS_SERVER, diversification, | 904 Perspective::IS_SERVER, diversification, |
815 ¶ms->initial_crypters, | 905 ¶ms->initial_crypters, |
816 ¶ms->initial_subkey_secret)) { | 906 ¶ms->initial_subkey_secret)) { |
817 *error_details = "Symmetric key setup failed"; | 907 helper.Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, |
818 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 908 "Symmetric key setup failed"); |
| 909 return; |
819 } | 910 } |
820 | 911 |
821 string forward_secure_public_value; | 912 string forward_secure_public_value; |
822 if (ephemeral_key_source_.get()) { | 913 if (ephemeral_key_source_.get()) { |
823 params->forward_secure_premaster_secret = | 914 params->forward_secure_premaster_secret = |
824 ephemeral_key_source_->CalculateForwardSecureKey( | 915 ephemeral_key_source_->CalculateForwardSecureKey( |
825 key_exchange, rand, clock->ApproximateNow(), public_value, | 916 key_exchange, rand, clock->ApproximateNow(), public_value, |
826 &forward_secure_public_value); | 917 &forward_secure_public_value); |
827 } else { | 918 } else { |
828 std::unique_ptr<KeyExchange> forward_secure_key_exchange( | 919 std::unique_ptr<KeyExchange> forward_secure_key_exchange( |
829 key_exchange->NewKeyPair(rand)); | 920 key_exchange->NewKeyPair(rand)); |
830 forward_secure_public_value = | 921 forward_secure_public_value = |
831 forward_secure_key_exchange->public_value().as_string(); | 922 forward_secure_key_exchange->public_value().as_string(); |
832 if (!forward_secure_key_exchange->CalculateSharedKey( | 923 if (!forward_secure_key_exchange->CalculateSharedKey( |
833 public_value, ¶ms->forward_secure_premaster_secret)) { | 924 public_value, ¶ms->forward_secure_premaster_secret)) { |
834 *error_details = "Invalid public value"; | 925 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
835 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 926 "Invalid public value"); |
| 927 return; |
836 } | 928 } |
837 } | 929 } |
838 | 930 |
839 string forward_secure_hkdf_input; | 931 string forward_secure_hkdf_input; |
840 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; | 932 label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1; |
841 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); | 933 forward_secure_hkdf_input.reserve(label_len + hkdf_suffix.size()); |
842 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, | 934 forward_secure_hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, |
843 label_len); | 935 label_len); |
844 forward_secure_hkdf_input.append(hkdf_suffix); | 936 forward_secure_hkdf_input.append(hkdf_suffix); |
845 | 937 |
846 string shlo_nonce; | 938 string shlo_nonce; |
847 shlo_nonce = NewServerNonce(rand, info.now); | 939 shlo_nonce = NewServerNonce(rand, info.now); |
848 out->SetStringPiece(kServerNonceTag, shlo_nonce); | 940 out->SetStringPiece(kServerNonceTag, shlo_nonce); |
849 | 941 |
850 if (!CryptoUtils::DeriveKeys( | 942 if (!CryptoUtils::DeriveKeys( |
851 params->forward_secure_premaster_secret, params->aead, | 943 params->forward_secure_premaster_secret, params->aead, |
852 info.client_nonce, | 944 info.client_nonce, |
853 shlo_nonce.empty() ? info.server_nonce : shlo_nonce, | 945 shlo_nonce.empty() ? info.server_nonce : shlo_nonce, |
854 forward_secure_hkdf_input, Perspective::IS_SERVER, | 946 forward_secure_hkdf_input, Perspective::IS_SERVER, |
855 CryptoUtils::Diversification::Never(), | 947 CryptoUtils::Diversification::Never(), |
856 ¶ms->forward_secure_crypters, ¶ms->subkey_secret)) { | 948 ¶ms->forward_secure_crypters, ¶ms->subkey_secret)) { |
857 *error_details = "Symmetric key setup failed"; | 949 helper.Fail(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED, |
858 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; | 950 "Symmetric key setup failed"); |
| 951 return; |
859 } | 952 } |
860 | 953 |
861 out->set_tag(kSHLO); | 954 out->set_tag(kSHLO); |
862 QuicTagVector supported_version_tags; | 955 QuicTagVector supported_version_tags; |
863 for (size_t i = 0; i < supported_versions.size(); ++i) { | 956 for (size_t i = 0; i < supported_versions.size(); ++i) { |
864 supported_version_tags.push_back( | 957 supported_version_tags.push_back( |
865 QuicVersionToQuicTag(supported_versions[i])); | 958 QuicVersionToQuicTag(supported_versions[i])); |
866 } | 959 } |
867 out->SetVector(kVER, supported_version_tags); | 960 out->SetVector(kVER, supported_version_tags); |
868 out->SetStringPiece( | 961 out->SetStringPiece( |
869 kSourceAddressTokenTag, | 962 kSourceAddressTokenTag, |
870 NewSourceAddressToken(*requested_config.get(), info.source_address_tokens, | 963 NewSourceAddressToken(*requested_config.get(), info.source_address_tokens, |
871 client_address.address(), rand, info.now, nullptr)); | 964 client_address.address(), rand, info.now, nullptr)); |
872 QuicSocketAddressCoder address_coder(client_address); | 965 QuicSocketAddressCoder address_coder(client_address); |
873 out->SetStringPiece(kCADR, address_coder.Encode()); | 966 out->SetStringPiece(kCADR, address_coder.Encode()); |
874 out->SetStringPiece(kPUBS, forward_secure_public_value); | 967 out->SetStringPiece(kPUBS, forward_secure_public_value); |
875 | 968 |
876 return QUIC_NO_ERROR; | 969 helper.Succeed(std::move(out), std::move(out_diversification_nonce)); |
877 } | 970 } |
878 | 971 |
879 scoped_refptr<QuicCryptoServerConfig::Config> | 972 scoped_refptr<QuicCryptoServerConfig::Config> |
880 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { | 973 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { |
881 // In Chromium, we will dead lock if the lock is held by the current thread. | 974 // In Chromium, we will dead lock if the lock is held by the current thread. |
882 // Chromium doesn't have AssertReaderHeld API call. | 975 // Chromium doesn't have AssertReaderHeld API call. |
883 // configs_lock_.AssertReaderHeld(); | 976 // configs_lock_.AssertReaderHeld(); |
884 | 977 |
885 if (!requested_scid.empty()) { | 978 if (!requested_scid.empty()) { |
886 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); | 979 ConfigMap::const_iterator it = configs_.find(requested_scid.as_string()); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 const string& leaf_cert_sct, | 1121 const string& leaf_cert_sct, |
1029 std::unique_ptr<ProofSource::Details> details) override { | 1122 std::unique_ptr<ProofSource::Details> details) override { |
1030 if (ok) { | 1123 if (ok) { |
1031 crypto_proof_->chain = chain; | 1124 crypto_proof_->chain = chain; |
1032 crypto_proof_->signature = signature; | 1125 crypto_proof_->signature = signature; |
1033 crypto_proof_->cert_sct = leaf_cert_sct; | 1126 crypto_proof_->cert_sct = leaf_cert_sct; |
1034 } | 1127 } |
1035 config_.EvaluateClientHelloAfterGetProof( | 1128 config_.EvaluateClientHelloAfterGetProof( |
1036 found_error_, server_ip_, version_, primary_orbit_, requested_config_, | 1129 found_error_, server_ip_, version_, primary_orbit_, requested_config_, |
1037 primary_config_, crypto_proof_, std::move(details), !ok, | 1130 primary_config_, crypto_proof_, std::move(details), !ok, |
1038 std::move(client_hello_state_), std::move(done_cb_)); | 1131 client_hello_state_, std::move(done_cb_)); |
1039 } | 1132 } |
1040 | 1133 |
1041 private: | 1134 private: |
1042 const QuicCryptoServerConfig& config_; | 1135 const QuicCryptoServerConfig& config_; |
1043 const bool found_error_; | 1136 const bool found_error_; |
1044 const IPAddress& server_ip_; | 1137 const IPAddress& server_ip_; |
1045 const QuicVersion version_; | 1138 const QuicVersion version_; |
1046 const uint8_t* primary_orbit_; | 1139 const uint8_t* primary_orbit_; |
1047 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; | 1140 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
1048 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; | 1141 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 bool need_proof = true; | 1224 bool need_proof = true; |
1132 need_proof = !crypto_proof->chain; | 1225 need_proof = !crypto_proof->chain; |
1133 if (FLAGS_enable_async_get_proof) { | 1226 if (FLAGS_enable_async_get_proof) { |
1134 if (need_proof) { | 1227 if (need_proof) { |
1135 // Make an async call to GetProof and setup the callback to trampoline | 1228 // Make an async call to GetProof and setup the callback to trampoline |
1136 // back into EvaluateClientHelloAfterGetProof | 1229 // back into EvaluateClientHelloAfterGetProof |
1137 std::unique_ptr<EvaluateClientHelloCallback> cb( | 1230 std::unique_ptr<EvaluateClientHelloCallback> cb( |
1138 new EvaluateClientHelloCallback( | 1231 new EvaluateClientHelloCallback( |
1139 *this, found_error, server_ip, version, primary_orbit, | 1232 *this, found_error, server_ip, version, primary_orbit, |
1140 requested_config, primary_config, crypto_proof, | 1233 requested_config, primary_config, crypto_proof, |
1141 std::move(client_hello_state), std::move(done_cb))); | 1234 client_hello_state, std::move(done_cb))); |
1142 proof_source_->GetProof(server_ip, info->sni.as_string(), | 1235 proof_source_->GetProof(server_ip, info->sni.as_string(), |
1143 serialized_config, version, chlo_hash, | 1236 serialized_config, version, chlo_hash, |
1144 std::move(cb)); | 1237 std::move(cb)); |
1145 helper.DetachCallback(); | 1238 helper.DetachCallback(); |
1146 return; | 1239 return; |
1147 } | 1240 } |
1148 } | 1241 } |
1149 | 1242 |
1150 // No need to get a new proof if one was already generated. | 1243 // No need to get a new proof if one was already generated. |
1151 if (need_proof && | 1244 if (need_proof && |
1152 !proof_source_->GetProof(server_ip, info->sni.as_string(), | 1245 !proof_source_->GetProof(server_ip, info->sni.as_string(), |
1153 serialized_config, version, chlo_hash, | 1246 serialized_config, version, chlo_hash, |
1154 &crypto_proof->chain, &crypto_proof->signature, | 1247 &crypto_proof->chain, &crypto_proof->signature, |
1155 &crypto_proof->cert_sct)) { | 1248 &crypto_proof->cert_sct)) { |
1156 get_proof_failed = true; | 1249 get_proof_failed = true; |
1157 } | 1250 } |
1158 | 1251 |
1159 // Details are null because the synchronous version of GetProof does not | 1252 // Details are null because the synchronous version of GetProof does not |
1160 // return any stats. Eventually the synchronous codepath will be eliminated. | 1253 // return any stats. Eventually the synchronous codepath will be eliminated. |
1161 EvaluateClientHelloAfterGetProof( | 1254 EvaluateClientHelloAfterGetProof( |
1162 found_error, server_ip, version, primary_orbit, requested_config, | 1255 found_error, server_ip, version, primary_orbit, requested_config, |
1163 primary_config, crypto_proof, nullptr /* proof_source_details */, | 1256 primary_config, crypto_proof, nullptr /* proof_source_details */, |
1164 get_proof_failed, std::move(client_hello_state), std::move(done_cb)); | 1257 get_proof_failed, client_hello_state, std::move(done_cb)); |
1165 helper.DetachCallback(); | 1258 helper.DetachCallback(); |
1166 } | 1259 } |
1167 | 1260 |
1168 void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( | 1261 void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
1169 bool found_error, | 1262 bool found_error, |
1170 const IPAddress& server_ip, | 1263 const IPAddress& server_ip, |
1171 QuicVersion version, | 1264 QuicVersion version, |
1172 const uint8_t* primary_orbit, | 1265 const uint8_t* primary_orbit, |
1173 scoped_refptr<Config> requested_config, | 1266 scoped_refptr<Config> requested_config, |
1174 scoped_refptr<Config> primary_config, | 1267 scoped_refptr<Config> primary_config, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 // Since neither are present, reject the handshake which will send a | 1359 // Since neither are present, reject the handshake which will send a |
1267 // server nonce to the client. | 1360 // server nonce to the client. |
1268 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); | 1361 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
1269 helper.ValidationComplete(QUIC_NO_ERROR, "", | 1362 helper.ValidationComplete(QUIC_NO_ERROR, "", |
1270 std::move(proof_source_details)); | 1363 std::move(proof_source_details)); |
1271 return; | 1364 return; |
1272 } | 1365 } |
1273 | 1366 |
1274 strike_register_client->VerifyNonceIsValidAndUnique( | 1367 strike_register_client->VerifyNonceIsValidAndUnique( |
1275 info->client_nonce, info->now, | 1368 info->client_nonce, info->now, |
1276 new VerifyNonceIsValidAndUniqueCallback(std::move(client_hello_state), | 1369 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, |
1277 std::move(proof_source_details), | 1370 std::move(proof_source_details), |
1278 std::move(done_cb))); | 1371 std::move(done_cb))); |
1279 helper.DetachCallback(); | 1372 helper.DetachCallback(); |
1280 } | 1373 } |
1281 | 1374 |
1282 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1375 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
1283 QuicVersion version, | 1376 QuicVersion version, |
1284 StringPiece chlo_hash, | 1377 StringPiece chlo_hash, |
1285 const SourceAddressTokens& previous_source_address_tokens, | 1378 const SourceAddressTokens& previous_source_address_tokens, |
1286 const IPAddress& server_ip, | 1379 const IPAddress& server_ip, |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 priority(0), | 2162 priority(0), |
2070 source_address_token_boxer(nullptr) {} | 2163 source_address_token_boxer(nullptr) {} |
2071 | 2164 |
2072 QuicCryptoServerConfig::Config::~Config() { | 2165 QuicCryptoServerConfig::Config::~Config() { |
2073 base::STLDeleteElements(&key_exchanges); | 2166 base::STLDeleteElements(&key_exchanges); |
2074 } | 2167 } |
2075 | 2168 |
2076 QuicCryptoProof::QuicCryptoProof() {} | 2169 QuicCryptoProof::QuicCryptoProof() {} |
2077 QuicCryptoProof::~QuicCryptoProof() {} | 2170 QuicCryptoProof::~QuicCryptoProof() {} |
2078 } // namespace net | 2171 } // namespace net |
OLD | NEW |