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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 helper.Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD"); | 687 helper.Fail(QUIC_UNSUPPORTED_PROOF_DEMAND, "Missing or invalid PDMD"); |
688 return; | 688 return; |
689 } | 689 } |
690 DCHECK(proof_source_.get()); | 690 DCHECK(proof_source_.get()); |
691 string chlo_hash; | 691 string chlo_hash; |
692 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash, | 692 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash, |
693 Perspective::IS_SERVER); | 693 Perspective::IS_SERVER); |
694 | 694 |
695 // No need to get a new proof if one was already generated. | 695 // No need to get a new proof if one was already generated. |
696 if (!signed_config->chain) { | 696 if (!signed_config->chain) { |
697 const QuicTag* tag_ptr; | |
698 size_t num_tags; | |
699 QuicTagVector connection_options; | 697 QuicTagVector connection_options; |
700 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { | 698 client_hello.GetTaglist(kCOPT, &connection_options); |
701 connection_options.assign(tag_ptr, tag_ptr + num_tags); | |
702 } | |
703 std::unique_ptr<ProcessClientHelloCallback> cb( | 699 std::unique_ptr<ProcessClientHelloCallback> cb( |
704 new ProcessClientHelloCallback( | 700 new ProcessClientHelloCallback( |
705 this, validate_chlo_result, reject_only, connection_id, | 701 this, validate_chlo_result, reject_only, connection_id, |
706 client_address, version, supported_versions, use_stateless_rejects, | 702 client_address, version, supported_versions, use_stateless_rejects, |
707 server_designated_connection_id, clock, rand, | 703 server_designated_connection_id, clock, rand, |
708 compressed_certs_cache, params, signed_config, | 704 compressed_certs_cache, params, signed_config, |
709 total_framing_overhead, chlo_packet_size, requested_config, | 705 total_framing_overhead, chlo_packet_size, requested_config, |
710 primary_config, std::move(done_cb))); | 706 primary_config, std::move(done_cb))); |
711 proof_source_->GetProof(server_address, info.sni.as_string(), | 707 proof_source_->GetProof(server_address, info.sni.as_string(), |
712 primary_config->serialized, version, chlo_hash, | 708 primary_config->serialized, version, chlo_hash, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 std::move(proof_source_details)); | 779 std::move(proof_source_details)); |
784 return; | 780 return; |
785 } | 781 } |
786 | 782 |
787 if (reject_only) { | 783 if (reject_only) { |
788 helper.Succeed(std::move(out), std::move(out_diversification_nonce), | 784 helper.Succeed(std::move(out), std::move(out_diversification_nonce), |
789 std::move(proof_source_details)); | 785 std::move(proof_source_details)); |
790 return; | 786 return; |
791 } | 787 } |
792 | 788 |
793 const QuicTag* their_aeads; | 789 QuicTagVector their_aeads; |
794 const QuicTag* their_key_exchanges; | 790 QuicTagVector their_key_exchanges; |
795 size_t num_their_aeads, num_their_key_exchanges; | 791 if (client_hello.GetTaglist(kAEAD, &their_aeads) != QUIC_NO_ERROR || |
796 if (client_hello.GetTaglist(kAEAD, &their_aeads, &num_their_aeads) != | 792 client_hello.GetTaglist(kKEXS, &their_key_exchanges) != QUIC_NO_ERROR || |
797 QUIC_NO_ERROR || | 793 their_aeads.size() != 1 || their_key_exchanges.size() != 1) { |
798 client_hello.GetTaglist(kKEXS, &their_key_exchanges, | |
799 &num_their_key_exchanges) != QUIC_NO_ERROR || | |
800 num_their_aeads != 1 || num_their_key_exchanges != 1) { | |
801 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 794 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
802 "Missing or invalid AEAD or KEXS"); | 795 "Missing or invalid AEAD or KEXS"); |
803 return; | 796 return; |
804 } | 797 } |
805 | 798 |
806 size_t key_exchange_index; | 799 size_t key_exchange_index; |
807 if (!FindMutualQuicTag(requested_config->aead, their_aeads, num_their_aeads, | 800 if (!FindMutualQuicTag(requested_config->aead, their_aeads.data(), |
808 ¶ms->aead, nullptr) || | 801 their_aeads.size(), ¶ms->aead, nullptr) || |
809 !FindMutualQuicTag(requested_config->kexs, their_key_exchanges, | 802 !FindMutualQuicTag(requested_config->kexs, their_key_exchanges.data(), |
810 num_their_key_exchanges, ¶ms->key_exchange, | 803 their_key_exchanges.size(), ¶ms->key_exchange, |
811 &key_exchange_index)) { | 804 &key_exchange_index)) { |
812 helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS"); | 805 helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS"); |
813 return; | 806 return; |
814 } | 807 } |
815 | 808 |
816 if (!requested_config->tb_key_params.empty()) { | 809 if (!requested_config->tb_key_params.empty()) { |
817 const QuicTag* their_tbkps; | 810 QuicTagVector their_tbkps; |
818 size_t num_their_tbkps; | 811 switch (client_hello.GetTaglist(kTBKP, &their_tbkps)) { |
819 switch (client_hello.GetTaglist(kTBKP, &their_tbkps, &num_their_tbkps)) { | |
820 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | 812 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
821 break; | 813 break; |
822 case QUIC_NO_ERROR: | 814 case QUIC_NO_ERROR: |
823 if (FindMutualQuicTag(requested_config->tb_key_params, their_tbkps, | 815 if (FindMutualQuicTag(requested_config->tb_key_params, |
824 num_their_tbkps, ¶ms->token_binding_key_param, | 816 their_tbkps.data(), their_tbkps.size(), |
825 nullptr)) { | 817 ¶ms->token_binding_key_param, nullptr)) { |
826 break; | 818 break; |
827 } | 819 } |
828 default: | 820 default: |
829 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 821 helper.Fail(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
830 "Invalid Token Binding key parameter"); | 822 "Invalid Token Binding key parameter"); |
831 return; | 823 return; |
832 } | 824 } |
833 } | 825 } |
834 | 826 |
835 QuicStringPiece public_value; | 827 QuicStringPiece public_value; |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1259 found_error = true; | 1251 found_error = true; |
1260 } | 1252 } |
1261 | 1253 |
1262 bool get_proof_failed = false; | 1254 bool get_proof_failed = false; |
1263 string serialized_config = primary_config->serialized; | 1255 string serialized_config = primary_config->serialized; |
1264 string chlo_hash; | 1256 string chlo_hash; |
1265 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash, | 1257 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash, |
1266 Perspective::IS_SERVER); | 1258 Perspective::IS_SERVER); |
1267 bool need_proof = true; | 1259 bool need_proof = true; |
1268 need_proof = !signed_config->chain; | 1260 need_proof = !signed_config->chain; |
1269 const QuicTag* tag_ptr; | |
1270 size_t num_tags; | |
1271 QuicTagVector connection_options; | 1261 QuicTagVector connection_options; |
1272 if (client_hello.GetTaglist(kCOPT, &tag_ptr, &num_tags) == QUIC_NO_ERROR) { | 1262 client_hello.GetTaglist(kCOPT, &connection_options); |
1273 connection_options.assign(tag_ptr, tag_ptr + num_tags); | |
1274 } | |
1275 | 1263 |
1276 if (need_proof) { | 1264 if (need_proof) { |
1277 // Make an async call to GetProof and setup the callback to trampoline | 1265 // Make an async call to GetProof and setup the callback to trampoline |
1278 // back into EvaluateClientHelloAfterGetProof | 1266 // back into EvaluateClientHelloAfterGetProof |
1279 std::unique_ptr<EvaluateClientHelloCallback> cb( | 1267 std::unique_ptr<EvaluateClientHelloCallback> cb( |
1280 new EvaluateClientHelloCallback( | 1268 new EvaluateClientHelloCallback( |
1281 *this, found_error, server_address.host(), version, | 1269 *this, found_error, server_address.host(), version, |
1282 requested_config, primary_config, signed_config, client_hello_state, | 1270 requested_config, primary_config, signed_config, client_hello_state, |
1283 std::move(done_cb))); | 1271 std::move(done_cb))); |
1284 proof_source_->GetProof(server_address, info->sni.as_string(), | 1272 proof_source_->GetProof(server_address, info->sni.as_string(), |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1616 | 1604 |
1617 config->priority = protobuf->priority(); | 1605 config->priority = protobuf->priority(); |
1618 | 1606 |
1619 QuicStringPiece scid; | 1607 QuicStringPiece scid; |
1620 if (!msg->GetStringPiece(kSCID, &scid)) { | 1608 if (!msg->GetStringPiece(kSCID, &scid)) { |
1621 QUIC_LOG(WARNING) << "Server config message is missing SCID"; | 1609 QUIC_LOG(WARNING) << "Server config message is missing SCID"; |
1622 return nullptr; | 1610 return nullptr; |
1623 } | 1611 } |
1624 config->id = scid.as_string(); | 1612 config->id = scid.as_string(); |
1625 | 1613 |
1626 const QuicTag* aead_tags; | 1614 if (msg->GetTaglist(kAEAD, &(config->aead)) != QUIC_NO_ERROR) { |
Nico
2017/05/27 00:34:32
Nit: no parens
Ryan Hamilton
2017/05/27 00:39:54
Done.
| |
1627 size_t aead_len; | |
1628 if (msg->GetTaglist(kAEAD, &aead_tags, &aead_len) != QUIC_NO_ERROR) { | |
1629 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; | 1615 QUIC_LOG(WARNING) << "Server config message is missing AEAD"; |
1630 return nullptr; | 1616 return nullptr; |
1631 } | 1617 } |
1632 config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); | |
1633 | 1618 |
1634 const QuicTag* kexs_tags; | 1619 QuicTagVector kexs_tags; |
1635 size_t kexs_len; | 1620 if (msg->GetTaglist(kKEXS, &kexs_tags) != QUIC_NO_ERROR) { |
1636 if (msg->GetTaglist(kKEXS, &kexs_tags, &kexs_len) != QUIC_NO_ERROR) { | |
1637 QUIC_LOG(WARNING) << "Server config message is missing KEXS"; | 1621 QUIC_LOG(WARNING) << "Server config message is missing KEXS"; |
1638 return nullptr; | 1622 return nullptr; |
1639 } | 1623 } |
1640 | 1624 |
1641 const QuicTag* tbkp_tags; | |
1642 size_t tbkp_len; | |
1643 QuicErrorCode err; | 1625 QuicErrorCode err; |
1644 if ((err = msg->GetTaglist(kTBKP, &tbkp_tags, &tbkp_len)) != | 1626 if ((err = msg->GetTaglist(kTBKP, &(config->tb_key_params))) != |
Nico
2017/05/27 00:34:32
Ditto
Ryan Hamilton
2017/05/27 00:39:53
Done.
| |
1645 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && | 1627 QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND && |
1646 err != QUIC_NO_ERROR) { | 1628 err != QUIC_NO_ERROR) { |
1647 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; | 1629 QUIC_LOG(WARNING) << "Server config message is missing or has invalid TBKP"; |
1648 return nullptr; | 1630 return nullptr; |
1649 } | 1631 } |
1650 config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); | |
1651 | 1632 |
1652 QuicStringPiece orbit; | 1633 QuicStringPiece orbit; |
1653 if (!msg->GetStringPiece(kORBT, &orbit)) { | 1634 if (!msg->GetStringPiece(kORBT, &orbit)) { |
1654 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; | 1635 QUIC_LOG(WARNING) << "Server config message is missing ORBT"; |
1655 return nullptr; | 1636 return nullptr; |
1656 } | 1637 } |
1657 | 1638 |
1658 if (orbit.size() != kOrbitSize) { | 1639 if (orbit.size() != kOrbitSize) { |
1659 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." | 1640 QUIC_LOG(WARNING) << "Orbit value in server config is the wrong length." |
1660 " Got " | 1641 " Got " |
1661 << orbit.size() << " want " << kOrbitSize; | 1642 << orbit.size() << " want " << kOrbitSize; |
1662 return nullptr; | 1643 return nullptr; |
1663 } | 1644 } |
1664 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); | 1645 static_assert(sizeof(config->orbit) == kOrbitSize, "incorrect orbit size"); |
1665 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); | 1646 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
1666 | 1647 |
1667 if (kexs_len != protobuf->key_size()) { | 1648 if (kexs_tags.size() != protobuf->key_size()) { |
1668 QUIC_LOG(WARNING) << "Server config has " << kexs_len | 1649 QUIC_LOG(WARNING) << "Server config has " << kexs_tags.size() |
1669 << " key exchange methods configured, but " | 1650 << " key exchange methods configured, but " |
1670 << protobuf->key_size() << " private keys"; | 1651 << protobuf->key_size() << " private keys"; |
1671 return nullptr; | 1652 return nullptr; |
1672 } | 1653 } |
1673 | 1654 |
1674 const QuicTag* proof_demand_tags; | 1655 QuicTagVector proof_demand_tags; |
1675 size_t num_proof_demand_tags; | 1656 if (msg->GetTaglist(kPDMD, &proof_demand_tags) == QUIC_NO_ERROR) { |
1676 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == | 1657 for (QuicTag tag : proof_demand_tags) { |
1677 QUIC_NO_ERROR) { | 1658 if (tag == kCHID) { |
1678 for (size_t i = 0; i < num_proof_demand_tags; i++) { | |
1679 if (proof_demand_tags[i] == kCHID) { | |
1680 config->channel_id_enabled = true; | 1659 config->channel_id_enabled = true; |
1681 break; | 1660 break; |
1682 } | 1661 } |
1683 } | 1662 } |
1684 } | 1663 } |
1685 | 1664 |
1686 for (size_t i = 0; i < kexs_len; i++) { | 1665 for (size_t i = 0; i < kexs_tags.size(); i++) { |
1687 const QuicTag tag = kexs_tags[i]; | 1666 const QuicTag tag = kexs_tags[i]; |
1688 string private_key; | 1667 string private_key; |
1689 | 1668 |
1690 config->kexs.push_back(tag); | 1669 config->kexs.push_back(tag); |
1691 | 1670 |
1692 for (size_t j = 0; j < protobuf->key_size(); j++) { | 1671 for (size_t j = 0; j < protobuf->key_size(); j++) { |
1693 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); | 1672 const QuicServerConfigProtobuf::PrivateKey& key = protobuf->key(i); |
1694 if (key.tag() == tag) { | 1673 if (key.tag() == tag) { |
1695 private_key = key.private_key(); | 1674 private_key = key.private_key(); |
1696 break; | 1675 break; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1934 | 1913 |
1935 uint64_t hash_from_client; | 1914 uint64_t hash_from_client; |
1936 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { | 1915 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { |
1937 return false; | 1916 return false; |
1938 } | 1917 } |
1939 return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client; | 1918 return CryptoUtils::ComputeLeafCertHash(certs.at(0)) == hash_from_client; |
1940 } | 1919 } |
1941 | 1920 |
1942 bool QuicCryptoServerConfig::ClientDemandsX509Proof( | 1921 bool QuicCryptoServerConfig::ClientDemandsX509Proof( |
1943 const CryptoHandshakeMessage& client_hello) const { | 1922 const CryptoHandshakeMessage& client_hello) const { |
1944 const QuicTag* their_proof_demands; | 1923 QuicTagVector their_proof_demands; |
1945 size_t num_their_proof_demands; | |
1946 | 1924 |
1947 if (client_hello.GetTaglist(kPDMD, &their_proof_demands, | 1925 if (client_hello.GetTaglist(kPDMD, &their_proof_demands) != QUIC_NO_ERROR) { |
1948 &num_their_proof_demands) != QUIC_NO_ERROR) { | |
1949 return false; | 1926 return false; |
1950 } | 1927 } |
1951 | 1928 |
1952 for (size_t i = 0; i < num_their_proof_demands; i++) { | 1929 for (const QuicTag tag : their_proof_demands) { |
1953 switch (their_proof_demands[i]) { | 1930 if (tag == kX509) { |
1954 case kX509: | 1931 return true; |
1955 return true; | |
1956 } | 1932 } |
1957 } | 1933 } |
1958 return false; | 1934 return false; |
1959 } | 1935 } |
1960 | 1936 |
1961 QuicCryptoServerConfig::Config::Config() | 1937 QuicCryptoServerConfig::Config::Config() |
1962 : channel_id_enabled(false), | 1938 : channel_id_enabled(false), |
1963 is_primary(false), | 1939 is_primary(false), |
1964 primary_time(QuicWallTime::Zero()), | 1940 primary_time(QuicWallTime::Zero()), |
1965 expiry_time(QuicWallTime::Zero()), | 1941 expiry_time(QuicWallTime::Zero()), |
1966 priority(0), | 1942 priority(0), |
1967 source_address_token_boxer(nullptr) {} | 1943 source_address_token_boxer(nullptr) {} |
1968 | 1944 |
1969 QuicCryptoServerConfig::Config::~Config() {} | 1945 QuicCryptoServerConfig::Config::~Config() {} |
1970 | 1946 |
1971 QuicSignedServerConfig::QuicSignedServerConfig() {} | 1947 QuicSignedServerConfig::QuicSignedServerConfig() {} |
1972 QuicSignedServerConfig::~QuicSignedServerConfig() {} | 1948 QuicSignedServerConfig::~QuicSignedServerConfig() {} |
1973 | 1949 |
1974 } // namespace net | 1950 } // namespace net |
OLD | NEW |