| 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 <ostream> |
| 6 #include <vector> |
| 7 |
| 5 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 6 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 7 #include "crypto/secure_hash.h" | 10 #include "crypto/secure_hash.h" |
| 8 #include "net/quic/crypto/crypto_utils.h" | 11 #include "net/quic/crypto/crypto_utils.h" |
| 9 #include "net/quic/crypto/quic_crypto_server_config.h" | 12 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 10 #include "net/quic/crypto/quic_random.h" | 13 #include "net/quic/crypto/quic_random.h" |
| 14 #include "net/quic/quic_flags.h" |
| 11 #include "net/quic/quic_socket_address_coder.h" | 15 #include "net/quic/quic_socket_address_coder.h" |
| 12 #include "net/quic/quic_utils.h" | 16 #include "net/quic/quic_utils.h" |
| 13 #include "net/quic/test_tools/crypto_test_utils.h" | 17 #include "net/quic/test_tools/crypto_test_utils.h" |
| 14 #include "net/quic/test_tools/delayed_verify_strike_register_client.h" | 18 #include "net/quic/test_tools/delayed_verify_strike_register_client.h" |
| 15 #include "net/quic/test_tools/mock_clock.h" | 19 #include "net/quic/test_tools/mock_clock.h" |
| 16 #include "net/quic/test_tools/mock_random.h" | 20 #include "net/quic/test_tools/mock_random.h" |
| 17 #include "net/quic/test_tools/quic_test_utils.h" | 21 #include "net/quic/test_tools/quic_test_utils.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 23 |
| 20 using base::StringPiece; | 24 using base::StringPiece; |
| 25 using std::ostream; |
| 21 using std::string; | 26 using std::string; |
| 27 using std::vector; |
| 22 | 28 |
| 23 namespace net { | 29 namespace net { |
| 24 namespace test { | 30 namespace test { |
| 25 | 31 |
| 26 class QuicCryptoServerConfigPeer { | 32 class QuicCryptoServerConfigPeer { |
| 27 public: | 33 public: |
| 28 explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config) | 34 explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config) |
| 29 : server_config_(server_config) {} | 35 : server_config_(server_config) {} |
| 30 | 36 |
| 31 base::Lock* GetStrikeRegisterClientLock() { | 37 base::Lock* GetStrikeRegisterClientLock() { |
| 32 return &server_config_->strike_register_client_lock_; | 38 return &server_config_->strike_register_client_lock_; |
| 33 } | 39 } |
| 34 | 40 |
| 35 private: | 41 private: |
| 36 QuicCryptoServerConfig* server_config_; | 42 QuicCryptoServerConfig* server_config_; |
| 37 }; | 43 }; |
| 38 | 44 |
| 39 class CryptoServerTest : public ::testing::Test { | 45 // Run tests with combinations of |
| 46 // {FLAGS_use_early_return_when_verifying_chlo, |
| 47 // FLAGS_send_quic_crypto_reject_reason}. |
| 48 struct TestParams { |
| 49 TestParams(bool use_early_return_when_verifying_chlo, |
| 50 bool send_quic_crypto_reject_reason) |
| 51 : use_early_return_when_verifying_chlo( |
| 52 use_early_return_when_verifying_chlo), |
| 53 send_quic_crypto_reject_reason(send_quic_crypto_reject_reason) { |
| 54 } |
| 55 |
| 56 friend ostream& operator<<(ostream& os, const TestParams& p) { |
| 57 os << "{ use_early_return_when_verifying_chlo: " |
| 58 << p.use_early_return_when_verifying_chlo |
| 59 << " send_quic_crypto_reject_reason: " |
| 60 << p.send_quic_crypto_reject_reason << " }"; |
| 61 return os; |
| 62 } |
| 63 |
| 64 bool use_early_return_when_verifying_chlo; |
| 65 bool send_quic_crypto_reject_reason; |
| 66 }; |
| 67 |
| 68 // Constructs various test permutations. |
| 69 vector<TestParams> GetTestParams() { |
| 70 vector<TestParams> params; |
| 71 params.push_back(TestParams(false, false)); |
| 72 params.push_back(TestParams(false, true)); |
| 73 params.push_back(TestParams(true, false)); |
| 74 params.push_back(TestParams(true, true)); |
| 75 return params; |
| 76 } |
| 77 |
| 78 class CryptoServerTest : public ::testing::TestWithParam<TestParams> { |
| 40 public: | 79 public: |
| 41 CryptoServerTest() | 80 CryptoServerTest() |
| 42 : rand_(QuicRandom::GetInstance()), | 81 : rand_(QuicRandom::GetInstance()), |
| 43 client_address_(Loopback4(), 1234), | 82 client_address_(Loopback4(), 1234), |
| 44 config_(QuicCryptoServerConfig::TESTING, rand_) { | 83 config_(QuicCryptoServerConfig::TESTING, rand_) { |
| 45 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); | 84 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); |
| 46 supported_versions_ = QuicSupportedVersions(); | 85 supported_versions_ = QuicSupportedVersions(); |
| 47 client_version_ = QuicUtils::TagToString( | 86 client_version_ = QuicUtils::TagToString( |
| 48 QuicVersionToQuicTag(supported_versions_.front())); | 87 QuicVersionToQuicTag(supported_versions_.front())); |
| 88 |
| 89 FLAGS_use_early_return_when_verifying_chlo = |
| 90 GetParam().use_early_return_when_verifying_chlo; |
| 91 FLAGS_send_quic_crypto_reject_reason = |
| 92 GetParam().send_quic_crypto_reject_reason; |
| 49 } | 93 } |
| 50 | 94 |
| 51 virtual void SetUp() { | 95 virtual void SetUp() { |
| 52 scoped_ptr<CryptoHandshakeMessage> msg( | 96 scoped_ptr<CryptoHandshakeMessage> msg( |
| 53 config_.AddDefaultConfig(rand_, &clock_, | 97 config_.AddDefaultConfig(rand_, &clock_, |
| 54 config_options_)); | 98 config_options_)); |
| 55 | 99 |
| 56 StringPiece orbit; | 100 StringPiece orbit; |
| 57 CHECK(msg->GetStringPiece(kORBT, &orbit)); | 101 CHECK(msg->GetStringPiece(kORBT, &orbit)); |
| 58 CHECK_EQ(sizeof(orbit_), orbit.size()); | 102 CHECK_EQ(sizeof(orbit_), orbit.size()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 71 "KEXS", "C255", | 115 "KEXS", "C255", |
| 72 "PUBS", pub_hex_.c_str(), | 116 "PUBS", pub_hex_.c_str(), |
| 73 "NONC", nonce_hex_.c_str(), | 117 "NONC", nonce_hex_.c_str(), |
| 74 "VER\0", client_version_.data(), | 118 "VER\0", client_version_.data(), |
| 75 "$padding", static_cast<int>(kClientHelloMinimumSize), | 119 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 76 NULL); | 120 NULL); |
| 77 ShouldSucceed(client_hello); | 121 ShouldSucceed(client_hello); |
| 78 // The message should be rejected because the source-address token is | 122 // The message should be rejected because the source-address token is |
| 79 // missing. | 123 // missing. |
| 80 ASSERT_EQ(kREJ, out_.tag()); | 124 ASSERT_EQ(kREJ, out_.tag()); |
| 125 const HandshakeFailureReason kRejectReasons[] = { |
| 126 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 127 }; |
| 128 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 81 | 129 |
| 82 StringPiece srct; | 130 StringPiece srct; |
| 83 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); | 131 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); |
| 84 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); | 132 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); |
| 85 | 133 |
| 86 StringPiece scfg; | 134 StringPiece scfg; |
| 87 ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); | 135 ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); |
| 88 server_config_.reset(CryptoFramer::ParseMessage(scfg)); | 136 server_config_.reset(CryptoFramer::ParseMessage(scfg)); |
| 89 | 137 |
| 90 StringPiece scid; | 138 StringPiece scid; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 260 |
| 213 string GenerateNonce() { | 261 string GenerateNonce() { |
| 214 string nonce; | 262 string nonce; |
| 215 CryptoUtils::GenerateNonce( | 263 CryptoUtils::GenerateNonce( |
| 216 clock_.WallNow(), rand_, | 264 clock_.WallNow(), rand_, |
| 217 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), | 265 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), |
| 218 &nonce); | 266 &nonce); |
| 219 return nonce; | 267 return nonce; |
| 220 } | 268 } |
| 221 | 269 |
| 270 void CheckRejectReasons( |
| 271 const HandshakeFailureReason* expected_handshake_failures, |
| 272 size_t expected_count) { |
| 273 const QuicTag* reject_reason_tags; |
| 274 size_t num_reject_reasons; |
| 275 QuicErrorCode error_code = out_.GetTaglist( |
| 276 kRejectReason, &reject_reason_tags, &num_reject_reasons); |
| 277 if (!FLAGS_send_quic_crypto_reject_reason) { |
| 278 ASSERT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error_code); |
| 279 return; |
| 280 } |
| 281 ASSERT_EQ(QUIC_NO_ERROR, error_code); |
| 282 |
| 283 if (FLAGS_use_early_return_when_verifying_chlo) { |
| 284 EXPECT_EQ(1u, num_reject_reasons); |
| 285 } else { |
| 286 EXPECT_EQ(expected_count, num_reject_reasons); |
| 287 } |
| 288 for (size_t i = 0; i < num_reject_reasons; ++i) { |
| 289 EXPECT_EQ(expected_handshake_failures[i], reject_reason_tags[i]); |
| 290 } |
| 291 } |
| 292 |
| 222 protected: | 293 protected: |
| 223 QuicRandom* const rand_; | 294 QuicRandom* const rand_; |
| 224 MockClock clock_; | 295 MockClock clock_; |
| 225 const IPEndPoint client_address_; | 296 const IPEndPoint client_address_; |
| 226 QuicVersionVector supported_versions_; | 297 QuicVersionVector supported_versions_; |
| 227 string client_version_; | 298 string client_version_; |
| 228 QuicCryptoServerConfig config_; | 299 QuicCryptoServerConfig config_; |
| 229 QuicCryptoServerConfig::ConfigOptions config_options_; | 300 QuicCryptoServerConfig::ConfigOptions config_options_; |
| 230 QuicCryptoNegotiatedParameters params_; | 301 QuicCryptoNegotiatedParameters params_; |
| 231 CryptoHandshakeMessage out_; | 302 CryptoHandshakeMessage out_; |
| 232 uint8 orbit_[kOrbitSize]; | 303 uint8 orbit_[kOrbitSize]; |
| 233 | 304 |
| 234 // These strings contain hex escaped values from the server suitable for | 305 // These strings contain hex escaped values from the server suitable for |
| 235 // passing to |InchoateClientHello| when constructing client hello messages. | 306 // passing to |InchoateClientHello| when constructing client hello messages. |
| 236 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; | 307 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; |
| 237 scoped_ptr<CryptoHandshakeMessage> server_config_; | 308 scoped_ptr<CryptoHandshakeMessage> server_config_; |
| 238 }; | 309 }; |
| 239 | 310 |
| 240 TEST_F(CryptoServerTest, BadSNI) { | 311 // Run all CryptoServerTest with all combinations of |
| 312 // FLAGS_use_early_return_when_verifying_chlo and |
| 313 // FLAGS_send_quic_crypto_reject_reason. |
| 314 INSTANTIATE_TEST_CASE_P(CryptoServerTests, |
| 315 CryptoServerTest, |
| 316 ::testing::ValuesIn(GetTestParams())); |
| 317 |
| 318 TEST_P(CryptoServerTest, BadSNI) { |
| 241 static const char* kBadSNIs[] = { | 319 static const char* kBadSNIs[] = { |
| 242 "", | 320 "", |
| 243 "foo", | 321 "foo", |
| 244 "#00", | 322 "#00", |
| 245 "#ff00", | 323 "#ff00", |
| 246 "127.0.0.1", | 324 "127.0.0.1", |
| 247 "ffee::1", | 325 "ffee::1", |
| 248 }; | 326 }; |
| 249 | 327 |
| 250 string client_version = QuicUtils::TagToString( | 328 string client_version = QuicUtils::TagToString( |
| 251 QuicVersionToQuicTag(supported_versions_.front())); | 329 QuicVersionToQuicTag(supported_versions_.front())); |
| 252 | 330 |
| 253 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { | 331 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { |
| 254 ShouldFailMentioning("SNI", InchoateClientHello( | 332 ShouldFailMentioning("SNI", InchoateClientHello( |
| 255 "CHLO", | 333 "CHLO", |
| 256 "SNI", kBadSNIs[i], | 334 "SNI", kBadSNIs[i], |
| 257 "VER\0", client_version.data(), | 335 "VER\0", client_version.data(), |
| 258 NULL)); | 336 NULL)); |
| 337 const HandshakeFailureReason kRejectReasons[] = { |
| 338 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 339 }; |
| 340 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 259 } | 341 } |
| 260 } | 342 } |
| 261 | 343 |
| 262 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. | 344 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. |
| 263 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { | 345 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { |
| 264 // Check that the server replies with a default certificate when no SNI is | 346 // Check that the server replies with a default certificate when no SNI is |
| 265 // specified. | 347 // specified. |
| 266 ShouldSucceed(InchoateClientHello( | 348 ShouldSucceed(InchoateClientHello( |
| 267 "CHLO", | 349 "CHLO", |
| 268 "AEAD", "AESG", | 350 "AEAD", "AESG", |
| 269 "KEXS", "C255", | 351 "KEXS", "C255", |
| 270 "SCID", scid_hex_.c_str(), | 352 "SCID", scid_hex_.c_str(), |
| 271 "#004b5453", srct_hex_.c_str(), | 353 "#004b5453", srct_hex_.c_str(), |
| 272 "PUBS", pub_hex_.c_str(), | 354 "PUBS", pub_hex_.c_str(), |
| 273 "NONC", nonce_hex_.c_str(), | 355 "NONC", nonce_hex_.c_str(), |
| 274 "$padding", static_cast<int>(kClientHelloMinimumSize), | 356 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 275 "PDMD", "X509", | 357 "PDMD", "X509", |
| 276 "VER\0", client_version_.data(), | 358 "VER\0", client_version_.data(), |
| 277 NULL)); | 359 NULL)); |
| 278 | 360 |
| 279 StringPiece cert, proof; | 361 StringPiece cert, proof; |
| 280 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); | 362 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); |
| 281 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); | 363 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); |
| 282 EXPECT_NE(0u, cert.size()); | 364 EXPECT_NE(0u, cert.size()); |
| 283 EXPECT_NE(0u, proof.size()); | 365 EXPECT_NE(0u, proof.size()); |
| 366 const HandshakeFailureReason kRejectReasons[] = { |
| 367 CLIENT_NONCE_UNKNOWN_FAILURE |
| 368 }; |
| 369 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 284 } | 370 } |
| 285 | 371 |
| 286 TEST_F(CryptoServerTest, TooSmall) { | 372 TEST_P(CryptoServerTest, TooSmall) { |
| 287 ShouldFailMentioning("too small", CryptoTestUtils::Message( | 373 ShouldFailMentioning("too small", CryptoTestUtils::Message( |
| 288 "CHLO", | 374 "CHLO", |
| 289 "VER\0", client_version_.data(), | 375 "VER\0", client_version_.data(), |
| 290 NULL)); | 376 NULL)); |
| 377 const HandshakeFailureReason kRejectReasons[] = { |
| 378 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 379 }; |
| 380 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 291 } | 381 } |
| 292 | 382 |
| 293 TEST_F(CryptoServerTest, BadSourceAddressToken) { | 383 TEST_P(CryptoServerTest, BadSourceAddressToken) { |
| 294 // Invalid source-address tokens should be ignored. | 384 // Invalid source-address tokens should be ignored. |
| 295 static const char* kBadSourceAddressTokens[] = { | 385 static const char* kBadSourceAddressTokens[] = { |
| 296 "", | 386 "", |
| 297 "foo", | 387 "foo", |
| 298 "#0000", | 388 "#0000", |
| 299 "#0000000000000000000000000000000000000000", | 389 "#0000000000000000000000000000000000000000", |
| 300 }; | 390 }; |
| 301 | 391 |
| 302 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { | 392 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { |
| 303 ShouldSucceed(InchoateClientHello( | 393 ShouldSucceed(InchoateClientHello( |
| 304 "CHLO", | 394 "CHLO", |
| 305 "STK", kBadSourceAddressTokens[i], | 395 "STK", kBadSourceAddressTokens[i], |
| 306 "VER\0", client_version_.data(), | 396 "VER\0", client_version_.data(), |
| 307 NULL)); | 397 NULL)); |
| 398 const HandshakeFailureReason kRejectReasons[] = { |
| 399 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 400 }; |
| 401 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 308 } | 402 } |
| 309 } | 403 } |
| 310 | 404 |
| 311 TEST_F(CryptoServerTest, BadClientNonce) { | 405 TEST_P(CryptoServerTest, BadClientNonce) { |
| 312 // Invalid nonces should be ignored. | 406 // Invalid nonces should be ignored. |
| 313 static const char* kBadNonces[] = { | 407 static const char* kBadNonces[] = { |
| 314 "", | 408 "", |
| 315 "#0000", | 409 "#0000", |
| 316 "#0000000000000000000000000000000000000000", | 410 "#0000000000000000000000000000000000000000", |
| 317 }; | 411 }; |
| 318 | 412 |
| 319 for (size_t i = 0; i < arraysize(kBadNonces); i++) { | 413 for (size_t i = 0; i < arraysize(kBadNonces); i++) { |
| 320 ShouldSucceed(InchoateClientHello( | 414 ShouldSucceed(InchoateClientHello( |
| 321 "CHLO", | 415 "CHLO", |
| 322 "NONC", kBadNonces[i], | 416 "NONC", kBadNonces[i], |
| 323 "VER\0", client_version_.data(), | 417 "VER\0", client_version_.data(), |
| 324 NULL)); | 418 NULL)); |
| 419 const HandshakeFailureReason kRejectReasons[] = { |
| 420 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 421 }; |
| 422 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 325 } | 423 } |
| 326 } | 424 } |
| 327 | 425 |
| 328 TEST_F(CryptoServerTest, DowngradeAttack) { | 426 TEST_P(CryptoServerTest, DowngradeAttack) { |
| 329 if (supported_versions_.size() == 1) { | 427 if (supported_versions_.size() == 1) { |
| 330 // No downgrade attack is possible if the server only supports one version. | 428 // No downgrade attack is possible if the server only supports one version. |
| 331 return; | 429 return; |
| 332 } | 430 } |
| 333 // Set the client's preferred version to a supported version that | 431 // Set the client's preferred version to a supported version that |
| 334 // is not the "current" version (supported_versions_.front()). | 432 // is not the "current" version (supported_versions_.front()). |
| 335 string bad_version = QuicUtils::TagToString( | 433 string bad_version = QuicUtils::TagToString( |
| 336 QuicVersionToQuicTag(supported_versions_.back())); | 434 QuicVersionToQuicTag(supported_versions_.back())); |
| 337 | 435 |
| 338 ShouldFailMentioning("Downgrade", InchoateClientHello( | 436 ShouldFailMentioning("Downgrade", InchoateClientHello( |
| 339 "CHLO", | 437 "CHLO", |
| 340 "VER\0", bad_version.data(), | 438 "VER\0", bad_version.data(), |
| 341 NULL)); | 439 NULL)); |
| 440 const HandshakeFailureReason kRejectReasons[] = { |
| 441 SERVER_CONFIG_INCHOATE_HELLO_FAILURE |
| 442 }; |
| 443 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 342 } | 444 } |
| 343 | 445 |
| 344 TEST_F(CryptoServerTest, ReplayProtection) { | 446 TEST_P(CryptoServerTest, CorruptServerConfig) { |
| 447 // This tests corrupted server config. |
| 448 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 449 "CHLO", |
| 450 "AEAD", "AESG", |
| 451 "KEXS", "C255", |
| 452 "SCID", (string(1, 'X') + scid_hex_).c_str(), |
| 453 "#004b5453", srct_hex_.c_str(), |
| 454 "PUBS", pub_hex_.c_str(), |
| 455 "NONC", nonce_hex_.c_str(), |
| 456 "VER\0", client_version_.data(), |
| 457 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 458 NULL); |
| 459 ShouldSucceed(msg); |
| 460 ASSERT_EQ(kREJ, out_.tag()); |
| 461 const HandshakeFailureReason kRejectReasons[] = { |
| 462 SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE |
| 463 }; |
| 464 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 465 } |
| 466 |
| 467 TEST_P(CryptoServerTest, CorruptSourceAddressToken) { |
| 468 // This tests corrupted source address token. |
| 469 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 470 "CHLO", |
| 471 "AEAD", "AESG", |
| 472 "KEXS", "C255", |
| 473 "SCID", scid_hex_.c_str(), |
| 474 "#004b5453", (string(1, 'X') + srct_hex_).c_str(), |
| 475 "PUBS", pub_hex_.c_str(), |
| 476 "NONC", nonce_hex_.c_str(), |
| 477 "VER\0", client_version_.data(), |
| 478 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 479 NULL); |
| 480 ShouldSucceed(msg); |
| 481 ASSERT_EQ(kREJ, out_.tag()); |
| 482 const HandshakeFailureReason kRejectReasons[] = { |
| 483 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE |
| 484 }; |
| 485 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 486 } |
| 487 |
| 488 TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) { |
| 489 // This test corrupts client nonce and source address token. |
| 490 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 491 "CHLO", |
| 492 "AEAD", "AESG", |
| 493 "KEXS", "C255", |
| 494 "SCID", scid_hex_.c_str(), |
| 495 "#004b5453", (string(1, 'X') + srct_hex_).c_str(), |
| 496 "PUBS", pub_hex_.c_str(), |
| 497 "NONC", (string(1, 'X') + nonce_hex_).c_str(), |
| 498 "VER\0", client_version_.data(), |
| 499 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 500 NULL); |
| 501 ShouldSucceed(msg); |
| 502 ASSERT_EQ(kREJ, out_.tag()); |
| 503 const HandshakeFailureReason kRejectReasons[] = { |
| 504 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 505 CLIENT_NONCE_INVALID_FAILURE |
| 506 }; |
| 507 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 508 } |
| 509 |
| 510 TEST_P(CryptoServerTest, CorruptMultipleTags) { |
| 511 // This test corrupts client nonce, server nonce and source address token. |
| 512 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 513 "CHLO", |
| 514 "AEAD", "AESG", |
| 515 "KEXS", "C255", |
| 516 "SCID", scid_hex_.c_str(), |
| 517 "#004b5453", (string(1, 'X') + srct_hex_).c_str(), |
| 518 "PUBS", pub_hex_.c_str(), |
| 519 "NONC", (string(1, 'X') + nonce_hex_).c_str(), |
| 520 "SNO\0", (string(1, 'X') + nonce_hex_).c_str(), |
| 521 "VER\0", client_version_.data(), |
| 522 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 523 NULL); |
| 524 ShouldSucceed(msg); |
| 525 ASSERT_EQ(kREJ, out_.tag()); |
| 526 const HandshakeFailureReason kRejectReasons[] = { |
| 527 SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 528 CLIENT_NONCE_INVALID_FAILURE, |
| 529 SERVER_NONCE_DECRYPTION_FAILURE, |
| 530 }; |
| 531 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 532 } |
| 533 |
| 534 TEST_P(CryptoServerTest, ReplayProtection) { |
| 345 // This tests that disabling replay protection works. | 535 // This tests that disabling replay protection works. |
| 346 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 536 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 347 "CHLO", | 537 "CHLO", |
| 348 "AEAD", "AESG", | 538 "AEAD", "AESG", |
| 349 "KEXS", "C255", | 539 "KEXS", "C255", |
| 350 "SCID", scid_hex_.c_str(), | 540 "SCID", scid_hex_.c_str(), |
| 351 "#004b5453", srct_hex_.c_str(), | 541 "#004b5453", srct_hex_.c_str(), |
| 352 "PUBS", pub_hex_.c_str(), | 542 "PUBS", pub_hex_.c_str(), |
| 353 "NONC", nonce_hex_.c_str(), | 543 "NONC", nonce_hex_.c_str(), |
| 354 "VER\0", client_version_.data(), | 544 "VER\0", client_version_.data(), |
| 355 "$padding", static_cast<int>(kClientHelloMinimumSize), | 545 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 356 NULL); | 546 NULL); |
| 357 ShouldSucceed(msg); | 547 ShouldSucceed(msg); |
| 358 // The message should be rejected because the strike-register is still | 548 // The message should be rejected because the strike-register is still |
| 359 // quiescent. | 549 // quiescent. |
| 360 ASSERT_EQ(kREJ, out_.tag()); | 550 ASSERT_EQ(kREJ, out_.tag()); |
| 361 | 551 |
| 552 const HandshakeFailureReason kRejectReasons[] = { |
| 553 CLIENT_NONCE_UNKNOWN_FAILURE |
| 554 }; |
| 555 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 556 |
| 362 config_.set_replay_protection(false); | 557 config_.set_replay_protection(false); |
| 363 | 558 |
| 364 ShouldSucceed(msg); | 559 ShouldSucceed(msg); |
| 365 // The message should be accepted now. | 560 // The message should be accepted now. |
| 366 ASSERT_EQ(kSHLO, out_.tag()); | 561 ASSERT_EQ(kSHLO, out_.tag()); |
| 367 CheckServerHello(out_); | 562 CheckServerHello(out_); |
| 368 | 563 |
| 369 ShouldSucceed(msg); | 564 ShouldSucceed(msg); |
| 370 // The message should accepted twice when replay protection is off. | 565 // The message should accepted twice when replay protection is off. |
| 371 ASSERT_EQ(kSHLO, out_.tag()); | 566 ASSERT_EQ(kSHLO, out_.tag()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 EXPECT_TRUE(0 == memcmp(digest, scid_str.data(), sizeof(digest))); | 637 EXPECT_TRUE(0 == memcmp(digest, scid_str.data(), sizeof(digest))); |
| 443 } | 638 } |
| 444 | 639 |
| 445 class CryptoServerTestNoConfig : public CryptoServerTest { | 640 class CryptoServerTestNoConfig : public CryptoServerTest { |
| 446 public: | 641 public: |
| 447 virtual void SetUp() { | 642 virtual void SetUp() { |
| 448 // Deliberately don't add a config so that we can test this situation. | 643 // Deliberately don't add a config so that we can test this situation. |
| 449 } | 644 } |
| 450 }; | 645 }; |
| 451 | 646 |
| 452 TEST_F(CryptoServerTestNoConfig, DontCrash) { | 647 TEST_P(CryptoServerTestNoConfig, DontCrash) { |
| 453 ShouldFailMentioning("No config", InchoateClientHello( | 648 ShouldFailMentioning("No config", InchoateClientHello( |
| 454 "CHLO", | 649 "CHLO", |
| 455 "VER\0", client_version_.data(), | 650 "VER\0", client_version_.data(), |
| 456 NULL)); | 651 NULL)); |
| 652 |
| 653 const HandshakeFailureReason kRejectReasons[] = { |
| 654 CLIENT_NONCE_UNKNOWN_FAILURE |
| 655 }; |
| 656 CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); |
| 457 } | 657 } |
| 458 | 658 |
| 459 class AsyncStrikeServerVerificationTest : public CryptoServerTest { | 659 class AsyncStrikeServerVerificationTest : public CryptoServerTest { |
| 460 protected: | 660 protected: |
| 461 AsyncStrikeServerVerificationTest() { | 661 AsyncStrikeServerVerificationTest() { |
| 462 } | 662 } |
| 463 | 663 |
| 464 virtual void SetUp() { | 664 virtual void SetUp() { |
| 465 const string kOrbit = "12345678"; | 665 const string kOrbit = "12345678"; |
| 466 config_options_.orbit = kOrbit; | 666 config_options_.orbit = kOrbit; |
| 467 strike_register_client_ = new DelayedVerifyStrikeRegisterClient( | 667 strike_register_client_ = new DelayedVerifyStrikeRegisterClient( |
| 468 10000, // strike_register_max_entries | 668 10000, // strike_register_max_entries |
| 469 static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()), | 669 static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()), |
| 470 60, // strike_register_window_secs | 670 60, // strike_register_window_secs |
| 471 reinterpret_cast<const uint8 *>(kOrbit.data()), | 671 reinterpret_cast<const uint8 *>(kOrbit.data()), |
| 472 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | 672 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); |
| 473 config_.SetStrikeRegisterClient(strike_register_client_); | 673 config_.SetStrikeRegisterClient(strike_register_client_); |
| 474 CryptoServerTest::SetUp(); | 674 CryptoServerTest::SetUp(); |
| 475 strike_register_client_->StartDelayingVerification(); | 675 strike_register_client_->StartDelayingVerification(); |
| 476 } | 676 } |
| 477 | 677 |
| 478 DelayedVerifyStrikeRegisterClient* strike_register_client_; | 678 DelayedVerifyStrikeRegisterClient* strike_register_client_; |
| 479 }; | 679 }; |
| 480 | 680 |
| 481 TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { | 681 TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { |
| 482 // This tests async validation with a strike register works. | 682 // This tests async validation with a strike register works. |
| 483 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 683 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 484 "CHLO", | 684 "CHLO", |
| 485 "AEAD", "AESG", | 685 "AEAD", "AESG", |
| 486 "KEXS", "C255", | 686 "KEXS", "C255", |
| 487 "SCID", scid_hex_.c_str(), | 687 "SCID", scid_hex_.c_str(), |
| 488 "#004b5453", srct_hex_.c_str(), | 688 "#004b5453", srct_hex_.c_str(), |
| 489 "PUBS", pub_hex_.c_str(), | 689 "PUBS", pub_hex_.c_str(), |
| 490 "NONC", nonce_hex_.c_str(), | 690 "NONC", nonce_hex_.c_str(), |
| 491 "VER\0", client_version_.data(), | 691 "VER\0", client_version_.data(), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 517 | 717 |
| 518 strike_register_client_->RunPendingVerifications(); | 718 strike_register_client_->RunPendingVerifications(); |
| 519 ASSERT_TRUE(called); | 719 ASSERT_TRUE(called); |
| 520 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | 720 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); |
| 521 // The message should be rejected now. | 721 // The message should be rejected now. |
| 522 EXPECT_EQ(kREJ, out_.tag()); | 722 EXPECT_EQ(kREJ, out_.tag()); |
| 523 } | 723 } |
| 524 | 724 |
| 525 } // namespace test | 725 } // namespace test |
| 526 } // namespace net | 726 } // namespace net |
| OLD | NEW |