| 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
| 7 #include "crypto/secure_hash.h" | 7 #include "crypto/secure_hash.h" |
| 8 #include "net/quic/crypto/crypto_utils.h" | 8 #include "net/quic/crypto/crypto_utils.h" |
| 9 #include "net/quic/crypto/quic_crypto_server_config.h" | 9 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 10 #include "net/quic/crypto/quic_random.h" | 10 #include "net/quic/crypto/quic_random.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 class CryptoServerTest : public ::testing::Test { | 39 class CryptoServerTest : public ::testing::Test { |
| 40 public: | 40 public: |
| 41 CryptoServerTest() | 41 CryptoServerTest() |
| 42 : rand_(QuicRandom::GetInstance()), | 42 : rand_(QuicRandom::GetInstance()), |
| 43 client_address_(Loopback4(), 1234), | 43 client_address_(Loopback4(), 1234), |
| 44 config_(QuicCryptoServerConfig::TESTING, rand_) { | 44 config_(QuicCryptoServerConfig::TESTING, rand_) { |
| 45 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); | 45 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); |
| 46 supported_versions_ = QuicSupportedVersions(); | 46 supported_versions_ = QuicSupportedVersions(); |
| 47 client_version_ = QuicUtils::TagToString( |
| 48 QuicVersionToQuicTag(supported_versions_.front())); |
| 47 } | 49 } |
| 48 | 50 |
| 49 virtual void SetUp() { | 51 virtual void SetUp() { |
| 50 scoped_ptr<CryptoHandshakeMessage> msg( | 52 scoped_ptr<CryptoHandshakeMessage> msg( |
| 51 config_.AddDefaultConfig(rand_, &clock_, | 53 config_.AddDefaultConfig(rand_, &clock_, |
| 52 config_options_)); | 54 config_options_)); |
| 53 | 55 |
| 54 StringPiece orbit; | 56 StringPiece orbit; |
| 55 CHECK(msg->GetStringPiece(kORBT, &orbit)); | 57 CHECK(msg->GetStringPiece(kORBT, &orbit)); |
| 56 CHECK_EQ(sizeof(orbit_), orbit.size()); | 58 CHECK_EQ(sizeof(orbit_), orbit.size()); |
| 57 memcpy(orbit_, orbit.data(), orbit.size()); | 59 memcpy(orbit_, orbit.data(), orbit.size()); |
| 58 | 60 |
| 59 char public_value[32]; | 61 char public_value[32]; |
| 60 memset(public_value, 42, sizeof(public_value)); | 62 memset(public_value, 42, sizeof(public_value)); |
| 61 | 63 |
| 62 const string nonce_str = GenerateNonce(); | 64 const string nonce_str = GenerateNonce(); |
| 63 nonce_hex_ = "#" + base::HexEncode(nonce_str.data(), nonce_str.size()); | 65 nonce_hex_ = "#" + base::HexEncode(nonce_str.data(), nonce_str.size()); |
| 64 pub_hex_ = "#" + base::HexEncode(public_value, sizeof(public_value)); | 66 pub_hex_ = "#" + base::HexEncode(public_value, sizeof(public_value)); |
| 65 | 67 |
| 66 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 68 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( |
| 67 "CHLO", | 69 "CHLO", |
| 68 "AEAD", "AESG", | 70 "AEAD", "AESG", |
| 69 "KEXS", "C255", | 71 "KEXS", "C255", |
| 70 "PUBS", pub_hex_.c_str(), | 72 "PUBS", pub_hex_.c_str(), |
| 71 "NONC", nonce_hex_.c_str(), | 73 "NONC", nonce_hex_.c_str(), |
| 74 "VER\0", client_version_.data(), |
| 72 "$padding", static_cast<int>(kClientHelloMinimumSize), | 75 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 73 NULL); | 76 NULL); |
| 74 ShouldSucceed(client_hello); | 77 ShouldSucceed(client_hello); |
| 75 // The message should be rejected because the source-address token is | 78 // The message should be rejected because the source-address token is |
| 76 // missing. | 79 // missing. |
| 77 ASSERT_EQ(kREJ, out_.tag()); | 80 ASSERT_EQ(kREJ, out_.tag()); |
| 78 | 81 |
| 79 StringPiece srct; | 82 StringPiece srct; |
| 80 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); | 83 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); |
| 81 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); | 84 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), | 217 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), |
| 215 &nonce); | 218 &nonce); |
| 216 return nonce; | 219 return nonce; |
| 217 } | 220 } |
| 218 | 221 |
| 219 protected: | 222 protected: |
| 220 QuicRandom* const rand_; | 223 QuicRandom* const rand_; |
| 221 MockClock clock_; | 224 MockClock clock_; |
| 222 const IPEndPoint client_address_; | 225 const IPEndPoint client_address_; |
| 223 QuicVersionVector supported_versions_; | 226 QuicVersionVector supported_versions_; |
| 227 string client_version_; |
| 224 QuicCryptoServerConfig config_; | 228 QuicCryptoServerConfig config_; |
| 225 QuicCryptoServerConfig::ConfigOptions config_options_; | 229 QuicCryptoServerConfig::ConfigOptions config_options_; |
| 226 QuicCryptoNegotiatedParameters params_; | 230 QuicCryptoNegotiatedParameters params_; |
| 227 CryptoHandshakeMessage out_; | 231 CryptoHandshakeMessage out_; |
| 228 uint8 orbit_[kOrbitSize]; | 232 uint8 orbit_[kOrbitSize]; |
| 229 | 233 |
| 230 // These strings contain hex escaped values from the server suitable for | 234 // These strings contain hex escaped values from the server suitable for |
| 231 // passing to |InchoateClientHello| when constructing client hello messages. | 235 // passing to |InchoateClientHello| when constructing client hello messages. |
| 232 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; | 236 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; |
| 233 scoped_ptr<CryptoHandshakeMessage> server_config_; | 237 scoped_ptr<CryptoHandshakeMessage> server_config_; |
| 234 }; | 238 }; |
| 235 | 239 |
| 236 TEST_F(CryptoServerTest, BadSNI) { | 240 TEST_F(CryptoServerTest, BadSNI) { |
| 237 static const char* kBadSNIs[] = { | 241 static const char* kBadSNIs[] = { |
| 238 "", | 242 "", |
| 239 "foo", | 243 "foo", |
| 240 "#00", | 244 "#00", |
| 241 "#ff00", | 245 "#ff00", |
| 242 "127.0.0.1", | 246 "127.0.0.1", |
| 243 "ffee::1", | 247 "ffee::1", |
| 244 }; | 248 }; |
| 245 | 249 |
| 250 string client_version = QuicUtils::TagToString( |
| 251 QuicVersionToQuicTag(supported_versions_.front())); |
| 252 |
| 246 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { | 253 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { |
| 247 ShouldFailMentioning("SNI", InchoateClientHello( | 254 ShouldFailMentioning("SNI", InchoateClientHello( |
| 248 "CHLO", | 255 "CHLO", |
| 249 "SNI", kBadSNIs[i], | 256 "SNI", kBadSNIs[i], |
| 257 "VER\0", client_version.data(), |
| 250 NULL)); | 258 NULL)); |
| 251 } | 259 } |
| 252 } | 260 } |
| 253 | 261 |
| 254 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. | 262 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. |
| 255 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { | 263 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { |
| 256 // Check that the server replies with a default certificate when no SNI is | 264 // Check that the server replies with a default certificate when no SNI is |
| 257 // specified. | 265 // specified. |
| 258 ShouldSucceed(InchoateClientHello( | 266 ShouldSucceed(InchoateClientHello( |
| 259 "CHLO", | 267 "CHLO", |
| 260 "AEAD", "AESG", | 268 "AEAD", "AESG", |
| 261 "KEXS", "C255", | 269 "KEXS", "C255", |
| 262 "SCID", scid_hex_.c_str(), | 270 "SCID", scid_hex_.c_str(), |
| 263 "#004b5453", srct_hex_.c_str(), | 271 "#004b5453", srct_hex_.c_str(), |
| 264 "PUBS", pub_hex_.c_str(), | 272 "PUBS", pub_hex_.c_str(), |
| 265 "NONC", nonce_hex_.c_str(), | 273 "NONC", nonce_hex_.c_str(), |
| 266 "$padding", static_cast<int>(kClientHelloMinimumSize), | 274 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 267 "PDMD", "X509", | 275 "PDMD", "X509", |
| 276 "VER\0", client_version_.data(), |
| 268 NULL)); | 277 NULL)); |
| 269 | 278 |
| 270 StringPiece cert, proof; | 279 StringPiece cert, proof; |
| 271 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); | 280 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); |
| 272 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); | 281 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); |
| 273 EXPECT_NE(0u, cert.size()); | 282 EXPECT_NE(0u, cert.size()); |
| 274 EXPECT_NE(0u, proof.size()); | 283 EXPECT_NE(0u, proof.size()); |
| 275 } | 284 } |
| 276 | 285 |
| 277 TEST_F(CryptoServerTest, TooSmall) { | 286 TEST_F(CryptoServerTest, TooSmall) { |
| 278 ShouldFailMentioning("too small", CryptoTestUtils::Message( | 287 ShouldFailMentioning("too small", CryptoTestUtils::Message( |
| 279 "CHLO", | 288 "CHLO", |
| 289 "VER\0", client_version_.data(), |
| 280 NULL)); | 290 NULL)); |
| 281 } | 291 } |
| 282 | 292 |
| 283 TEST_F(CryptoServerTest, BadSourceAddressToken) { | 293 TEST_F(CryptoServerTest, BadSourceAddressToken) { |
| 284 // Invalid source-address tokens should be ignored. | 294 // Invalid source-address tokens should be ignored. |
| 285 static const char* kBadSourceAddressTokens[] = { | 295 static const char* kBadSourceAddressTokens[] = { |
| 286 "", | 296 "", |
| 287 "foo", | 297 "foo", |
| 288 "#0000", | 298 "#0000", |
| 289 "#0000000000000000000000000000000000000000", | 299 "#0000000000000000000000000000000000000000", |
| 290 }; | 300 }; |
| 291 | 301 |
| 292 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { | 302 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { |
| 293 ShouldSucceed(InchoateClientHello( | 303 ShouldSucceed(InchoateClientHello( |
| 294 "CHLO", | 304 "CHLO", |
| 295 "STK", kBadSourceAddressTokens[i], | 305 "STK", kBadSourceAddressTokens[i], |
| 306 "VER\0", client_version_.data(), |
| 296 NULL)); | 307 NULL)); |
| 297 } | 308 } |
| 298 } | 309 } |
| 299 | 310 |
| 300 TEST_F(CryptoServerTest, BadClientNonce) { | 311 TEST_F(CryptoServerTest, BadClientNonce) { |
| 301 // Invalid nonces should be ignored. | 312 // Invalid nonces should be ignored. |
| 302 static const char* kBadNonces[] = { | 313 static const char* kBadNonces[] = { |
| 303 "", | 314 "", |
| 304 "#0000", | 315 "#0000", |
| 305 "#0000000000000000000000000000000000000000", | 316 "#0000000000000000000000000000000000000000", |
| 306 }; | 317 }; |
| 307 | 318 |
| 308 for (size_t i = 0; i < arraysize(kBadNonces); i++) { | 319 for (size_t i = 0; i < arraysize(kBadNonces); i++) { |
| 309 ShouldSucceed(InchoateClientHello( | 320 ShouldSucceed(InchoateClientHello( |
| 310 "CHLO", | 321 "CHLO", |
| 311 "NONC", kBadNonces[i], | 322 "NONC", kBadNonces[i], |
| 323 "VER\0", client_version_.data(), |
| 312 NULL)); | 324 NULL)); |
| 313 } | 325 } |
| 314 } | 326 } |
| 315 | 327 |
| 316 TEST_F(CryptoServerTest, DowngradeAttack) { | 328 TEST_F(CryptoServerTest, DowngradeAttack) { |
| 317 if (supported_versions_.size() == 1) { | 329 if (supported_versions_.size() == 1) { |
| 318 // No downgrade attack is possible if the server only supports one version. | 330 // No downgrade attack is possible if the server only supports one version. |
| 319 return; | 331 return; |
| 320 } | 332 } |
| 321 // Set the client's preferred version to a supported version that | 333 // Set the client's preferred version to a supported version that |
| 322 // is not the "current" version (supported_versions_.front()). | 334 // is not the "current" version (supported_versions_.front()). |
| 323 string client_version = QuicUtils::TagToString( | 335 string bad_version = QuicUtils::TagToString( |
| 324 QuicVersionToQuicTag(supported_versions_.back())); | 336 QuicVersionToQuicTag(supported_versions_.back())); |
| 325 | 337 |
| 326 ShouldFailMentioning("Downgrade", InchoateClientHello( | 338 ShouldFailMentioning("Downgrade", InchoateClientHello( |
| 327 "CHLO", | 339 "CHLO", |
| 328 "VER\0", client_version.data(), | 340 "VER\0", bad_version.data(), |
| 329 NULL)); | 341 NULL)); |
| 330 } | 342 } |
| 331 | 343 |
| 332 TEST_F(CryptoServerTest, ReplayProtection) { | 344 TEST_F(CryptoServerTest, ReplayProtection) { |
| 333 // This tests that disabling replay protection works. | 345 // This tests that disabling replay protection works. |
| 334 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 346 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 335 "CHLO", | 347 "CHLO", |
| 336 "AEAD", "AESG", | 348 "AEAD", "AESG", |
| 337 "KEXS", "C255", | 349 "KEXS", "C255", |
| 338 "SCID", scid_hex_.c_str(), | 350 "SCID", scid_hex_.c_str(), |
| 339 "#004b5453", srct_hex_.c_str(), | 351 "#004b5453", srct_hex_.c_str(), |
| 340 "PUBS", pub_hex_.c_str(), | 352 "PUBS", pub_hex_.c_str(), |
| 341 "NONC", nonce_hex_.c_str(), | 353 "NONC", nonce_hex_.c_str(), |
| 354 "VER\0", client_version_.data(), |
| 342 "$padding", static_cast<int>(kClientHelloMinimumSize), | 355 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 343 NULL); | 356 NULL); |
| 344 ShouldSucceed(msg); | 357 ShouldSucceed(msg); |
| 345 // The message should be rejected because the strike-register is still | 358 // The message should be rejected because the strike-register is still |
| 346 // quiescent. | 359 // quiescent. |
| 347 ASSERT_EQ(kREJ, out_.tag()); | 360 ASSERT_EQ(kREJ, out_.tag()); |
| 348 | 361 |
| 349 config_.set_replay_protection(false); | 362 config_.set_replay_protection(false); |
| 350 | 363 |
| 351 ShouldSucceed(msg); | 364 ShouldSucceed(msg); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 class CryptoServerTestNoConfig : public CryptoServerTest { | 445 class CryptoServerTestNoConfig : public CryptoServerTest { |
| 433 public: | 446 public: |
| 434 virtual void SetUp() { | 447 virtual void SetUp() { |
| 435 // Deliberately don't add a config so that we can test this situation. | 448 // Deliberately don't add a config so that we can test this situation. |
| 436 } | 449 } |
| 437 }; | 450 }; |
| 438 | 451 |
| 439 TEST_F(CryptoServerTestNoConfig, DontCrash) { | 452 TEST_F(CryptoServerTestNoConfig, DontCrash) { |
| 440 ShouldFailMentioning("No config", InchoateClientHello( | 453 ShouldFailMentioning("No config", InchoateClientHello( |
| 441 "CHLO", | 454 "CHLO", |
| 455 "VER\0", client_version_.data(), |
| 442 NULL)); | 456 NULL)); |
| 443 } | 457 } |
| 444 | 458 |
| 445 class AsyncStrikeServerVerificationTest : public CryptoServerTest { | 459 class AsyncStrikeServerVerificationTest : public CryptoServerTest { |
| 446 protected: | 460 protected: |
| 447 AsyncStrikeServerVerificationTest() { | 461 AsyncStrikeServerVerificationTest() { |
| 448 } | 462 } |
| 449 | 463 |
| 450 virtual void SetUp() { | 464 virtual void SetUp() { |
| 451 const string kOrbit = "12345678"; | 465 const string kOrbit = "12345678"; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 467 TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { | 481 TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { |
| 468 // This tests async validation with a strike register works. | 482 // This tests async validation with a strike register works. |
| 469 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 483 CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
| 470 "CHLO", | 484 "CHLO", |
| 471 "AEAD", "AESG", | 485 "AEAD", "AESG", |
| 472 "KEXS", "C255", | 486 "KEXS", "C255", |
| 473 "SCID", scid_hex_.c_str(), | 487 "SCID", scid_hex_.c_str(), |
| 474 "#004b5453", srct_hex_.c_str(), | 488 "#004b5453", srct_hex_.c_str(), |
| 475 "PUBS", pub_hex_.c_str(), | 489 "PUBS", pub_hex_.c_str(), |
| 476 "NONC", nonce_hex_.c_str(), | 490 "NONC", nonce_hex_.c_str(), |
| 491 "VER\0", client_version_.data(), |
| 477 "$padding", static_cast<int>(kClientHelloMinimumSize), | 492 "$padding", static_cast<int>(kClientHelloMinimumSize), |
| 478 NULL); | 493 NULL); |
| 479 | 494 |
| 480 // Clear the message tag. | 495 // Clear the message tag. |
| 481 out_.set_tag(0); | 496 out_.set_tag(0); |
| 482 | 497 |
| 483 bool called = false; | 498 bool called = false; |
| 484 RunValidate(msg, new ValidateCallback(this, true, "", &called)); | 499 RunValidate(msg, new ValidateCallback(this, true, "", &called)); |
| 485 // The verification request was queued. | 500 // The verification request was queued. |
| 486 ASSERT_FALSE(called); | 501 ASSERT_FALSE(called); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 502 | 517 |
| 503 strike_register_client_->RunPendingVerifications(); | 518 strike_register_client_->RunPendingVerifications(); |
| 504 ASSERT_TRUE(called); | 519 ASSERT_TRUE(called); |
| 505 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | 520 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); |
| 506 // The message should be rejected now. | 521 // The message should be rejected now. |
| 507 EXPECT_EQ(kREJ, out_.tag()); | 522 EXPECT_EQ(kREJ, out_.tag()); |
| 508 } | 523 } |
| 509 | 524 |
| 510 } // namespace test | 525 } // namespace test |
| 511 } // namespace net | 526 } // namespace net |
| OLD | NEW |