| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/tools/quic/stateless_rejector.h" | 5 #include "net/tools/quic/stateless_rejector.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" |
| 10 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 11 #include "net/quic/core/crypto/crypto_handshake_message.h" | 12 #include "net/quic/core/crypto/crypto_handshake_message.h" |
| 12 #include "net/quic/core/crypto/proof_source.h" | 13 #include "net/quic/core/crypto/proof_source.h" |
| 13 #include "net/quic/core/quic_utils.h" | 14 #include "net/quic/core/quic_utils.h" |
| 14 #include "net/quic/test_tools/crypto_test_utils.h" | 15 #include "net/quic/test_tools/crypto_test_utils.h" |
| 15 #include "net/quic/test_tools/quic_crypto_server_config_peer.h" | 16 #include "net/quic/test_tools/quic_crypto_server_config_peer.h" |
| 16 #include "net/quic/test_tools/quic_test_utils.h" | 17 #include "net/quic/test_tools/quic_test_utils.h" |
| 17 | 18 |
| 18 using std::ostream; | 19 using std::ostream; |
| 19 using std::string; | 20 using std::string; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 class StatelessRejectorTest : public ::testing::TestWithParam<TestParams> { | 71 class StatelessRejectorTest : public ::testing::TestWithParam<TestParams> { |
| 71 public: | 72 public: |
| 72 StatelessRejectorTest() | 73 StatelessRejectorTest() |
| 73 : proof_source_(CryptoTestUtils::ProofSourceForTesting()), | 74 : proof_source_(CryptoTestUtils::ProofSourceForTesting()), |
| 74 config_(QuicCryptoServerConfig::TESTING, | 75 config_(QuicCryptoServerConfig::TESTING, |
| 75 QuicRandom::GetInstance(), | 76 QuicRandom::GetInstance(), |
| 76 CryptoTestUtils::ProofSourceForTesting()), | 77 CryptoTestUtils::ProofSourceForTesting()), |
| 77 config_peer_(&config_), | 78 config_peer_(&config_), |
| 78 compressed_certs_cache_( | 79 compressed_certs_cache_( |
| 79 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), | 80 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), |
| 80 rejector_(GetParam().version, | 81 rejector_(base::MakeUnique<StatelessRejector>( |
| 81 AllSupportedVersions(), | 82 GetParam().version, |
| 82 &config_, | 83 AllSupportedVersions(), |
| 83 &compressed_certs_cache_, | 84 &config_, |
| 84 &clock_, | 85 &compressed_certs_cache_, |
| 85 QuicRandom::GetInstance(), | 86 &clock_, |
| 86 kDefaultMaxPacketSize, | 87 QuicRandom::GetInstance(), |
| 87 IPEndPoint(net::test::Loopback4(), 12345), | 88 kDefaultMaxPacketSize, |
| 88 IPEndPoint(net::test::Loopback4(), 443)) { | 89 IPEndPoint(net::test::Loopback4(), 12345), |
| 90 IPEndPoint(net::test::Loopback4(), 443))) { |
| 89 FLAGS_enable_quic_stateless_reject_support = | 91 FLAGS_enable_quic_stateless_reject_support = |
| 90 GetParam().flags == ENABLED || GetParam().flags == CHEAP_DISABLED; | 92 GetParam().flags == ENABLED || GetParam().flags == CHEAP_DISABLED; |
| 91 FLAGS_quic_use_cheap_stateless_rejects = | 93 FLAGS_quic_use_cheap_stateless_rejects = |
| 92 GetParam().flags == ENABLED || GetParam().flags == STATELESS_DISABLED; | 94 GetParam().flags == ENABLED || GetParam().flags == STATELESS_DISABLED; |
| 93 | 95 |
| 94 // Add a new primary config. | 96 // Add a new primary config. |
| 95 std::unique_ptr<CryptoHandshakeMessage> msg(config_.AddDefaultConfig( | 97 std::unique_ptr<CryptoHandshakeMessage> msg(config_.AddDefaultConfig( |
| 96 QuicRandom::GetInstance(), &clock_, config_options_)); | 98 QuicRandom::GetInstance(), &clock_, config_options_)); |
| 97 | 99 |
| 98 // Save the server config. | 100 // Save the server config. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 120 SourceAddressTokens previous_tokens; | 122 SourceAddressTokens previous_tokens; |
| 121 IPAddress ip = net::test::Loopback4(); | 123 IPAddress ip = net::test::Loopback4(); |
| 122 MockRandom rand; | 124 MockRandom rand; |
| 123 string stk = config_peer_.NewSourceAddressToken( | 125 string stk = config_peer_.NewSourceAddressToken( |
| 124 config_peer_.GetPrimaryConfig()->id, previous_tokens, ip, &rand, | 126 config_peer_.GetPrimaryConfig()->id, previous_tokens, ip, &rand, |
| 125 clock_.WallNow(), nullptr); | 127 clock_.WallNow(), nullptr); |
| 126 stk_hex_ = "#" + QuicUtils::HexEncode(stk); | 128 stk_hex_ = "#" + QuicUtils::HexEncode(stk); |
| 127 } | 129 } |
| 128 | 130 |
| 129 protected: | 131 protected: |
| 132 class ProcessDoneCallback : public StatelessRejector::ProcessDoneCallback { |
| 133 public: |
| 134 explicit ProcessDoneCallback(StatelessRejectorTest* test) : test_(test) {} |
| 135 void Run(std::unique_ptr<StatelessRejector> rejector) override { |
| 136 test_->rejector_ = std::move(rejector); |
| 137 } |
| 138 |
| 139 private: |
| 140 StatelessRejectorTest* test_; |
| 141 }; |
| 142 |
| 130 QuicFlagSaver flags_; // Save/restore all QUIC flag values. | 143 QuicFlagSaver flags_; // Save/restore all QUIC flag values. |
| 144 |
| 131 std::unique_ptr<ProofSource> proof_source_; | 145 std::unique_ptr<ProofSource> proof_source_; |
| 132 MockClock clock_; | 146 MockClock clock_; |
| 133 QuicCryptoServerConfig config_; | 147 QuicCryptoServerConfig config_; |
| 134 QuicCryptoServerConfigPeer config_peer_; | 148 QuicCryptoServerConfigPeer config_peer_; |
| 135 QuicCompressedCertsCache compressed_certs_cache_; | 149 QuicCompressedCertsCache compressed_certs_cache_; |
| 136 QuicCryptoServerConfig::ConfigOptions config_options_; | 150 QuicCryptoServerConfig::ConfigOptions config_options_; |
| 137 StatelessRejector rejector_; | 151 std::unique_ptr<StatelessRejector> rejector_; |
| 138 | 152 |
| 139 // Values used in CHLO messages | 153 // Values used in CHLO messages |
| 140 string scid_hex_; | 154 string scid_hex_; |
| 141 string nonc_hex_; | 155 string nonc_hex_; |
| 142 string pubs_hex_; | 156 string pubs_hex_; |
| 143 string ver_hex_; | 157 string ver_hex_; |
| 144 string stk_hex_; | 158 string stk_hex_; |
| 145 }; | 159 }; |
| 146 | 160 |
| 147 INSTANTIATE_TEST_CASE_P(Flags, | 161 INSTANTIATE_TEST_CASE_P(Flags, |
| 148 StatelessRejectorTest, | 162 StatelessRejectorTest, |
| 149 ::testing::ValuesIn(GetTestParams()), | 163 ::testing::ValuesIn(GetTestParams()), |
| 150 TestParamToString); | 164 TestParamToString); |
| 151 | 165 |
| 152 TEST_P(StatelessRejectorTest, InvalidChlo) { | 166 TEST_P(StatelessRejectorTest, InvalidChlo) { |
| 153 // clang-format off | 167 // clang-format off |
| 154 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 168 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 155 "CHLO", | 169 "CHLO", |
| 156 "PDMD", "X509", | 170 "PDMD", "X509", |
| 157 "COPT", "SREJ", | 171 "COPT", "SREJ", |
| 158 nullptr); | 172 nullptr); |
| 159 // clang-format on | 173 // clang-format on |
| 160 rejector_.OnChlo(GetParam().version, kConnectionId, | 174 rejector_->OnChlo(GetParam().version, kConnectionId, |
| 161 kServerDesignateConnectionId, client_hello); | 175 kServerDesignateConnectionId, client_hello); |
| 162 | 176 |
| 163 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { | 177 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { |
| 164 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_.state()); | 178 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state()); |
| 165 return; | 179 return; |
| 166 } | 180 } |
| 167 | 181 |
| 168 EXPECT_EQ(StatelessRejector::FAILED, rejector_.state()); | 182 // The StatelessRejector is undecided - proceed with async processing |
| 169 EXPECT_EQ(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, rejector_.error()); | 183 ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state()); |
| 184 StatelessRejector::Process(std::move(rejector_), |
| 185 base::MakeUnique<ProcessDoneCallback>(this)); |
| 186 |
| 187 EXPECT_EQ(StatelessRejector::FAILED, rejector_->state()); |
| 188 EXPECT_EQ(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, rejector_->error()); |
| 170 } | 189 } |
| 171 | 190 |
| 172 TEST_P(StatelessRejectorTest, ValidChloWithoutSrejSupport) { | 191 TEST_P(StatelessRejectorTest, ValidChloWithoutSrejSupport) { |
| 173 // clang-format off | 192 // clang-format off |
| 174 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 193 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 175 "CHLO", | 194 "CHLO", |
| 176 "PDMD", "X509", | 195 "PDMD", "X509", |
| 177 "AEAD", "AESG", | 196 "AEAD", "AESG", |
| 178 "KEXS", "C255", | 197 "KEXS", "C255", |
| 179 "PUBS", pubs_hex_.c_str(), | 198 "PUBS", pubs_hex_.c_str(), |
| 180 "NONC", nonc_hex_.c_str(), | 199 "NONC", nonc_hex_.c_str(), |
| 181 "VER\0", ver_hex_.c_str(), | 200 "VER\0", ver_hex_.c_str(), |
| 182 "$padding", static_cast<int>(kClientHelloMinimumSize), | 201 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 183 nullptr); | 202 nullptr); |
| 184 // clang-format on | 203 // clang-format on |
| 185 | 204 |
| 186 rejector_.OnChlo(GetParam().version, kConnectionId, | 205 rejector_->OnChlo(GetParam().version, kConnectionId, |
| 187 kServerDesignateConnectionId, client_hello); | 206 kServerDesignateConnectionId, client_hello); |
| 188 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_.state()); | 207 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state()); |
| 189 } | 208 } |
| 190 | 209 |
| 191 TEST_P(StatelessRejectorTest, RejectChlo) { | 210 TEST_P(StatelessRejectorTest, RejectChlo) { |
| 192 // clang-format off | 211 // clang-format off |
| 193 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 212 const CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 194 "CHLO", | 213 "CHLO", |
| 195 "PDMD", "X509", | 214 "PDMD", "X509", |
| 196 "AEAD", "AESG", | 215 "AEAD", "AESG", |
| 197 "KEXS", "C255", | 216 "KEXS", "C255", |
| 198 "COPT", "SREJ", | 217 "COPT", "SREJ", |
| 199 "SCID", scid_hex_.c_str(), | 218 "SCID", scid_hex_.c_str(), |
| 200 "PUBS", pubs_hex_.c_str(), | 219 "PUBS", pubs_hex_.c_str(), |
| 201 "NONC", nonc_hex_.c_str(), | 220 "NONC", nonc_hex_.c_str(), |
| 202 "#004b5453", stk_hex_.c_str(), | 221 "#004b5453", stk_hex_.c_str(), |
| 203 "VER\0", ver_hex_.c_str(), | 222 "VER\0", ver_hex_.c_str(), |
| 204 "$padding", static_cast<int>(kClientHelloMinimumSize), | 223 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 205 nullptr); | 224 nullptr); |
| 206 // clang-format on | 225 // clang-format on |
| 207 | 226 |
| 208 rejector_.OnChlo(GetParam().version, kConnectionId, | 227 rejector_->OnChlo(GetParam().version, kConnectionId, |
| 209 kServerDesignateConnectionId, client_hello); | 228 kServerDesignateConnectionId, client_hello); |
| 210 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { | 229 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { |
| 211 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_.state()); | 230 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state()); |
| 212 return; | 231 return; |
| 213 } | 232 } |
| 214 ASSERT_EQ(StatelessRejector::REJECTED, rejector_.state()); | 233 |
| 215 const CryptoHandshakeMessage& reply = rejector_.reply(); | 234 // The StatelessRejector is undecided - proceed with async processing |
| 235 ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state()); |
| 236 StatelessRejector::Process(std::move(rejector_), |
| 237 base::MakeUnique<ProcessDoneCallback>(this)); |
| 238 |
| 239 ASSERT_EQ(StatelessRejector::REJECTED, rejector_->state()); |
| 240 const CryptoHandshakeMessage& reply = rejector_->reply(); |
| 216 EXPECT_EQ(kSREJ, reply.tag()); | 241 EXPECT_EQ(kSREJ, reply.tag()); |
| 217 const uint32_t* reject_reasons; | 242 const uint32_t* reject_reasons; |
| 218 size_t num_reject_reasons; | 243 size_t num_reject_reasons; |
| 219 EXPECT_EQ(QUIC_NO_ERROR, | 244 EXPECT_EQ(QUIC_NO_ERROR, |
| 220 reply.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons)); | 245 reply.GetTaglist(kRREJ, &reject_reasons, &num_reject_reasons)); |
| 221 EXPECT_EQ(1u, num_reject_reasons); | 246 EXPECT_EQ(1u, num_reject_reasons); |
| 222 EXPECT_EQ(INVALID_EXPECTED_LEAF_CERTIFICATE, | 247 EXPECT_EQ(INVALID_EXPECTED_LEAF_CERTIFICATE, |
| 223 static_cast<HandshakeFailureReason>(reject_reasons[0])); | 248 static_cast<HandshakeFailureReason>(reject_reasons[0])); |
| 224 } | 249 } |
| 225 | 250 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 "SCID", scid_hex_.c_str(), | 263 "SCID", scid_hex_.c_str(), |
| 239 "PUBS", pubs_hex_.c_str(), | 264 "PUBS", pubs_hex_.c_str(), |
| 240 "NONC", nonc_hex_.c_str(), | 265 "NONC", nonc_hex_.c_str(), |
| 241 "#004b5453", stk_hex_.c_str(), | 266 "#004b5453", stk_hex_.c_str(), |
| 242 "VER\0", ver_hex_.c_str(), | 267 "VER\0", ver_hex_.c_str(), |
| 243 "XLCT", xlct_hex.c_str(), | 268 "XLCT", xlct_hex.c_str(), |
| 244 "$padding", static_cast<int>(kClientHelloMinimumSize), | 269 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 245 nullptr); | 270 nullptr); |
| 246 // clang-format on | 271 // clang-format on |
| 247 | 272 |
| 248 rejector_.OnChlo(GetParam().version, kConnectionId, | 273 rejector_->OnChlo(GetParam().version, kConnectionId, |
| 249 kServerDesignateConnectionId, client_hello); | 274 kServerDesignateConnectionId, client_hello); |
| 250 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { | 275 if (GetParam().flags != ENABLED || GetParam().version <= QUIC_VERSION_32) { |
| 251 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_.state()); | 276 EXPECT_EQ(StatelessRejector::UNSUPPORTED, rejector_->state()); |
| 252 return; | 277 return; |
| 253 } | 278 } |
| 254 EXPECT_EQ(StatelessRejector::ACCEPTED, rejector_.state()); | 279 |
| 280 // The StatelessRejector is undecided - proceed with async processing |
| 281 ASSERT_EQ(StatelessRejector::UNKNOWN, rejector_->state()); |
| 282 StatelessRejector::Process(std::move(rejector_), |
| 283 base::MakeUnique<ProcessDoneCallback>(this)); |
| 284 |
| 285 EXPECT_EQ(StatelessRejector::ACCEPTED, rejector_->state()); |
| 255 } | 286 } |
| 256 | 287 |
| 257 } // namespace | 288 } // namespace |
| 258 } // namespace test | 289 } // namespace test |
| 259 } // namespace net | 290 } // namespace net |
| OLD | NEW |