| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <cstdint> | 6 #include <cstdint> |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <ostream> | 8 #include <ostream> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 public: | 105 public: |
| 106 CryptoServerTest() | 106 CryptoServerTest() |
| 107 : rand_(QuicRandom::GetInstance()), | 107 : rand_(QuicRandom::GetInstance()), |
| 108 client_address_(Loopback4(), 1234), | 108 client_address_(Loopback4(), 1234), |
| 109 config_(QuicCryptoServerConfig::TESTING, | 109 config_(QuicCryptoServerConfig::TESTING, |
| 110 rand_, | 110 rand_, |
| 111 CryptoTestUtils::ProofSourceForTesting()), | 111 CryptoTestUtils::ProofSourceForTesting()), |
| 112 compressed_certs_cache_( | 112 compressed_certs_cache_( |
| 113 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), | 113 QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), |
| 114 params_(new QuicCryptoNegotiatedParameters), | 114 params_(new QuicCryptoNegotiatedParameters), |
| 115 crypto_proof_(new QuicCryptoProof), | 115 signed_config_(new QuicSignedServerConfig), |
| 116 chlo_packet_size_(kDefaultMaxPacketSize) { | 116 chlo_packet_size_(kDefaultMaxPacketSize) { |
| 117 supported_versions_ = GetParam().supported_versions; | 117 supported_versions_ = GetParam().supported_versions; |
| 118 config_.set_enable_serving_sct(true); | 118 config_.set_enable_serving_sct(true); |
| 119 | 119 |
| 120 client_version_ = supported_versions_.front(); | 120 client_version_ = supported_versions_.front(); |
| 121 client_version_string_ = | 121 client_version_string_ = |
| 122 QuicUtils::TagToString(QuicVersionToQuicTag(client_version_)); | 122 QuicTagToString(QuicVersionToQuicTag(client_version_)); |
| 123 | 123 |
| 124 FLAGS_quic_require_handshake_confirmation_pre33 = false; | 124 FLAGS_quic_require_handshake_confirmation_pre33 = false; |
| 125 FLAGS_enable_quic_stateless_reject_support = | 125 FLAGS_enable_quic_stateless_reject_support = |
| 126 GetParam().enable_stateless_rejects; | 126 GetParam().enable_stateless_rejects; |
| 127 use_stateless_rejects_ = GetParam().use_stateless_rejects; | 127 use_stateless_rejects_ = GetParam().use_stateless_rejects; |
| 128 } | 128 } |
| 129 | 129 |
| 130 void SetUp() override { | 130 void SetUp() override { |
| 131 QuicCryptoServerConfig::ConfigOptions old_config_options; | 131 QuicCryptoServerConfig::ConfigOptions old_config_options; |
| 132 old_config_options.id = kOldConfigId; | 132 old_config_options.id = kOldConfigId; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 srct_hex_ = "#" + QuicUtils::HexEncode(srct); | 176 srct_hex_ = "#" + QuicUtils::HexEncode(srct); |
| 177 | 177 |
| 178 StringPiece scfg; | 178 StringPiece scfg; |
| 179 ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); | 179 ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); |
| 180 server_config_.reset(CryptoFramer::ParseMessage(scfg)); | 180 server_config_.reset(CryptoFramer::ParseMessage(scfg)); |
| 181 | 181 |
| 182 StringPiece scid; | 182 StringPiece scid; |
| 183 ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid)); | 183 ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid)); |
| 184 scid_hex_ = "#" + QuicUtils::HexEncode(scid); | 184 scid_hex_ = "#" + QuicUtils::HexEncode(scid); |
| 185 | 185 |
| 186 crypto_proof_ = scoped_refptr<QuicCryptoProof>(new QuicCryptoProof()); | 186 signed_config_ = |
| 187 DCHECK(crypto_proof_->chain.get() == nullptr); | 187 scoped_refptr<QuicSignedServerConfig>(new QuicSignedServerConfig()); |
| 188 DCHECK(signed_config_->chain.get() == nullptr); |
| 188 } | 189 } |
| 189 | 190 |
| 190 // Helper used to accept the result of ValidateClientHello and pass | 191 // Helper used to accept the result of ValidateClientHello and pass |
| 191 // it on to ProcessClientHello. | 192 // it on to ProcessClientHello. |
| 192 class ValidateCallback : public ValidateClientHelloResultCallback { | 193 class ValidateCallback : public ValidateClientHelloResultCallback { |
| 193 public: | 194 public: |
| 194 ValidateCallback(CryptoServerTest* test, | 195 ValidateCallback(CryptoServerTest* test, |
| 195 bool should_succeed, | 196 bool should_succeed, |
| 196 const char* error_substr, | 197 const char* error_substr, |
| 197 bool* called) | 198 bool* called) |
| 198 : test_(test), | 199 : test_(test), |
| 199 should_succeed_(should_succeed), | 200 should_succeed_(should_succeed), |
| 200 error_substr_(error_substr), | 201 error_substr_(error_substr), |
| 201 called_(called) { | 202 called_(called) { |
| 202 *called_ = false; | 203 *called_ = false; |
| 203 } | 204 } |
| 204 | 205 |
| 205 void Run(scoped_refptr<Result> result, | 206 void Run(scoped_refptr<Result> result, |
| 206 std::unique_ptr<ProofSource::Details> /* details */) override { | 207 std::unique_ptr<ProofSource::Details> /* details */) override { |
| 207 { | |
| 208 // Ensure that the strike register client lock is not held. | |
| 209 QuicCryptoServerConfigPeer peer(&test_->config_); | |
| 210 base::Lock* m = peer.GetStrikeRegisterClientLock(); | |
| 211 // In Chromium, we will dead lock if the lock is held by the current | |
| 212 // thread. Chromium doesn't have AssertNotHeld API call. | |
| 213 // m->AssertNotHeld(); | |
| 214 base::AutoLock lock(*m); | |
| 215 } | |
| 216 ASSERT_FALSE(*called_); | 208 ASSERT_FALSE(*called_); |
| 217 test_->ProcessValidationResult(std::move(result), should_succeed_, | 209 test_->ProcessValidationResult(std::move(result), should_succeed_, |
| 218 error_substr_); | 210 error_substr_); |
| 219 *called_ = true; | 211 *called_ = true; |
| 220 } | 212 } |
| 221 | 213 |
| 222 private: | 214 private: |
| 223 CryptoServerTest* test_; | 215 CryptoServerTest* test_; |
| 224 const bool should_succeed_; | 216 const bool should_succeed_; |
| 225 const char* const error_substr_; | 217 const char* const error_substr_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 241 ASSERT_TRUE(decoder.Decode(address.data(), address.size())); | 233 ASSERT_TRUE(decoder.Decode(address.data(), address.size())); |
| 242 EXPECT_EQ(client_address_.address(), decoder.ip()); | 234 EXPECT_EQ(client_address_.address(), decoder.ip()); |
| 243 EXPECT_EQ(client_address_.port(), decoder.port()); | 235 EXPECT_EQ(client_address_.port(), decoder.port()); |
| 244 } | 236 } |
| 245 | 237 |
| 246 void ShouldSucceed(const CryptoHandshakeMessage& message) { | 238 void ShouldSucceed(const CryptoHandshakeMessage& message) { |
| 247 bool called = false; | 239 bool called = false; |
| 248 IPAddress server_ip; | 240 IPAddress server_ip; |
| 249 config_.ValidateClientHello( | 241 config_.ValidateClientHello( |
| 250 message, client_address_.address(), server_ip, | 242 message, client_address_.address(), server_ip, |
| 251 supported_versions_.front(), &clock_, crypto_proof_, | 243 supported_versions_.front(), &clock_, signed_config_, |
| 252 std::unique_ptr<ValidateCallback>( | 244 std::unique_ptr<ValidateCallback>( |
| 253 new ValidateCallback(this, true, "", &called))); | 245 new ValidateCallback(this, true, "", &called))); |
| 254 EXPECT_TRUE(called); | 246 EXPECT_TRUE(called); |
| 255 } | 247 } |
| 256 | 248 |
| 257 void ShouldFailMentioning(const char* error_substr, | 249 void ShouldFailMentioning(const char* error_substr, |
| 258 const CryptoHandshakeMessage& message) { | 250 const CryptoHandshakeMessage& message) { |
| 259 bool called = false; | 251 bool called = false; |
| 260 ShouldFailMentioning(error_substr, message, &called); | 252 ShouldFailMentioning(error_substr, message, &called); |
| 261 EXPECT_TRUE(called); | 253 EXPECT_TRUE(called); |
| 262 } | 254 } |
| 263 | 255 |
| 264 void ShouldFailMentioning(const char* error_substr, | 256 void ShouldFailMentioning(const char* error_substr, |
| 265 const CryptoHandshakeMessage& message, | 257 const CryptoHandshakeMessage& message, |
| 266 bool* called) { | 258 bool* called) { |
| 267 IPAddress server_ip; | 259 IPAddress server_ip; |
| 268 config_.ValidateClientHello( | 260 config_.ValidateClientHello( |
| 269 message, client_address_.address(), server_ip, | 261 message, client_address_.address(), server_ip, |
| 270 supported_versions_.front(), &clock_, crypto_proof_, | 262 supported_versions_.front(), &clock_, signed_config_, |
| 271 std::unique_ptr<ValidateCallback>( | 263 std::unique_ptr<ValidateCallback>( |
| 272 new ValidateCallback(this, false, error_substr, called))); | 264 new ValidateCallback(this, false, error_substr, called))); |
| 273 } | 265 } |
| 274 | 266 |
| 275 class ProcessCallback : public ProcessClientHelloResultCallback { | 267 class ProcessCallback : public ProcessClientHelloResultCallback { |
| 276 public: | 268 public: |
| 277 ProcessCallback(scoped_refptr<ValidateCallback::Result> result, | 269 ProcessCallback(scoped_refptr<ValidateCallback::Result> result, |
| 278 bool should_succeed, | 270 bool should_succeed, |
| 279 const char* error_substr, | 271 const char* error_substr, |
| 280 bool* called, | 272 bool* called, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 bool should_succeed, | 314 bool should_succeed, |
| 323 const char* error_substr) { | 315 const char* error_substr) { |
| 324 IPAddress server_ip; | 316 IPAddress server_ip; |
| 325 QuicConnectionId server_designated_connection_id = | 317 QuicConnectionId server_designated_connection_id = |
| 326 rand_for_id_generation_.RandUint64(); | 318 rand_for_id_generation_.RandUint64(); |
| 327 bool called; | 319 bool called; |
| 328 config_.ProcessClientHello( | 320 config_.ProcessClientHello( |
| 329 result, /*reject_only=*/false, /*connection_id=*/1, server_ip, | 321 result, /*reject_only=*/false, /*connection_id=*/1, server_ip, |
| 330 client_address_, supported_versions_.front(), supported_versions_, | 322 client_address_, supported_versions_.front(), supported_versions_, |
| 331 use_stateless_rejects_, server_designated_connection_id, &clock_, rand_, | 323 use_stateless_rejects_, server_designated_connection_id, &clock_, rand_, |
| 332 &compressed_certs_cache_, params_, crypto_proof_, | 324 &compressed_certs_cache_, params_, signed_config_, |
| 333 /*total_framing_overhead=*/50, chlo_packet_size_, | 325 /*total_framing_overhead=*/50, chlo_packet_size_, |
| 334 std::unique_ptr<ProcessCallback>(new ProcessCallback( | 326 std::unique_ptr<ProcessCallback>(new ProcessCallback( |
| 335 result, should_succeed, error_substr, &called, &out_))); | 327 result, should_succeed, error_substr, &called, &out_))); |
| 336 EXPECT_TRUE(called); | 328 EXPECT_TRUE(called); |
| 337 } | 329 } |
| 338 | 330 |
| 339 string GenerateNonce() { | 331 string GenerateNonce() { |
| 340 string nonce; | 332 string nonce; |
| 341 CryptoUtils::GenerateNonce( | 333 CryptoUtils::GenerateNonce( |
| 342 clock_.WallNow(), rand_, | 334 clock_.WallNow(), rand_, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 373 ASSERT_EQ(QUIC_NO_ERROR, | 365 ASSERT_EQ(QUIC_NO_ERROR, |
| 374 out_.GetUint64(kRCID, &server_designated_connection_id)); | 366 out_.GetUint64(kRCID, &server_designated_connection_id)); |
| 375 EXPECT_EQ(rand_for_id_generation_.RandUint64(), | 367 EXPECT_EQ(rand_for_id_generation_.RandUint64(), |
| 376 server_designated_connection_id); | 368 server_designated_connection_id); |
| 377 } | 369 } |
| 378 rand_for_id_generation_.ChangeValue(); | 370 rand_for_id_generation_.ChangeValue(); |
| 379 } | 371 } |
| 380 | 372 |
| 381 void CheckRejectTag() { | 373 void CheckRejectTag() { |
| 382 if (RejectsAreStateless()) { | 374 if (RejectsAreStateless()) { |
| 383 ASSERT_EQ(kSREJ, out_.tag()) << QuicUtils::TagToString(out_.tag()); | 375 ASSERT_EQ(kSREJ, out_.tag()) << QuicTagToString(out_.tag()); |
| 384 } else { | 376 } else { |
| 385 ASSERT_EQ(kREJ, out_.tag()) << QuicUtils::TagToString(out_.tag()); | 377 ASSERT_EQ(kREJ, out_.tag()) << QuicTagToString(out_.tag()); |
| 386 } | 378 } |
| 387 } | 379 } |
| 388 | 380 |
| 389 bool RejectsAreStateless() { | 381 bool RejectsAreStateless() { |
| 390 return GetParam().enable_stateless_rejects && | 382 return GetParam().enable_stateless_rejects && |
| 391 GetParam().use_stateless_rejects; | 383 GetParam().use_stateless_rejects; |
| 392 } | 384 } |
| 393 | 385 |
| 394 string XlctHexString() { | 386 string XlctHexString() { |
| 395 uint64_t xlct = CryptoTestUtils::LeafCertHashForTesting(); | 387 uint64_t xlct = CryptoTestUtils::LeafCertHashForTesting(); |
| 396 return "#" + | 388 return "#" + |
| 397 QuicUtils::HexEncode(reinterpret_cast<char*>(&xlct), sizeof(xlct)); | 389 QuicUtils::HexEncode(reinterpret_cast<char*>(&xlct), sizeof(xlct)); |
| 398 } | 390 } |
| 399 | 391 |
| 400 protected: | 392 protected: |
| 401 QuicFlagSaver flags_; // Save/restore all QUIC flag values. | 393 QuicFlagSaver flags_; // Save/restore all QUIC flag values. |
| 402 QuicRandom* const rand_; | 394 QuicRandom* const rand_; |
| 403 MockRandom rand_for_id_generation_; | 395 MockRandom rand_for_id_generation_; |
| 404 MockClock clock_; | 396 MockClock clock_; |
| 405 IPEndPoint client_address_; | 397 IPEndPoint client_address_; |
| 406 QuicVersionVector supported_versions_; | 398 QuicVersionVector supported_versions_; |
| 407 QuicVersion client_version_; | 399 QuicVersion client_version_; |
| 408 string client_version_string_; | 400 string client_version_string_; |
| 409 QuicCryptoServerConfig config_; | 401 QuicCryptoServerConfig config_; |
| 410 QuicCompressedCertsCache compressed_certs_cache_; | 402 QuicCompressedCertsCache compressed_certs_cache_; |
| 411 QuicCryptoServerConfig::ConfigOptions config_options_; | 403 QuicCryptoServerConfig::ConfigOptions config_options_; |
| 412 scoped_refptr<QuicCryptoNegotiatedParameters> params_; | 404 scoped_refptr<QuicCryptoNegotiatedParameters> params_; |
| 413 scoped_refptr<QuicCryptoProof> crypto_proof_; | 405 scoped_refptr<QuicSignedServerConfig> signed_config_; |
| 414 CryptoHandshakeMessage out_; | 406 CryptoHandshakeMessage out_; |
| 415 uint8_t orbit_[kOrbitSize]; | 407 uint8_t orbit_[kOrbitSize]; |
| 416 bool use_stateless_rejects_; | 408 bool use_stateless_rejects_; |
| 417 size_t chlo_packet_size_; | 409 size_t chlo_packet_size_; |
| 418 | 410 |
| 419 // These strings contain hex escaped values from the server suitable for using | 411 // These strings contain hex escaped values from the server suitable for using |
| 420 // when constructing client hello messages. | 412 // when constructing client hello messages. |
| 421 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; | 413 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; |
| 422 std::unique_ptr<CryptoHandshakeMessage> server_config_; | 414 std::unique_ptr<CryptoHandshakeMessage> server_config_; |
| 423 }; | 415 }; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 } | 702 } |
| 711 | 703 |
| 712 TEST_P(CryptoServerTest, DowngradeAttack) { | 704 TEST_P(CryptoServerTest, DowngradeAttack) { |
| 713 if (supported_versions_.size() == 1) { | 705 if (supported_versions_.size() == 1) { |
| 714 // No downgrade attack is possible if the server only supports one version. | 706 // No downgrade attack is possible if the server only supports one version. |
| 715 return; | 707 return; |
| 716 } | 708 } |
| 717 // Set the client's preferred version to a supported version that | 709 // Set the client's preferred version to a supported version that |
| 718 // is not the "current" version (supported_versions_.front()). | 710 // is not the "current" version (supported_versions_.front()). |
| 719 string bad_version = | 711 string bad_version = |
| 720 QuicUtils::TagToString(QuicVersionToQuicTag(supported_versions_.back())); | 712 QuicTagToString(QuicVersionToQuicTag(supported_versions_.back())); |
| 721 | 713 |
| 722 // clang-format off | 714 // clang-format off |
| 723 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 715 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 724 "CHLO", | 716 "CHLO", |
| 725 "PDMD", "X509", | 717 "PDMD", "X509", |
| 726 "VER\0", bad_version.c_str(), | 718 "VER\0", bad_version.c_str(), |
| 727 "$padding", static_cast<int>(kClientHelloMinimumSize), | 719 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 728 nullptr); | 720 nullptr); |
| 729 // clang-format on | 721 // clang-format on |
| 730 ShouldFailMentioning("Downgrade", msg); | 722 ShouldFailMentioning("Downgrade", msg); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 "NONP", (string(1, 'X') + nonce_hex_).c_str(), | 811 "NONP", (string(1, 'X') + nonce_hex_).c_str(), |
| 820 "SNO\0", (string(1, 'X') + nonce_hex_).c_str(), | 812 "SNO\0", (string(1, 'X') + nonce_hex_).c_str(), |
| 821 "XLCT", XlctHexString().c_str(), | 813 "XLCT", XlctHexString().c_str(), |
| 822 "VER\0", client_version_string_.c_str(), | 814 "VER\0", client_version_string_.c_str(), |
| 823 "$padding", static_cast<int>(kClientHelloMinimumSize), | 815 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 824 nullptr); | 816 nullptr); |
| 825 // clang-format on | 817 // clang-format on |
| 826 ShouldSucceed(msg); | 818 ShouldSucceed(msg); |
| 827 CheckRejectTag(); | 819 CheckRejectTag(); |
| 828 | 820 |
| 829 if (client_version_ <= QUIC_VERSION_32) { | 821 const HandshakeFailureReason kRejectReasons[] = { |
| 830 const HandshakeFailureReason kRejectReasons[] = { | 822 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE}; |
| 831 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE, | 823 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 832 SERVER_NONCE_DECRYPTION_FAILURE}; | |
| 833 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); | |
| 834 } else { | |
| 835 const HandshakeFailureReason kRejectReasons[] = { | |
| 836 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, CLIENT_NONCE_INVALID_FAILURE}; | |
| 837 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); | |
| 838 }; | |
| 839 } | 824 } |
| 840 | 825 |
| 841 TEST_P(CryptoServerTest, NoServerNonce) { | 826 TEST_P(CryptoServerTest, NoServerNonce) { |
| 842 // When no server nonce is present and no strike register is configured, | 827 // When no server nonce is present and no strike register is configured, |
| 843 // the CHLO should be rejected. | 828 // the CHLO should be rejected. |
| 844 // clang-format off | 829 // clang-format off |
| 845 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 830 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 846 "CHLO", | 831 "CHLO", |
| 847 "PDMD", "X509", | 832 "PDMD", "X509", |
| 848 "AEAD", "AESG", | 833 "AEAD", "AESG", |
| 849 "KEXS", "C255", | 834 "KEXS", "C255", |
| 850 "SCID", scid_hex_.c_str(), | 835 "SCID", scid_hex_.c_str(), |
| 851 "#004b5453", srct_hex_.c_str(), | 836 "#004b5453", srct_hex_.c_str(), |
| 852 "PUBS", pub_hex_.c_str(), | 837 "PUBS", pub_hex_.c_str(), |
| 853 "NONC", nonce_hex_.c_str(), | 838 "NONC", nonce_hex_.c_str(), |
| 854 "NONP", nonce_hex_.c_str(), | 839 "NONP", nonce_hex_.c_str(), |
| 855 "XLCT", XlctHexString().c_str(), | 840 "XLCT", XlctHexString().c_str(), |
| 856 "VER\0", client_version_string_.c_str(), | 841 "VER\0", client_version_string_.c_str(), |
| 857 "$padding", static_cast<int>(kClientHelloMinimumSize), | 842 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 858 nullptr); | 843 nullptr); |
| 859 // clang-format on | 844 // clang-format on |
| 860 | 845 |
| 861 ShouldSucceed(msg); | 846 ShouldSucceed(msg); |
| 862 | 847 |
| 863 if (client_version_ <= QUIC_VERSION_32) { | 848 // Even without a server nonce, this ClientHello should be accepted in |
| 864 CheckRejectTag(); | 849 // version 33. |
| 865 const HandshakeFailureReason kRejectReasons[] = { | 850 ASSERT_EQ(kSHLO, out_.tag()); |
| 866 SERVER_NONCE_REQUIRED_FAILURE}; | 851 CheckServerHello(out_); |
| 867 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); | |
| 868 } else { | |
| 869 // Even without a server nonce, this ClientHello should be accepted in | |
| 870 // version 33. | |
| 871 ASSERT_EQ(kSHLO, out_.tag()); | |
| 872 CheckServerHello(out_); | |
| 873 } | |
| 874 } | 852 } |
| 875 | 853 |
| 876 TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { | 854 TEST_P(CryptoServerTest, ProofForSuppliedServerConfig) { |
| 877 client_address_ = IPEndPoint(Loopback6(), 1234); | 855 client_address_ = IPEndPoint(Loopback6(), 1234); |
| 878 // clang-format off | 856 // clang-format off |
| 879 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 857 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 880 "CHLO", | 858 "CHLO", |
| 881 "AEAD", "AESG", | 859 "AEAD", "AESG", |
| 882 "KEXS", "C255", | 860 "KEXS", "C255", |
| 883 "PDMD", "X509", | 861 "PDMD", "X509", |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 const HandshakeFailureReason kRejectReasons[] = { | 1091 const HandshakeFailureReason kRejectReasons[] = { |
| 1114 SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; | 1092 SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; |
| 1115 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); | 1093 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 1116 } | 1094 } |
| 1117 | 1095 |
| 1118 class CryptoServerTestOldVersion : public CryptoServerTest { | 1096 class CryptoServerTestOldVersion : public CryptoServerTest { |
| 1119 public: | 1097 public: |
| 1120 void SetUp() override { | 1098 void SetUp() override { |
| 1121 client_version_ = supported_versions_.back(); | 1099 client_version_ = supported_versions_.back(); |
| 1122 client_version_string_ = | 1100 client_version_string_ = |
| 1123 QuicUtils::TagToString(QuicVersionToQuicTag(client_version_)); | 1101 QuicTagToString(QuicVersionToQuicTag(client_version_)); |
| 1124 CryptoServerTest::SetUp(); | 1102 CryptoServerTest::SetUp(); |
| 1125 } | 1103 } |
| 1126 }; | 1104 }; |
| 1127 | 1105 |
| 1128 TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) { | 1106 TEST_P(CryptoServerTestOldVersion, ServerIgnoresXlct) { |
| 1129 // clang-format off | 1107 // clang-format off |
| 1130 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 1108 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 1131 "CHLO", | 1109 "CHLO", |
| 1132 "PDMD", "X509", | 1110 "PDMD", "X509", |
| 1133 "AEAD", "AESG", | 1111 "AEAD", "AESG", |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 // clang-format on | 1145 // clang-format on |
| 1168 // If replay protection isn't disabled, then | 1146 // If replay protection isn't disabled, then |
| 1169 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false | 1147 // QuicCryptoServerConfig::EvaluateClientHello will leave info.unique as false |
| 1170 // and cause ProcessClientHello to exit early (and generate a REJ message). | 1148 // and cause ProcessClientHello to exit early (and generate a REJ message). |
| 1171 config_.set_replay_protection(false); | 1149 config_.set_replay_protection(false); |
| 1172 | 1150 |
| 1173 ShouldSucceed(msg); | 1151 ShouldSucceed(msg); |
| 1174 EXPECT_EQ(kSHLO, out_.tag()); | 1152 EXPECT_EQ(kSHLO, out_.tag()); |
| 1175 } | 1153 } |
| 1176 | 1154 |
| 1177 class AsyncStrikeServerVerificationTest : public CryptoServerTest { | |
| 1178 protected: | |
| 1179 AsyncStrikeServerVerificationTest() {} | |
| 1180 | |
| 1181 void SetUp() override { | |
| 1182 const string kOrbit = "12345678"; | |
| 1183 config_options_.orbit = kOrbit; | |
| 1184 strike_register_client_ = new DelayedVerifyStrikeRegisterClient( | |
| 1185 10000, // strike_register_max_entries | |
| 1186 static_cast<uint32_t>(clock_.WallNow().ToUNIXSeconds()), | |
| 1187 60, // strike_register_window_secs | |
| 1188 reinterpret_cast<const uint8_t*>(kOrbit.c_str()), | |
| 1189 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | |
| 1190 config_.SetStrikeRegisterClient(strike_register_client_); | |
| 1191 ASSERT_NO_FATAL_FAILURE(CryptoServerTest::SetUp()); | |
| 1192 strike_register_client_->StartDelayingVerification(); | |
| 1193 } | |
| 1194 | |
| 1195 DelayedVerifyStrikeRegisterClient* strike_register_client_; | |
| 1196 }; | |
| 1197 | |
| 1198 TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { | |
| 1199 // This tests async validation with a strike register works. | |
| 1200 // clang-format off | |
| 1201 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | |
| 1202 "CHLO", | |
| 1203 "PDMD", "X509", | |
| 1204 "AEAD", "AESG", | |
| 1205 "KEXS", "C255", | |
| 1206 "SCID", scid_hex_.c_str(), | |
| 1207 "#004b5453", srct_hex_.c_str(), | |
| 1208 "PUBS", pub_hex_.c_str(), | |
| 1209 "NONC", nonce_hex_.c_str(), | |
| 1210 "VER\0", client_version_string_.c_str(), | |
| 1211 "$padding", static_cast<int>(kClientHelloMinimumSize), | |
| 1212 nullptr); | |
| 1213 // clang-format on | |
| 1214 | |
| 1215 // Clear the message tag. | |
| 1216 out_.set_tag(0); | |
| 1217 | |
| 1218 bool called = false; | |
| 1219 IPAddress server_ip; | |
| 1220 config_.ValidateClientHello( | |
| 1221 msg, client_address_.address(), server_ip, client_version_, &clock_, | |
| 1222 crypto_proof_, std::unique_ptr<ValidateCallback>( | |
| 1223 new ValidateCallback(this, true, "", &called))); | |
| 1224 // The verification request was queued. | |
| 1225 ASSERT_FALSE(called); | |
| 1226 EXPECT_EQ(0u, out_.tag()); | |
| 1227 EXPECT_EQ(1, strike_register_client_->PendingVerifications()); | |
| 1228 | |
| 1229 // Continue processing the verification request. | |
| 1230 strike_register_client_->RunPendingVerifications(); | |
| 1231 ASSERT_TRUE(called); | |
| 1232 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | |
| 1233 // The message should be accepted now. | |
| 1234 EXPECT_EQ(kSHLO, out_.tag()); | |
| 1235 | |
| 1236 // Rejected if replayed. | |
| 1237 config_.ValidateClientHello( | |
| 1238 msg, client_address_.address(), server_ip, client_version_, &clock_, | |
| 1239 crypto_proof_, std::unique_ptr<ValidateCallback>( | |
| 1240 new ValidateCallback(this, true, "", &called))); | |
| 1241 // The verification request was queued. | |
| 1242 ASSERT_FALSE(called); | |
| 1243 EXPECT_EQ(1, strike_register_client_->PendingVerifications()); | |
| 1244 | |
| 1245 strike_register_client_->RunPendingVerifications(); | |
| 1246 ASSERT_TRUE(called); | |
| 1247 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | |
| 1248 // The message should be rejected now. | |
| 1249 CheckRejectTag(); | |
| 1250 } | |
| 1251 | |
| 1252 TEST_P(AsyncStrikeServerVerificationTest, RequireHandshakeCofirmationPre33) { | |
| 1253 FLAGS_quic_require_handshake_confirmation = false; | |
| 1254 FLAGS_quic_require_handshake_confirmation_pre33 = true; | |
| 1255 // clang-format off | |
| 1256 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | |
| 1257 "CHLO", | |
| 1258 "PDMD", "X509", | |
| 1259 "AEAD", "AESG", | |
| 1260 "KEXS", "C255", | |
| 1261 "SNI", "foobar1.example.com", | |
| 1262 "SCID", scid_hex_.c_str(), | |
| 1263 "#004b5453", srct_hex_.c_str(), | |
| 1264 "PUBS", pub_hex_.c_str(), | |
| 1265 "NONC", nonce_hex_.c_str(), | |
| 1266 "VER\0", client_version_string_.c_str(), | |
| 1267 "XLCT", XlctHexString().c_str(), | |
| 1268 "$padding", static_cast<int>(kClientHelloMinimumSize), | |
| 1269 nullptr); | |
| 1270 // clang-format on | |
| 1271 | |
| 1272 ShouldSucceed(msg); | |
| 1273 | |
| 1274 if (client_version_ <= QUIC_VERSION_32) { | |
| 1275 // clang-format off | |
| 1276 const HandshakeFailureReason kRejectReasons[] = { | |
| 1277 SERVER_NONCE_REQUIRED_FAILURE | |
| 1278 }; | |
| 1279 // clang-format on | |
| 1280 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); | |
| 1281 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | |
| 1282 } else { | |
| 1283 // version 33. | |
| 1284 ASSERT_EQ(kSHLO, out_.tag()); | |
| 1285 CheckServerHello(out_); | |
| 1286 } | |
| 1287 } | |
| 1288 | |
| 1289 } // namespace test | 1155 } // namespace test |
| 1290 } // namespace net | 1156 } // namespace net |
| OLD | NEW |