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