| 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) { |
| 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)) != |
| 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 |