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 |