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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 scids->push_back(it->first); | 493 scids->push_back(it->first); |
494 } | 494 } |
495 } | 495 } |
496 | 496 |
497 void QuicCryptoServerConfig::ValidateClientHello( | 497 void QuicCryptoServerConfig::ValidateClientHello( |
498 const CryptoHandshakeMessage& client_hello, | 498 const CryptoHandshakeMessage& client_hello, |
499 const IPAddress& client_ip, | 499 const IPAddress& client_ip, |
500 const IPAddress& server_ip, | 500 const IPAddress& server_ip, |
501 QuicVersion version, | 501 QuicVersion version, |
502 const QuicClock* clock, | 502 const QuicClock* clock, |
503 scoped_refptr<QuicCryptoProof> crypto_proof, | 503 scoped_refptr<QuicSignedServerConfig> signed_config, |
504 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { | 504 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
505 const QuicWallTime now(clock->WallNow()); | 505 const QuicWallTime now(clock->WallNow()); |
506 | 506 |
507 scoped_refptr<ValidateClientHelloResultCallback::Result> result( | 507 scoped_refptr<ValidateClientHelloResultCallback::Result> result( |
508 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, | 508 new ValidateClientHelloResultCallback::Result(client_hello, client_ip, |
509 now)); | 509 now)); |
510 | 510 |
511 StringPiece requested_scid; | 511 StringPiece requested_scid; |
512 client_hello.GetStringPiece(kSCID, &requested_scid); | 512 client_hello.GetStringPiece(kSCID, &requested_scid); |
513 | 513 |
514 scoped_refptr<Config> requested_config; | 514 scoped_refptr<Config> requested_config; |
515 scoped_refptr<Config> primary_config; | 515 scoped_refptr<Config> primary_config; |
516 { | 516 { |
517 base::AutoLock locked(configs_lock_); | 517 base::AutoLock locked(configs_lock_); |
518 | 518 |
519 if (!primary_config_.get()) { | 519 if (!primary_config_.get()) { |
520 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; | 520 result->error_code = QUIC_CRYPTO_INTERNAL_ERROR; |
521 result->error_details = "No configurations loaded"; | 521 result->error_details = "No configurations loaded"; |
522 } else { | 522 } else { |
523 if (!next_config_promotion_time_.IsZero() && | 523 if (!next_config_promotion_time_.IsZero() && |
524 next_config_promotion_time_.IsAfter(now)) { | 524 next_config_promotion_time_.IsAfter(now)) { |
525 SelectNewPrimaryConfig(now); | 525 SelectNewPrimaryConfig(now); |
526 DCHECK(primary_config_.get()); | 526 DCHECK(primary_config_.get()); |
527 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 527 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
528 } | 528 } |
529 } | 529 } |
530 | 530 |
531 requested_config = GetConfigWithScid(requested_scid); | 531 requested_config = GetConfigWithScid(requested_scid); |
532 primary_config = primary_config_; | 532 primary_config = primary_config_; |
533 crypto_proof->config = primary_config_; | 533 signed_config->config = primary_config_; |
534 } | 534 } |
535 | 535 |
536 if (result->error_code == QUIC_NO_ERROR) { | 536 if (result->error_code == QUIC_NO_ERROR) { |
537 // QUIC requires a new proof for each CHLO so clear any existing proof. | 537 // QUIC requires a new proof for each CHLO so clear any existing proof. |
538 crypto_proof->chain = nullptr; | 538 signed_config->chain = nullptr; |
539 crypto_proof->signature = ""; | 539 signed_config->signature = ""; |
540 crypto_proof->cert_sct = ""; | 540 signed_config->cert_sct = ""; |
541 EvaluateClientHello(server_ip, version, requested_config, primary_config, | 541 EvaluateClientHello(server_ip, version, requested_config, primary_config, |
542 crypto_proof, result, std::move(done_cb)); | 542 signed_config, result, std::move(done_cb)); |
543 } else { | 543 } else { |
544 done_cb->Run(result, /* details = */ nullptr); | 544 done_cb->Run(result, /* details = */ nullptr); |
545 } | 545 } |
546 } | 546 } |
547 | 547 |
548 class ProcessClientHelloHelper { | 548 class ProcessClientHelloHelper { |
549 public: | 549 public: |
550 explicit ProcessClientHelloHelper( | 550 explicit ProcessClientHelloHelper( |
551 std::unique_ptr<ProcessClientHelloResultCallback>* done_cb) | 551 std::unique_ptr<ProcessClientHelloResultCallback>* done_cb) |
552 : done_cb_(done_cb) {} | 552 : done_cb_(done_cb) {} |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 QuicConnectionId connection_id, | 590 QuicConnectionId connection_id, |
591 const IPEndPoint& client_address, | 591 const IPEndPoint& client_address, |
592 QuicVersion version, | 592 QuicVersion version, |
593 const QuicVersionVector& supported_versions, | 593 const QuicVersionVector& supported_versions, |
594 bool use_stateless_rejects, | 594 bool use_stateless_rejects, |
595 QuicConnectionId server_designated_connection_id, | 595 QuicConnectionId server_designated_connection_id, |
596 const QuicClock* clock, | 596 const QuicClock* clock, |
597 QuicRandom* rand, | 597 QuicRandom* rand, |
598 QuicCompressedCertsCache* compressed_certs_cache, | 598 QuicCompressedCertsCache* compressed_certs_cache, |
599 scoped_refptr<QuicCryptoNegotiatedParameters> params, | 599 scoped_refptr<QuicCryptoNegotiatedParameters> params, |
600 scoped_refptr<QuicCryptoProof> crypto_proof, | 600 scoped_refptr<QuicSignedServerConfig> signed_config, |
601 QuicByteCount total_framing_overhead, | 601 QuicByteCount total_framing_overhead, |
602 QuicByteCount chlo_packet_size, | 602 QuicByteCount chlo_packet_size, |
603 const scoped_refptr<QuicCryptoServerConfig::Config>& requested_config, | 603 const scoped_refptr<QuicCryptoServerConfig::Config>& requested_config, |
604 const scoped_refptr<QuicCryptoServerConfig::Config>& primary_config, | 604 const scoped_refptr<QuicCryptoServerConfig::Config>& primary_config, |
605 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) | 605 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) |
606 : config_(config), | 606 : config_(config), |
607 validate_chlo_result_(std::move(validate_chlo_result)), | 607 validate_chlo_result_(std::move(validate_chlo_result)), |
608 reject_only_(reject_only), | 608 reject_only_(reject_only), |
609 connection_id_(connection_id), | 609 connection_id_(connection_id), |
610 client_address_(client_address), | 610 client_address_(client_address), |
611 version_(version), | 611 version_(version), |
612 supported_versions_(supported_versions), | 612 supported_versions_(supported_versions), |
613 use_stateless_rejects_(use_stateless_rejects), | 613 use_stateless_rejects_(use_stateless_rejects), |
614 server_designated_connection_id_(server_designated_connection_id), | 614 server_designated_connection_id_(server_designated_connection_id), |
615 clock_(clock), | 615 clock_(clock), |
616 rand_(rand), | 616 rand_(rand), |
617 compressed_certs_cache_(compressed_certs_cache), | 617 compressed_certs_cache_(compressed_certs_cache), |
618 params_(params), | 618 params_(params), |
619 crypto_proof_(crypto_proof), | 619 signed_config_(signed_config), |
620 total_framing_overhead_(total_framing_overhead), | 620 total_framing_overhead_(total_framing_overhead), |
621 chlo_packet_size_(chlo_packet_size), | 621 chlo_packet_size_(chlo_packet_size), |
622 requested_config_(requested_config), | 622 requested_config_(requested_config), |
623 primary_config_(primary_config), | 623 primary_config_(primary_config), |
624 done_cb_(std::move(done_cb)) {} | 624 done_cb_(std::move(done_cb)) {} |
625 | 625 |
626 void Run(bool ok, | 626 void Run(bool ok, |
627 const scoped_refptr<ProofSource::Chain>& chain, | 627 const scoped_refptr<ProofSource::Chain>& chain, |
628 const string& signature, | 628 const QuicCryptoProof& proof, |
629 const string& leaf_cert_sct, | |
630 std::unique_ptr<ProofSource::Details> details) override { | 629 std::unique_ptr<ProofSource::Details> details) override { |
631 if (ok) { | 630 if (ok) { |
632 crypto_proof_->chain = chain; | 631 signed_config_->chain = chain; |
633 crypto_proof_->signature = signature; | 632 signed_config_->signature = proof.signature; |
634 crypto_proof_->cert_sct = leaf_cert_sct; | 633 signed_config_->cert_sct = proof.leaf_cert_scts; |
635 } | 634 } |
636 config_->ProcessClientHelloAfterGetProof( | 635 config_->ProcessClientHelloAfterGetProof( |
637 !ok, std::move(details), *validate_chlo_result_, reject_only_, | 636 !ok, std::move(details), *validate_chlo_result_, reject_only_, |
638 connection_id_, client_address_, version_, supported_versions_, | 637 connection_id_, client_address_, version_, supported_versions_, |
639 use_stateless_rejects_, server_designated_connection_id_, clock_, rand_, | 638 use_stateless_rejects_, server_designated_connection_id_, clock_, rand_, |
640 compressed_certs_cache_, params_, crypto_proof_, | 639 compressed_certs_cache_, params_, signed_config_, |
641 total_framing_overhead_, chlo_packet_size_, requested_config_, | 640 total_framing_overhead_, chlo_packet_size_, requested_config_, |
642 primary_config_, std::move(done_cb_)); | 641 primary_config_, std::move(done_cb_)); |
643 } | 642 } |
644 | 643 |
645 private: | 644 private: |
646 const QuicCryptoServerConfig* config_; | 645 const QuicCryptoServerConfig* config_; |
647 const scoped_refptr<ValidateClientHelloResultCallback::Result> | 646 const scoped_refptr<ValidateClientHelloResultCallback::Result> |
648 validate_chlo_result_; | 647 validate_chlo_result_; |
649 const bool reject_only_; | 648 const bool reject_only_; |
650 const QuicConnectionId connection_id_; | 649 const QuicConnectionId connection_id_; |
651 const IPEndPoint client_address_; | 650 const IPEndPoint client_address_; |
652 const QuicVersion version_; | 651 const QuicVersion version_; |
653 const QuicVersionVector supported_versions_; | 652 const QuicVersionVector supported_versions_; |
654 const bool use_stateless_rejects_; | 653 const bool use_stateless_rejects_; |
655 const QuicConnectionId server_designated_connection_id_; | 654 const QuicConnectionId server_designated_connection_id_; |
656 const QuicClock* const clock_; | 655 const QuicClock* const clock_; |
657 QuicRandom* const rand_; | 656 QuicRandom* const rand_; |
658 QuicCompressedCertsCache* compressed_certs_cache_; | 657 QuicCompressedCertsCache* compressed_certs_cache_; |
659 scoped_refptr<QuicCryptoNegotiatedParameters> params_; | 658 scoped_refptr<QuicCryptoNegotiatedParameters> params_; |
660 scoped_refptr<QuicCryptoProof> crypto_proof_; | 659 scoped_refptr<QuicSignedServerConfig> signed_config_; |
661 const QuicByteCount total_framing_overhead_; | 660 const QuicByteCount total_framing_overhead_; |
662 const QuicByteCount chlo_packet_size_; | 661 const QuicByteCount chlo_packet_size_; |
663 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; | 662 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
664 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; | 663 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; |
665 std::unique_ptr<ProcessClientHelloResultCallback> done_cb_; | 664 std::unique_ptr<ProcessClientHelloResultCallback> done_cb_; |
666 }; | 665 }; |
667 | 666 |
668 void QuicCryptoServerConfig::ProcessClientHello( | 667 void QuicCryptoServerConfig::ProcessClientHello( |
669 scoped_refptr<ValidateClientHelloResultCallback::Result> | 668 scoped_refptr<ValidateClientHelloResultCallback::Result> |
670 validate_chlo_result, | 669 validate_chlo_result, |
671 bool reject_only, | 670 bool reject_only, |
672 QuicConnectionId connection_id, | 671 QuicConnectionId connection_id, |
673 const IPAddress& server_ip, | 672 const IPAddress& server_ip, |
674 const IPEndPoint& client_address, | 673 const IPEndPoint& client_address, |
675 QuicVersion version, | 674 QuicVersion version, |
676 const QuicVersionVector& supported_versions, | 675 const QuicVersionVector& supported_versions, |
677 bool use_stateless_rejects, | 676 bool use_stateless_rejects, |
678 QuicConnectionId server_designated_connection_id, | 677 QuicConnectionId server_designated_connection_id, |
679 const QuicClock* clock, | 678 const QuicClock* clock, |
680 QuicRandom* rand, | 679 QuicRandom* rand, |
681 QuicCompressedCertsCache* compressed_certs_cache, | 680 QuicCompressedCertsCache* compressed_certs_cache, |
682 scoped_refptr<QuicCryptoNegotiatedParameters> params, | 681 scoped_refptr<QuicCryptoNegotiatedParameters> params, |
683 scoped_refptr<QuicCryptoProof> crypto_proof, | 682 scoped_refptr<QuicSignedServerConfig> signed_config, |
684 QuicByteCount total_framing_overhead, | 683 QuicByteCount total_framing_overhead, |
685 QuicByteCount chlo_packet_size, | 684 QuicByteCount chlo_packet_size, |
686 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { | 685 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { |
687 DCHECK(done_cb); | 686 DCHECK(done_cb); |
688 | 687 |
689 ProcessClientHelloHelper helper(&done_cb); | 688 ProcessClientHelloHelper helper(&done_cb); |
690 | 689 |
691 const CryptoHandshakeMessage& client_hello = | 690 const CryptoHandshakeMessage& client_hello = |
692 validate_chlo_result->client_hello; | 691 validate_chlo_result->client_hello; |
693 const ClientHelloInfo& info = validate_chlo_result->info; | 692 const ClientHelloInfo& info = validate_chlo_result->info; |
(...skipping 21 matching lines...) Expand all Loading... |
715 } else { | 714 } else { |
716 if (!next_config_promotion_time_.IsZero() && | 715 if (!next_config_promotion_time_.IsZero() && |
717 next_config_promotion_time_.IsAfter(now)) { | 716 next_config_promotion_time_.IsAfter(now)) { |
718 SelectNewPrimaryConfig(now); | 717 SelectNewPrimaryConfig(now); |
719 DCHECK(primary_config_.get()); | 718 DCHECK(primary_config_.get()); |
720 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); | 719 DCHECK_EQ(configs_.find(primary_config_->id)->second, primary_config_); |
721 } | 720 } |
722 | 721 |
723 // Use the config that the client requested in order to do key-agreement. | 722 // Use the config that the client requested in order to do key-agreement. |
724 // Otherwise give it a copy of |primary_config_| to use. | 723 // Otherwise give it a copy of |primary_config_| to use. |
725 primary_config = crypto_proof->config; | 724 primary_config = signed_config->config; |
726 requested_config = GetConfigWithScid(requested_scid); | 725 requested_config = GetConfigWithScid(requested_scid); |
727 } | 726 } |
728 } | 727 } |
729 if (no_primary_config) { | 728 if (no_primary_config) { |
730 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded"); | 729 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "No configurations loaded"); |
731 return; | 730 return; |
732 } | 731 } |
733 | 732 |
734 if (validate_chlo_result->error_code != QUIC_NO_ERROR) { | 733 if (validate_chlo_result->error_code != QUIC_NO_ERROR) { |
735 helper.Fail(validate_chlo_result->error_code, | 734 helper.Fail(validate_chlo_result->error_code, |
736 validate_chlo_result->error_details); | 735 validate_chlo_result->error_details); |
737 return; | 736 return; |
738 } | 737 } |
739 | 738 |
740 if (!ClientDemandsX509Proof(client_hello)) { | 739 if (!ClientDemandsX509Proof(client_hello)) { |
741 helper.Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD"); | 740 helper.Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD"); |
742 return; | 741 return; |
743 } | 742 } |
744 DCHECK(proof_source_.get()); | 743 DCHECK(proof_source_.get()); |
745 string chlo_hash; | 744 string chlo_hash; |
746 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); | 745 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
747 | 746 |
748 // No need to get a new proof if one was already generated. | 747 // No need to get a new proof if one was already generated. |
749 if (!crypto_proof->chain) { | 748 if (!signed_config->chain) { |
750 const QuicTag* tag_ptr; | 749 const QuicTag* tag_ptr; |
751 size_t num_tags; | 750 size_t num_tags; |
752 QuicTagVector connection_options; | 751 QuicTagVector connection_options; |
753 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { | 752 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { |
754 connection_options.assign(tag_ptr, tag_ptr + num_tags); | 753 connection_options.assign(tag_ptr, tag_ptr + num_tags); |
755 } | 754 } |
756 if (FLAGS_enable_async_get_proof) { | 755 if (FLAGS_enable_async_get_proof) { |
757 std::unique_ptr<ProcessClientHelloCallback> cb( | 756 std::unique_ptr<ProcessClientHelloCallback> cb( |
758 new ProcessClientHelloCallback( | 757 new ProcessClientHelloCallback( |
759 this, validate_chlo_result, reject_only, connection_id, | 758 this, validate_chlo_result, reject_only, connection_id, |
760 client_address, version, supported_versions, | 759 client_address, version, supported_versions, |
761 use_stateless_rejects, server_designated_connection_id, clock, | 760 use_stateless_rejects, server_designated_connection_id, clock, |
762 rand, compressed_certs_cache, params, crypto_proof, | 761 rand, compressed_certs_cache, params, signed_config, |
763 total_framing_overhead, chlo_packet_size, requested_config, | 762 total_framing_overhead, chlo_packet_size, requested_config, |
764 primary_config, std::move(done_cb))); | 763 primary_config, std::move(done_cb))); |
765 proof_source_->GetProof(server_ip, info.sni.as_string(), | 764 proof_source_->GetProof(server_ip, info.sni.as_string(), |
766 primary_config->serialized, version, chlo_hash, | 765 primary_config->serialized, version, chlo_hash, |
767 connection_options, std::move(cb)); | 766 connection_options, std::move(cb)); |
768 helper.DetachCallback(); | 767 helper.DetachCallback(); |
769 return; | 768 return; |
770 } | 769 } |
771 | 770 |
772 if (!proof_source_->GetProof( | 771 QuicCryptoProof proof; |
773 server_ip, info.sni.as_string(), primary_config->serialized, | 772 if (!proof_source_->GetProof(server_ip, info.sni.as_string(), |
774 version, chlo_hash, connection_options, &crypto_proof->chain, | 773 primary_config->serialized, version, chlo_hash, |
775 &crypto_proof->signature, &crypto_proof->cert_sct)) { | 774 connection_options, &signed_config->chain, |
| 775 &proof)) { |
776 helper.Fail(QUIC_HANDSHAKE_FAILED, "Missing or invalid crypto proof."); | 776 helper.Fail(QUIC_HANDSHAKE_FAILED, "Missing or invalid crypto proof."); |
777 return; | 777 return; |
778 } | 778 } |
| 779 signed_config->signature = proof.signature; |
| 780 signed_config->cert_sct = proof.leaf_cert_scts; |
779 } | 781 } |
780 | 782 |
781 helper.DetachCallback(); | 783 helper.DetachCallback(); |
782 ProcessClientHelloAfterGetProof( | 784 ProcessClientHelloAfterGetProof( |
783 /* found_error = */ false, /* proof_source_details = */ nullptr, | 785 /* found_error = */ false, /* proof_source_details = */ nullptr, |
784 *validate_chlo_result, reject_only, connection_id, client_address, | 786 *validate_chlo_result, reject_only, connection_id, client_address, |
785 version, supported_versions, use_stateless_rejects, | 787 version, supported_versions, use_stateless_rejects, |
786 server_designated_connection_id, clock, rand, compressed_certs_cache, | 788 server_designated_connection_id, clock, rand, compressed_certs_cache, |
787 params, crypto_proof, total_framing_overhead, chlo_packet_size, | 789 params, signed_config, total_framing_overhead, chlo_packet_size, |
788 requested_config, primary_config, std::move(done_cb)); | 790 requested_config, primary_config, std::move(done_cb)); |
789 } | 791 } |
790 | 792 |
791 void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( | 793 void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
792 bool found_error, | 794 bool found_error, |
793 std::unique_ptr<ProofSource::Details> proof_source_details, | 795 std::unique_ptr<ProofSource::Details> proof_source_details, |
794 const ValidateClientHelloResultCallback::Result& validate_chlo_result, | 796 const ValidateClientHelloResultCallback::Result& validate_chlo_result, |
795 bool reject_only, | 797 bool reject_only, |
796 QuicConnectionId connection_id, | 798 QuicConnectionId connection_id, |
797 const IPEndPoint& client_address, | 799 const IPEndPoint& client_address, |
798 QuicVersion version, | 800 QuicVersion version, |
799 const QuicVersionVector& supported_versions, | 801 const QuicVersionVector& supported_versions, |
800 bool use_stateless_rejects, | 802 bool use_stateless_rejects, |
801 QuicConnectionId server_designated_connection_id, | 803 QuicConnectionId server_designated_connection_id, |
802 const QuicClock* clock, | 804 const QuicClock* clock, |
803 QuicRandom* rand, | 805 QuicRandom* rand, |
804 QuicCompressedCertsCache* compressed_certs_cache, | 806 QuicCompressedCertsCache* compressed_certs_cache, |
805 scoped_refptr<QuicCryptoNegotiatedParameters> params, | 807 scoped_refptr<QuicCryptoNegotiatedParameters> params, |
806 scoped_refptr<QuicCryptoProof> crypto_proof, | 808 scoped_refptr<QuicSignedServerConfig> signed_config, |
807 QuicByteCount total_framing_overhead, | 809 QuicByteCount total_framing_overhead, |
808 QuicByteCount chlo_packet_size, | 810 QuicByteCount chlo_packet_size, |
809 const scoped_refptr<Config>& requested_config, | 811 const scoped_refptr<Config>& requested_config, |
810 const scoped_refptr<Config>& primary_config, | 812 const scoped_refptr<Config>& primary_config, |
811 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { | 813 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { |
812 ProcessClientHelloHelper helper(&done_cb); | 814 ProcessClientHelloHelper helper(&done_cb); |
813 | 815 |
814 if (found_error) { | 816 if (found_error) { |
815 helper.Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof"); | 817 helper.Fail(QUIC_HANDSHAKE_FAILED, "Failed to get proof"); |
816 return; | 818 return; |
817 } | 819 } |
818 | 820 |
819 const CryptoHandshakeMessage& client_hello = | 821 const CryptoHandshakeMessage& client_hello = |
820 validate_chlo_result.client_hello; | 822 validate_chlo_result.client_hello; |
821 const ClientHelloInfo& info = validate_chlo_result.info; | 823 const ClientHelloInfo& info = validate_chlo_result.info; |
822 std::unique_ptr<DiversificationNonce> out_diversification_nonce( | 824 std::unique_ptr<DiversificationNonce> out_diversification_nonce( |
823 new DiversificationNonce); | 825 new DiversificationNonce); |
824 | 826 |
825 StringPiece cert_sct; | 827 StringPiece cert_sct; |
826 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && | 828 if (client_hello.GetStringPiece(kCertificateSCTTag, &cert_sct) && |
827 cert_sct.empty()) { | 829 cert_sct.empty()) { |
828 params->sct_supported_by_client = true; | 830 params->sct_supported_by_client = true; |
829 } | 831 } |
830 | 832 |
831 std::unique_ptr<CryptoHandshakeMessage> out(new CryptoHandshakeMessage); | 833 std::unique_ptr<CryptoHandshakeMessage> out(new CryptoHandshakeMessage); |
832 if (!info.reject_reasons.empty() || !requested_config.get()) { | 834 if (!info.reject_reasons.empty() || !requested_config.get()) { |
833 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, | 835 BuildRejection(version, clock->WallNow(), *primary_config, client_hello, |
834 info, validate_chlo_result.cached_network_params, | 836 info, validate_chlo_result.cached_network_params, |
835 use_stateless_rejects, server_designated_connection_id, rand, | 837 use_stateless_rejects, server_designated_connection_id, rand, |
836 compressed_certs_cache, params, *crypto_proof, | 838 compressed_certs_cache, params, *signed_config, |
837 total_framing_overhead, chlo_packet_size, out.get()); | 839 total_framing_overhead, chlo_packet_size, out.get()); |
838 if (FLAGS_quic_export_rej_for_all_rejects && | 840 if (FLAGS_quic_export_rej_for_all_rejects && |
839 rejection_observer_ != nullptr) { | 841 rejection_observer_ != nullptr) { |
840 rejection_observer_->OnRejectionBuilt(info.reject_reasons, out.get()); | 842 rejection_observer_->OnRejectionBuilt(info.reject_reasons, out.get()); |
841 } | 843 } |
842 helper.Succeed(std::move(out), std::move(out_diversification_nonce), | 844 helper.Succeed(std::move(out), std::move(out_diversification_nonce), |
843 std::move(proof_source_details)); | 845 std::move(proof_source_details)); |
844 return; | 846 return; |
845 } | 847 } |
846 | 848 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 string hkdf_suffix; | 921 string hkdf_suffix; |
920 const QuicData& client_hello_serialized = client_hello.GetSerialized(); | 922 const QuicData& client_hello_serialized = client_hello.GetSerialized(); |
921 hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() + | 923 hkdf_suffix.reserve(sizeof(connection_id) + client_hello_serialized.length() + |
922 requested_config->serialized.size()); | 924 requested_config->serialized.size()); |
923 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), | 925 hkdf_suffix.append(reinterpret_cast<char*>(&connection_id), |
924 sizeof(connection_id)); | 926 sizeof(connection_id)); |
925 hkdf_suffix.append(client_hello_serialized.data(), | 927 hkdf_suffix.append(client_hello_serialized.data(), |
926 client_hello_serialized.length()); | 928 client_hello_serialized.length()); |
927 hkdf_suffix.append(requested_config->serialized); | 929 hkdf_suffix.append(requested_config->serialized); |
928 DCHECK(proof_source_.get()); | 930 DCHECK(proof_source_.get()); |
929 if (crypto_proof->chain->certs.empty()) { | 931 if (signed_config->chain->certs.empty()) { |
930 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); | 932 helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); |
931 return; | 933 return; |
932 } | 934 } |
933 hkdf_suffix.append(crypto_proof->chain->certs.at(0)); | 935 hkdf_suffix.append(signed_config->chain->certs.at(0)); |
934 | 936 |
935 StringPiece cetv_ciphertext; | 937 StringPiece cetv_ciphertext; |
936 if (requested_config->channel_id_enabled && | 938 if (requested_config->channel_id_enabled && |
937 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { | 939 client_hello.GetStringPiece(kCETV, &cetv_ciphertext)) { |
938 CryptoHandshakeMessage client_hello_copy(client_hello); | 940 CryptoHandshakeMessage client_hello_copy(client_hello); |
939 client_hello_copy.Erase(kCETV); | 941 client_hello_copy.Erase(kCETV); |
940 client_hello_copy.Erase(kPAD); | 942 client_hello_copy.Erase(kPAD); |
941 | 943 |
942 const QuicData& client_hello_copy_serialized = | 944 const QuicData& client_hello_copy_serialized = |
943 client_hello_copy.GetSerialized(); | 945 client_hello_copy.GetSerialized(); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 class QuicCryptoServerConfig::EvaluateClientHelloCallback | 1203 class QuicCryptoServerConfig::EvaluateClientHelloCallback |
1202 : public ProofSource::Callback { | 1204 : public ProofSource::Callback { |
1203 public: | 1205 public: |
1204 EvaluateClientHelloCallback( | 1206 EvaluateClientHelloCallback( |
1205 const QuicCryptoServerConfig& config, | 1207 const QuicCryptoServerConfig& config, |
1206 bool found_error, | 1208 bool found_error, |
1207 const IPAddress& server_ip, | 1209 const IPAddress& server_ip, |
1208 QuicVersion version, | 1210 QuicVersion version, |
1209 scoped_refptr<QuicCryptoServerConfig::Config> requested_config, | 1211 scoped_refptr<QuicCryptoServerConfig::Config> requested_config, |
1210 scoped_refptr<QuicCryptoServerConfig::Config> primary_config, | 1212 scoped_refptr<QuicCryptoServerConfig::Config> primary_config, |
1211 scoped_refptr<QuicCryptoProof> crypto_proof, | 1213 scoped_refptr<QuicSignedServerConfig> signed_config, |
1212 scoped_refptr<ValidateClientHelloResultCallback::Result> | 1214 scoped_refptr<ValidateClientHelloResultCallback::Result> |
1213 client_hello_state, | 1215 client_hello_state, |
1214 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) | 1216 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) |
1215 : config_(config), | 1217 : config_(config), |
1216 found_error_(found_error), | 1218 found_error_(found_error), |
1217 server_ip_(server_ip), | 1219 server_ip_(server_ip), |
1218 version_(version), | 1220 version_(version), |
1219 requested_config_(std::move(requested_config)), | 1221 requested_config_(std::move(requested_config)), |
1220 primary_config_(std::move(primary_config)), | 1222 primary_config_(std::move(primary_config)), |
1221 crypto_proof_(crypto_proof), | 1223 signed_config_(signed_config), |
1222 client_hello_state_(std::move(client_hello_state)), | 1224 client_hello_state_(std::move(client_hello_state)), |
1223 done_cb_(std::move(done_cb)) {} | 1225 done_cb_(std::move(done_cb)) {} |
1224 | 1226 |
1225 void Run(bool ok, | 1227 void Run(bool ok, |
1226 const scoped_refptr<ProofSource::Chain>& chain, | 1228 const scoped_refptr<ProofSource::Chain>& chain, |
1227 const string& signature, | 1229 const QuicCryptoProof& proof, |
1228 const string& leaf_cert_sct, | |
1229 std::unique_ptr<ProofSource::Details> details) override { | 1230 std::unique_ptr<ProofSource::Details> details) override { |
1230 if (ok) { | 1231 if (ok) { |
1231 crypto_proof_->chain = chain; | 1232 signed_config_->chain = chain; |
1232 crypto_proof_->signature = signature; | 1233 signed_config_->signature = proof.signature; |
1233 crypto_proof_->cert_sct = leaf_cert_sct; | 1234 signed_config_->cert_sct = proof.leaf_cert_scts; |
1234 } | 1235 } |
1235 config_.EvaluateClientHelloAfterGetProof( | 1236 config_.EvaluateClientHelloAfterGetProof( |
1236 found_error_, server_ip_, version_, requested_config_, primary_config_, | 1237 found_error_, server_ip_, version_, requested_config_, primary_config_, |
1237 crypto_proof_, std::move(details), !ok, client_hello_state_, | 1238 signed_config_, std::move(details), !ok, client_hello_state_, |
1238 std::move(done_cb_)); | 1239 std::move(done_cb_)); |
1239 } | 1240 } |
1240 | 1241 |
1241 private: | 1242 private: |
1242 const QuicCryptoServerConfig& config_; | 1243 const QuicCryptoServerConfig& config_; |
1243 const bool found_error_; | 1244 const bool found_error_; |
1244 const IPAddress& server_ip_; | 1245 const IPAddress& server_ip_; |
1245 const QuicVersion version_; | 1246 const QuicVersion version_; |
1246 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; | 1247 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
1247 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; | 1248 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; |
1248 scoped_refptr<QuicCryptoProof> crypto_proof_; | 1249 scoped_refptr<QuicSignedServerConfig> signed_config_; |
1249 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state_; | 1250 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state_; |
1250 std::unique_ptr<ValidateClientHelloResultCallback> done_cb_; | 1251 std::unique_ptr<ValidateClientHelloResultCallback> done_cb_; |
1251 }; | 1252 }; |
1252 | 1253 |
1253 void QuicCryptoServerConfig::EvaluateClientHello( | 1254 void QuicCryptoServerConfig::EvaluateClientHello( |
1254 const IPAddress& server_ip, | 1255 const IPAddress& server_ip, |
1255 QuicVersion version, | 1256 QuicVersion version, |
1256 scoped_refptr<Config> requested_config, | 1257 scoped_refptr<Config> requested_config, |
1257 scoped_refptr<Config> primary_config, | 1258 scoped_refptr<Config> primary_config, |
1258 scoped_refptr<QuicCryptoProof> crypto_proof, | 1259 scoped_refptr<QuicSignedServerConfig> signed_config, |
1259 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, | 1260 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, |
1260 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { | 1261 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
1261 ValidateClientHelloHelper helper(client_hello_state, &done_cb); | 1262 ValidateClientHelloHelper helper(client_hello_state, &done_cb); |
1262 | 1263 |
1263 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; | 1264 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; |
1264 ClientHelloInfo* info = &(client_hello_state->info); | 1265 ClientHelloInfo* info = &(client_hello_state->info); |
1265 | 1266 |
1266 if (client_hello.size() < kClientHelloMinimumSize) { | 1267 if (client_hello.size() < kClientHelloMinimumSize) { |
1267 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, | 1268 helper.ValidationComplete(QUIC_CRYPTO_INVALID_VALUE_LENGTH, |
1268 "Client hello too small", nullptr); | 1269 "Client hello too small", nullptr); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1320 info->reject_reasons.push_back(source_address_token_error); | 1321 info->reject_reasons.push_back(source_address_token_error); |
1321 // No valid source address token. | 1322 // No valid source address token. |
1322 found_error = true; | 1323 found_error = true; |
1323 } | 1324 } |
1324 | 1325 |
1325 bool get_proof_failed = false; | 1326 bool get_proof_failed = false; |
1326 string serialized_config = primary_config->serialized; | 1327 string serialized_config = primary_config->serialized; |
1327 string chlo_hash; | 1328 string chlo_hash; |
1328 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); | 1329 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
1329 bool need_proof = true; | 1330 bool need_proof = true; |
1330 need_proof = !crypto_proof->chain; | 1331 need_proof = !signed_config->chain; |
1331 const QuicTag* tag_ptr; | 1332 const QuicTag* tag_ptr; |
1332 size_t num_tags; | 1333 size_t num_tags; |
1333 QuicTagVector connection_options; | 1334 QuicTagVector connection_options; |
1334 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { | 1335 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { |
1335 connection_options.assign(tag_ptr, tag_ptr + num_tags); | 1336 connection_options.assign(tag_ptr, tag_ptr + num_tags); |
1336 } | 1337 } |
1337 if (FLAGS_enable_async_get_proof) { | 1338 if (FLAGS_enable_async_get_proof) { |
1338 if (need_proof) { | 1339 if (need_proof) { |
1339 // Make an async call to GetProof and setup the callback to trampoline | 1340 // Make an async call to GetProof and setup the callback to trampoline |
1340 // back into EvaluateClientHelloAfterGetProof | 1341 // back into EvaluateClientHelloAfterGetProof |
1341 std::unique_ptr<EvaluateClientHelloCallback> cb( | 1342 std::unique_ptr<EvaluateClientHelloCallback> cb( |
1342 new EvaluateClientHelloCallback( | 1343 new EvaluateClientHelloCallback( |
1343 *this, found_error, server_ip, version, requested_config, | 1344 *this, found_error, server_ip, version, requested_config, |
1344 primary_config, crypto_proof, client_hello_state, | 1345 primary_config, signed_config, client_hello_state, |
1345 std::move(done_cb))); | 1346 std::move(done_cb))); |
1346 proof_source_->GetProof(server_ip, info->sni.as_string(), | 1347 proof_source_->GetProof(server_ip, info->sni.as_string(), |
1347 serialized_config, version, chlo_hash, | 1348 serialized_config, version, chlo_hash, |
1348 connection_options, std::move(cb)); | 1349 connection_options, std::move(cb)); |
1349 helper.DetachCallback(); | 1350 helper.DetachCallback(); |
1350 return; | 1351 return; |
1351 } | 1352 } |
1352 } | 1353 } |
1353 | 1354 |
1354 // No need to get a new proof if one was already generated. | 1355 // No need to get a new proof if one was already generated. |
1355 if (need_proof && | 1356 if (need_proof) { |
1356 !proof_source_->GetProof( | 1357 QuicCryptoProof proof; |
1357 server_ip, info->sni.as_string(), serialized_config, version, | 1358 |
1358 chlo_hash, connection_options, &crypto_proof->chain, | 1359 if (proof_source_->GetProof( |
1359 &crypto_proof->signature, &crypto_proof->cert_sct)) { | 1360 server_ip, info->sni.as_string(), serialized_config, version, |
1360 get_proof_failed = true; | 1361 chlo_hash, connection_options, &signed_config->chain, &proof)) { |
| 1362 signed_config->signature = proof.signature; |
| 1363 signed_config->cert_sct = proof.leaf_cert_scts; |
| 1364 } else { |
| 1365 get_proof_failed = true; |
| 1366 } |
1361 } | 1367 } |
1362 | 1368 |
1363 // Details are null because the synchronous version of GetProof does not | 1369 // Details are null because the synchronous version of GetProof does not |
1364 // return any stats. Eventually the synchronous codepath will be eliminated. | 1370 // return any stats. Eventually the synchronous codepath will be eliminated. |
1365 EvaluateClientHelloAfterGetProof( | 1371 EvaluateClientHelloAfterGetProof( |
1366 found_error, server_ip, version, requested_config, primary_config, | 1372 found_error, server_ip, version, requested_config, primary_config, |
1367 crypto_proof, nullptr /* proof_source_details */, get_proof_failed, | 1373 signed_config, nullptr /* proof_source_details */, get_proof_failed, |
1368 client_hello_state, std::move(done_cb)); | 1374 client_hello_state, std::move(done_cb)); |
1369 helper.DetachCallback(); | 1375 helper.DetachCallback(); |
1370 } | 1376 } |
1371 | 1377 |
1372 void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( | 1378 void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
1373 bool found_error, | 1379 bool found_error, |
1374 const IPAddress& server_ip, | 1380 const IPAddress& server_ip, |
1375 QuicVersion version, | 1381 QuicVersion version, |
1376 scoped_refptr<Config> requested_config, | 1382 scoped_refptr<Config> requested_config, |
1377 scoped_refptr<Config> primary_config, | 1383 scoped_refptr<Config> primary_config, |
1378 scoped_refptr<QuicCryptoProof> crypto_proof, | 1384 scoped_refptr<QuicSignedServerConfig> signed_config, |
1379 std::unique_ptr<ProofSource::Details> proof_source_details, | 1385 std::unique_ptr<ProofSource::Details> proof_source_details, |
1380 bool get_proof_failed, | 1386 bool get_proof_failed, |
1381 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, | 1387 scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, |
1382 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { | 1388 std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
1383 ValidateClientHelloHelper helper(client_hello_state, &done_cb); | 1389 ValidateClientHelloHelper helper(client_hello_state, &done_cb); |
1384 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; | 1390 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; |
1385 ClientHelloInfo* info = &(client_hello_state->info); | 1391 ClientHelloInfo* info = &(client_hello_state->info); |
1386 | 1392 |
1387 if (get_proof_failed) { | 1393 if (get_proof_failed) { |
1388 found_error = true; | 1394 found_error = true; |
1389 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); | 1395 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
1390 } | 1396 } |
1391 | 1397 |
1392 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { | 1398 if (!ValidateExpectedLeafCertificate(client_hello, *signed_config)) { |
1393 found_error = true; | 1399 found_error = true; |
1394 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); | 1400 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); |
1395 } | 1401 } |
1396 | 1402 |
1397 if (info->client_nonce.size() != kNonceSize) { | 1403 if (info->client_nonce.size() != kNonceSize) { |
1398 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); | 1404 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); |
1399 // Invalid client nonce. | 1405 // Invalid client nonce. |
1400 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); | 1406 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); |
1401 DVLOG(1) << "Invalid client nonce."; | 1407 DVLOG(1) << "Invalid client nonce."; |
1402 found_error = true; | 1408 found_error = true; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1509 clock->WallNow(), cached_network_params); | 1515 clock->WallNow(), cached_network_params); |
1510 } | 1516 } |
1511 | 1517 |
1512 out->set_tag(kSCUP); | 1518 out->set_tag(kSCUP); |
1513 out->SetStringPiece(kSCFG, serialized); | 1519 out->SetStringPiece(kSCFG, serialized); |
1514 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); | 1520 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); |
1515 out->SetValue(kSTTL, | 1521 out->SetValue(kSTTL, |
1516 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); | 1522 expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); |
1517 | 1523 |
1518 scoped_refptr<ProofSource::Chain> chain; | 1524 scoped_refptr<ProofSource::Chain> chain; |
1519 string signature; | 1525 QuicCryptoProof proof; |
1520 string cert_sct; | |
1521 if (!proof_source_->GetProof(server_ip, params.sni, serialized, version, | 1526 if (!proof_source_->GetProof(server_ip, params.sni, serialized, version, |
1522 chlo_hash, connection_options, &chain, | 1527 chlo_hash, connection_options, &chain, &proof)) { |
1523 &signature, &cert_sct)) { | |
1524 DVLOG(1) << "Server: failed to get proof."; | 1528 DVLOG(1) << "Server: failed to get proof."; |
1525 return false; | 1529 return false; |
1526 } | 1530 } |
1527 | 1531 |
1528 const string compressed = CompressChain( | 1532 const string compressed = CompressChain( |
1529 compressed_certs_cache, chain, params.client_common_set_hashes, | 1533 compressed_certs_cache, chain, params.client_common_set_hashes, |
1530 params.client_cached_cert_hashes, common_cert_sets); | 1534 params.client_cached_cert_hashes, common_cert_sets); |
1531 | 1535 |
1532 out->SetStringPiece(kCertificateTag, compressed); | 1536 out->SetStringPiece(kCertificateTag, compressed); |
1533 out->SetStringPiece(kPROF, signature); | 1537 out->SetStringPiece(kPROF, proof.signature); |
1534 if (params.sct_supported_by_client && enable_serving_sct_) { | 1538 if (params.sct_supported_by_client && enable_serving_sct_) { |
1535 if (cert_sct.empty()) { | 1539 if (proof.leaf_cert_scts.empty()) { |
1536 DLOG(WARNING) << "SCT is expected but it is empty. sni: " << params.sni | 1540 DLOG(WARNING) << "SCT is expected but it is empty. sni: " << params.sni |
1537 << " server_ip: " << server_ip.ToString(); | 1541 << " server_ip: " << server_ip.ToString(); |
1538 } else { | 1542 } else { |
1539 out->SetStringPiece(kCertificateSCTTag, cert_sct); | 1543 out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); |
1540 } | 1544 } |
1541 } | 1545 } |
1542 return true; | 1546 return true; |
1543 } | 1547 } |
1544 | 1548 |
1545 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1549 void QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
1546 QuicVersion version, | 1550 QuicVersion version, |
1547 StringPiece chlo_hash, | 1551 StringPiece chlo_hash, |
1548 const SourceAddressTokens& previous_source_address_tokens, | 1552 const SourceAddressTokens& previous_source_address_tokens, |
1549 const IPAddress& server_ip, | 1553 const IPAddress& server_ip, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 common_cert_sets_(common_cert_sets), | 1609 common_cert_sets_(common_cert_sets), |
1606 client_common_set_hashes_(params.client_common_set_hashes), | 1610 client_common_set_hashes_(params.client_common_set_hashes), |
1607 client_cached_cert_hashes_(params.client_cached_cert_hashes), | 1611 client_cached_cert_hashes_(params.client_cached_cert_hashes), |
1608 sct_supported_by_client_(params.sct_supported_by_client), | 1612 sct_supported_by_client_(params.sct_supported_by_client), |
1609 message_(std::move(message)), | 1613 message_(std::move(message)), |
1610 cb_(std::move(cb)) {} | 1614 cb_(std::move(cb)) {} |
1611 | 1615 |
1612 void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: | 1616 void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: |
1613 Run(bool ok, | 1617 Run(bool ok, |
1614 const scoped_refptr<ProofSource::Chain>& chain, | 1618 const scoped_refptr<ProofSource::Chain>& chain, |
1615 const string& signature, | 1619 const QuicCryptoProof& proof, |
1616 const string& leaf_cert_sct, | |
1617 std::unique_ptr<ProofSource::Details> details) { | 1620 std::unique_ptr<ProofSource::Details> details) { |
1618 config_->FinishBuildServerConfigUpdateMessage( | 1621 config_->FinishBuildServerConfigUpdateMessage( |
1619 version_, compressed_certs_cache_, common_cert_sets_, | 1622 version_, compressed_certs_cache_, common_cert_sets_, |
1620 client_common_set_hashes_, client_cached_cert_hashes_, | 1623 client_common_set_hashes_, client_cached_cert_hashes_, |
1621 sct_supported_by_client_, ok, chain, signature, leaf_cert_sct, | 1624 sct_supported_by_client_, ok, chain, proof.signature, |
1622 std::move(details), std::move(message_), std::move(cb_)); | 1625 proof.leaf_cert_scts, std::move(details), std::move(message_), |
| 1626 std::move(cb_)); |
1623 } | 1627 } |
1624 | 1628 |
1625 void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage( | 1629 void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage( |
1626 QuicVersion version, | 1630 QuicVersion version, |
1627 QuicCompressedCertsCache* compressed_certs_cache, | 1631 QuicCompressedCertsCache* compressed_certs_cache, |
1628 const CommonCertSets* common_cert_sets, | 1632 const CommonCertSets* common_cert_sets, |
1629 const string& client_common_set_hashes, | 1633 const string& client_common_set_hashes, |
1630 const string& client_cached_cert_hashes, | 1634 const string& client_cached_cert_hashes, |
1631 bool sct_supported_by_client, | 1635 bool sct_supported_by_client, |
1632 bool ok, | 1636 bool ok, |
(...skipping 30 matching lines...) Expand all Loading... |
1663 QuicWallTime now, | 1667 QuicWallTime now, |
1664 const Config& config, | 1668 const Config& config, |
1665 const CryptoHandshakeMessage& client_hello, | 1669 const CryptoHandshakeMessage& client_hello, |
1666 const ClientHelloInfo& info, | 1670 const ClientHelloInfo& info, |
1667 const CachedNetworkParameters& cached_network_params, | 1671 const CachedNetworkParameters& cached_network_params, |
1668 bool use_stateless_rejects, | 1672 bool use_stateless_rejects, |
1669 QuicConnectionId server_designated_connection_id, | 1673 QuicConnectionId server_designated_connection_id, |
1670 QuicRandom* rand, | 1674 QuicRandom* rand, |
1671 QuicCompressedCertsCache* compressed_certs_cache, | 1675 QuicCompressedCertsCache* compressed_certs_cache, |
1672 scoped_refptr<QuicCryptoNegotiatedParameters> params, | 1676 scoped_refptr<QuicCryptoNegotiatedParameters> params, |
1673 const QuicCryptoProof& crypto_proof, | 1677 const QuicSignedServerConfig& signed_config, |
1674 QuicByteCount total_framing_overhead, | 1678 QuicByteCount total_framing_overhead, |
1675 QuicByteCount chlo_packet_size, | 1679 QuicByteCount chlo_packet_size, |
1676 CryptoHandshakeMessage* out) const { | 1680 CryptoHandshakeMessage* out) const { |
1677 if (FLAGS_enable_quic_stateless_reject_support && use_stateless_rejects) { | 1681 if (FLAGS_enable_quic_stateless_reject_support && use_stateless_rejects) { |
1678 DVLOG(1) << "QUIC Crypto server config returning stateless reject " | 1682 DVLOG(1) << "QUIC Crypto server config returning stateless reject " |
1679 << "with server-designated connection ID " | 1683 << "with server-designated connection ID " |
1680 << server_designated_connection_id; | 1684 << server_designated_connection_id; |
1681 out->set_tag(kSREJ); | 1685 out->set_tag(kSREJ); |
1682 out->SetValue(kRCID, server_designated_connection_id); | 1686 out->SetValue(kRCID, server_designated_connection_id); |
1683 } else { | 1687 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
1707 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { | 1711 if (client_hello.GetStringPiece(kCCS, &client_common_set_hashes)) { |
1708 params->client_common_set_hashes = client_common_set_hashes.as_string(); | 1712 params->client_common_set_hashes = client_common_set_hashes.as_string(); |
1709 } | 1713 } |
1710 | 1714 |
1711 StringPiece client_cached_cert_hashes; | 1715 StringPiece client_cached_cert_hashes; |
1712 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { | 1716 if (client_hello.GetStringPiece(kCCRT, &client_cached_cert_hashes)) { |
1713 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); | 1717 params->client_cached_cert_hashes = client_cached_cert_hashes.as_string(); |
1714 } | 1718 } |
1715 | 1719 |
1716 const string compressed = | 1720 const string compressed = |
1717 CompressChain(compressed_certs_cache, crypto_proof.chain, | 1721 CompressChain(compressed_certs_cache, signed_config.chain, |
1718 params->client_common_set_hashes, | 1722 params->client_common_set_hashes, |
1719 params->client_cached_cert_hashes, config.common_cert_sets); | 1723 params->client_cached_cert_hashes, config.common_cert_sets); |
1720 | 1724 |
1721 DCHECK_GT(chlo_packet_size, client_hello.size()); | 1725 DCHECK_GT(chlo_packet_size, client_hello.size()); |
1722 // kREJOverheadBytes is a very rough estimate of how much of a REJ | 1726 // kREJOverheadBytes is a very rough estimate of how much of a REJ |
1723 // message is taken up by things other than the certificates. | 1727 // message is taken up by things other than the certificates. |
1724 // STK: 56 bytes | 1728 // STK: 56 bytes |
1725 // SNO: 56 bytes | 1729 // SNO: 56 bytes |
1726 // SCFG | 1730 // SCFG |
1727 // SCID: 16 bytes | 1731 // SCID: 16 bytes |
1728 // PUBS: 38 bytes | 1732 // PUBS: 38 bytes |
1729 const size_t kREJOverheadBytes = 166; | 1733 const size_t kREJOverheadBytes = 166; |
1730 // max_unverified_size is the number of bytes that the certificate chain, | 1734 // max_unverified_size is the number of bytes that the certificate chain, |
1731 // signature, and (optionally) signed certificate timestamp can consume before | 1735 // signature, and (optionally) signed certificate timestamp can consume before |
1732 // we will demand a valid source-address token. | 1736 // we will demand a valid source-address token. |
1733 const size_t max_unverified_size = | 1737 const size_t max_unverified_size = |
1734 chlo_multiplier_ * (chlo_packet_size - total_framing_overhead) - | 1738 chlo_multiplier_ * (chlo_packet_size - total_framing_overhead) - |
1735 kREJOverheadBytes; | 1739 kREJOverheadBytes; |
1736 static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes, | 1740 static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes, |
1737 "overhead calculation may underflow"); | 1741 "overhead calculation may underflow"); |
1738 bool should_return_sct = | 1742 bool should_return_sct = |
1739 params->sct_supported_by_client && enable_serving_sct_; | 1743 params->sct_supported_by_client && enable_serving_sct_; |
1740 const size_t sct_size = should_return_sct ? crypto_proof.cert_sct.size() : 0; | 1744 const size_t sct_size = should_return_sct ? signed_config.cert_sct.size() : 0; |
1741 const size_t total_size = | 1745 const size_t total_size = |
1742 crypto_proof.signature.size() + compressed.size() + sct_size; | 1746 signed_config.signature.size() + compressed.size() + sct_size; |
1743 if (info.valid_source_address_token || total_size < max_unverified_size) { | 1747 if (info.valid_source_address_token || total_size < max_unverified_size) { |
1744 out->SetStringPiece(kCertificateTag, compressed); | 1748 out->SetStringPiece(kCertificateTag, compressed); |
1745 out->SetStringPiece(kPROF, crypto_proof.signature); | 1749 out->SetStringPiece(kPROF, signed_config.signature); |
1746 if (should_return_sct) { | 1750 if (should_return_sct) { |
1747 if (crypto_proof.cert_sct.empty()) { | 1751 if (signed_config.cert_sct.empty()) { |
1748 DLOG(WARNING) << "SCT is expected but it is empty."; | 1752 DLOG(WARNING) << "SCT is expected but it is empty."; |
1749 } else { | 1753 } else { |
1750 out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct); | 1754 out->SetStringPiece(kCertificateSCTTag, signed_config.cert_sct); |
1751 } | 1755 } |
1752 } | 1756 } |
1753 } else { | 1757 } else { |
1754 DLOG(WARNING) << "Sending inchoate REJ for hostname: " << info.sni | 1758 DLOG(WARNING) << "Sending inchoate REJ for hostname: " << info.sni |
1755 << " signature: " << crypto_proof.signature.size() | 1759 << " signature: " << signed_config.signature.size() |
1756 << " cert: " << compressed.size() << " sct:" << sct_size | 1760 << " cert: " << compressed.size() << " sct:" << sct_size |
1757 << " total: " << total_size | 1761 << " total: " << total_size |
1758 << " max: " << max_unverified_size; | 1762 << " max: " << max_unverified_size; |
1759 } | 1763 } |
1760 } | 1764 } |
1761 | 1765 |
1762 string QuicCryptoServerConfig::CompressChain( | 1766 string QuicCryptoServerConfig::CompressChain( |
1763 QuicCompressedCertsCache* compressed_certs_cache, | 1767 QuicCompressedCertsCache* compressed_certs_cache, |
1764 const scoped_refptr<ProofSource::Chain>& chain, | 1768 const scoped_refptr<ProofSource::Chain>& chain, |
1765 const string& client_common_set_hashes, | 1769 const string& client_common_set_hashes, |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2227 case STRIKE_REGISTER_TIMEOUT: | 2231 case STRIKE_REGISTER_TIMEOUT: |
2228 case STRIKE_REGISTER_FAILURE: | 2232 case STRIKE_REGISTER_FAILURE: |
2229 default: | 2233 default: |
2230 QUIC_BUG << "Unexpected server nonce error: " << nonce_error; | 2234 QUIC_BUG << "Unexpected server nonce error: " << nonce_error; |
2231 return SERVER_NONCE_NOT_UNIQUE_FAILURE; | 2235 return SERVER_NONCE_NOT_UNIQUE_FAILURE; |
2232 } | 2236 } |
2233 } | 2237 } |
2234 | 2238 |
2235 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( | 2239 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( |
2236 const CryptoHandshakeMessage& client_hello, | 2240 const CryptoHandshakeMessage& client_hello, |
2237 const QuicCryptoProof& crypto_proof) const { | 2241 const QuicSignedServerConfig& signed_config) const { |
2238 if (crypto_proof.chain->certs.empty()) { | 2242 if (signed_config.chain->certs.empty()) { |
2239 return false; | 2243 return false; |
2240 } | 2244 } |
2241 | 2245 |
2242 uint64_t hash_from_client; | 2246 uint64_t hash_from_client; |
2243 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { | 2247 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { |
2244 return false; | 2248 return false; |
2245 } | 2249 } |
2246 return CryptoUtils::ComputeLeafCertHash(crypto_proof.chain->certs.at(0)) == | 2250 return CryptoUtils::ComputeLeafCertHash(signed_config.chain->certs.at(0)) == |
2247 hash_from_client; | 2251 hash_from_client; |
2248 } | 2252 } |
2249 | 2253 |
2250 bool QuicCryptoServerConfig::ClientDemandsX509Proof( | 2254 bool QuicCryptoServerConfig::ClientDemandsX509Proof( |
2251 const CryptoHandshakeMessage& client_hello) const { | 2255 const CryptoHandshakeMessage& client_hello) const { |
2252 const QuicTag* their_proof_demands; | 2256 const QuicTag* their_proof_demands; |
2253 size_t num_their_proof_demands; | 2257 size_t num_their_proof_demands; |
2254 | 2258 |
2255 if (client_hello.GetTaglist(kPDMD, &their_proof_demands, | 2259 if (client_hello.GetTaglist(kPDMD, &their_proof_demands, |
2256 &num_their_proof_demands) != QUIC_NO_ERROR) { | 2260 &num_their_proof_demands) != QUIC_NO_ERROR) { |
(...skipping 13 matching lines...) Expand all Loading... |
2270 : channel_id_enabled(false), | 2274 : channel_id_enabled(false), |
2271 is_primary(false), | 2275 is_primary(false), |
2272 primary_time(QuicWallTime::Zero()), | 2276 primary_time(QuicWallTime::Zero()), |
2273 expiry_time(QuicWallTime::Zero()), | 2277 expiry_time(QuicWallTime::Zero()), |
2274 priority(0), | 2278 priority(0), |
2275 source_address_token_boxer(nullptr) {} | 2279 source_address_token_boxer(nullptr) {} |
2276 | 2280 |
2277 QuicCryptoServerConfig::Config::~Config() { | 2281 QuicCryptoServerConfig::Config::~Config() { |
2278 } | 2282 } |
2279 | 2283 |
2280 QuicCryptoProof::QuicCryptoProof() {} | 2284 QuicSignedServerConfig::QuicSignedServerConfig() {} |
2281 QuicCryptoProof::~QuicCryptoProof() {} | 2285 QuicSignedServerConfig::~QuicSignedServerConfig() {} |
2282 | 2286 |
2283 } // namespace net | 2287 } // namespace net |
OLD | NEW |