| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "net/quic/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 6 | 6 |
| 7 #include <stdarg.h> | 7 #include <stdarg.h> |
| 8 | 8 |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" | 10 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" |
| 11 #include "net/quic/crypto/crypto_handshake_message.h" | 11 #include "net/quic/crypto/crypto_handshake_message.h" |
| 12 #include "net/quic/crypto/crypto_secret_boxer.h" |
| 12 #include "net/quic/crypto/crypto_server_config_protobuf.h" | 13 #include "net/quic/crypto/crypto_server_config_protobuf.h" |
| 13 #include "net/quic/crypto/quic_random.h" | 14 #include "net/quic/crypto/quic_random.h" |
| 14 #include "net/quic/crypto/strike_register_client.h" | 15 #include "net/quic/crypto/strike_register_client.h" |
| 15 #include "net/quic/quic_time.h" | 16 #include "net/quic/quic_time.h" |
| 16 #include "net/quic/test_tools/mock_clock.h" | 17 #include "net/quic/test_tools/mock_clock.h" |
| 17 #include "net/quic/test_tools/quic_test_utils.h" | 18 #include "net/quic/test_tools/quic_test_utils.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 21 |
| 21 using base::StringPiece; | 22 using base::StringPiece; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 51 | 52 |
| 52 string NewSourceAddressToken( | 53 string NewSourceAddressToken( |
| 53 string config_id, | 54 string config_id, |
| 54 IPEndPoint ip, | 55 IPEndPoint ip, |
| 55 QuicRandom* rand, | 56 QuicRandom* rand, |
| 56 QuicWallTime now) { | 57 QuicWallTime now) { |
| 57 return server_config_->NewSourceAddressToken( | 58 return server_config_->NewSourceAddressToken( |
| 58 *GetConfig(config_id), ip, rand, now); | 59 *GetConfig(config_id), ip, rand, now); |
| 59 } | 60 } |
| 60 | 61 |
| 61 bool ValidateSourceAddressToken(string config_id, | 62 HandshakeFailureReason ValidateSourceAddressToken(string config_id, |
| 62 StringPiece srct, | 63 StringPiece srct, |
| 63 IPEndPoint ip, | 64 IPEndPoint ip, |
| 64 QuicWallTime now) { | 65 QuicWallTime now) { |
| 65 return server_config_->ValidateSourceAddressToken( | 66 return server_config_->ValidateSourceAddressToken( |
| 66 *GetConfig(config_id), srct, ip, now); | 67 *GetConfig(config_id), srct, ip, now); |
| 67 } | 68 } |
| 68 | 69 |
| 70 string NewServerNonce(QuicRandom* rand, QuicWallTime now) const { |
| 71 return server_config_->NewServerNonce(rand, now); |
| 72 } |
| 73 |
| 74 HandshakeFailureReason ValidateServerNonce(StringPiece token, |
| 75 QuicWallTime now) { |
| 76 return server_config_->ValidateServerNonce(token, now); |
| 77 } |
| 78 |
| 69 base::Lock* GetStrikeRegisterClientLock() { | 79 base::Lock* GetStrikeRegisterClientLock() { |
| 70 return &server_config_->strike_register_client_lock_; | 80 return &server_config_->strike_register_client_lock_; |
| 71 } | 81 } |
| 72 | 82 |
| 73 // CheckConfigs compares the state of the Configs in |server_config_| to the | 83 // CheckConfigs compares the state of the Configs in |server_config_| to the |
| 74 // description given as arguments. The arguments are given as NULL-terminated | 84 // description given as arguments. The arguments are given as NULL-terminated |
| 75 // pairs. The first of each pair is the server config ID of a Config. The | 85 // pairs. The first of each pair is the server config ID of a Config. The |
| 76 // second is a boolean describing whether the config is the primary. For | 86 // second is a boolean describing whether the config is the primary. For |
| 77 // example: | 87 // example: |
| 78 // CheckConfigs(NULL); // checks that no Configs are loaded. | 88 // CheckConfigs(NULL); // checks that no Configs are loaded. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 EXPECT_FALSE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kOverride)); | 273 EXPECT_FALSE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kOverride)); |
| 264 | 274 |
| 265 IPEndPoint ip4 = IPEndPoint(Loopback4(), 1); | 275 IPEndPoint ip4 = IPEndPoint(Loopback4(), 1); |
| 266 IPEndPoint ip4d = IPEndPoint(ConvertIPv4NumberToIPv6Number(ip4.address()), 1); | 276 IPEndPoint ip4d = IPEndPoint(ConvertIPv4NumberToIPv6Number(ip4.address()), 1); |
| 267 IPEndPoint ip6 = IPEndPoint(Loopback6(), 2); | 277 IPEndPoint ip6 = IPEndPoint(Loopback6(), 2); |
| 268 | 278 |
| 269 // Primary config generates configs that validate successfully. | 279 // Primary config generates configs that validate successfully. |
| 270 const string token4 = peer.NewSourceAddressToken(kPrimary, ip4, rand, now); | 280 const string token4 = peer.NewSourceAddressToken(kPrimary, ip4, rand, now); |
| 271 const string token4d = peer.NewSourceAddressToken(kPrimary, ip4d, rand, now); | 281 const string token4d = peer.NewSourceAddressToken(kPrimary, ip4d, rand, now); |
| 272 const string token6 = peer.NewSourceAddressToken(kPrimary, ip6, rand, now); | 282 const string token6 = peer.NewSourceAddressToken(kPrimary, ip6, rand, now); |
| 273 EXPECT_TRUE(peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); | 283 EXPECT_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 274 EXPECT_TRUE(peer.ValidateSourceAddressToken(kPrimary, token4, ip4d, now)); | 284 kPrimary, token4, ip4, now)); |
| 275 EXPECT_FALSE(peer.ValidateSourceAddressToken(kPrimary, token4, ip6, now)); | 285 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 276 EXPECT_TRUE(peer.ValidateSourceAddressToken(kPrimary, token4d, ip4, now)); | 286 kPrimary, token4, ip4d, now)); |
| 277 EXPECT_TRUE(peer.ValidateSourceAddressToken(kPrimary, token4d, ip4d, now)); | 287 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE, |
| 278 EXPECT_FALSE(peer.ValidateSourceAddressToken(kPrimary, token4d, ip6, now)); | 288 peer.ValidateSourceAddressToken(kPrimary, token4, ip6, now)); |
| 279 EXPECT_TRUE(peer.ValidateSourceAddressToken(kPrimary, token6, ip6, now)); | 289 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 290 kPrimary, token4d, ip4, now)); |
| 291 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 292 kPrimary, token4d, ip4d, now)); |
| 293 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE, |
| 294 peer.ValidateSourceAddressToken(kPrimary, token4d, ip6, now)); |
| 295 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 296 kPrimary, token6, ip6, now)); |
| 280 | 297 |
| 281 // Override config generates configs that validate successfully. | 298 // Override config generates configs that validate successfully. |
| 282 const string override_token4 = peer.NewSourceAddressToken( | 299 const string override_token4 = peer.NewSourceAddressToken( |
| 283 kOverride, ip4, rand, now); | 300 kOverride, ip4, rand, now); |
| 284 const string override_token6 = peer.NewSourceAddressToken( | 301 const string override_token6 = peer.NewSourceAddressToken( |
| 285 kOverride, ip6, rand, now); | 302 kOverride, ip6, rand, now); |
| 286 EXPECT_TRUE(peer.ValidateSourceAddressToken( | 303 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 287 kOverride, override_token4, ip4, now)); | 304 kOverride, override_token4, ip4, now)); |
| 288 EXPECT_FALSE(peer.ValidateSourceAddressToken( | 305 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE, |
| 289 kOverride, override_token4, ip6, now)); | 306 peer.ValidateSourceAddressToken(kOverride, override_token4, ip6, |
| 290 EXPECT_TRUE(peer.ValidateSourceAddressToken( | 307 now)); |
| 308 DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken( |
| 291 kOverride, override_token6, ip6, now)); | 309 kOverride, override_token6, ip6, now)); |
| 292 | 310 |
| 293 // Tokens generated by the primary config do not validate | 311 // Tokens generated by the primary config do not validate |
| 294 // successfully against the override config, and vice versa. | 312 // successfully against the override config, and vice versa. |
| 295 EXPECT_FALSE(peer.ValidateSourceAddressToken(kOverride, token4, ip4, now)); | 313 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 296 EXPECT_FALSE(peer.ValidateSourceAddressToken(kOverride, token6, ip6, now)); | 314 peer.ValidateSourceAddressToken(kOverride, token4, ip4, now)); |
| 297 EXPECT_FALSE(peer.ValidateSourceAddressToken( | 315 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 298 kPrimary, override_token4, ip4, now)); | 316 peer.ValidateSourceAddressToken(kOverride, token6, ip6, now)); |
| 299 EXPECT_FALSE(peer.ValidateSourceAddressToken( | 317 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 300 kPrimary, override_token6, ip6, now)); | 318 peer.ValidateSourceAddressToken(kPrimary, override_token4, ip4, |
| 319 now)); |
| 320 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE, |
| 321 peer.ValidateSourceAddressToken(kPrimary, override_token6, ip6, |
| 322 now)); |
| 301 | 323 |
| 302 // Validation fails after tokens expire. | 324 // Validation fails after tokens expire. |
| 303 now = original_time.Add(QuicTime::Delta::FromSeconds(86400 * 7)); | 325 now = original_time.Add(QuicTime::Delta::FromSeconds(86400 * 7)); |
| 304 EXPECT_FALSE(peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); | 326 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE, |
| 327 peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); |
| 305 | 328 |
| 306 now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2)); | 329 now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2)); |
| 307 EXPECT_FALSE(peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); | 330 DCHECK_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE, |
| 331 peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now)); |
| 332 } |
| 333 |
| 334 TEST(QuicCryptoServerConfigTest, ValidateServerNonce) { |
| 335 QuicRandom* rand = QuicRandom::GetInstance(); |
| 336 QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand); |
| 337 QuicCryptoServerConfigPeer peer(&server); |
| 338 |
| 339 StringPiece message("hello world"); |
| 340 const size_t key_size = CryptoSecretBoxer::GetKeySize(); |
| 341 scoped_ptr<uint8[]> key(new uint8[key_size]); |
| 342 memset(key.get(), 0x11, key_size); |
| 343 |
| 344 CryptoSecretBoxer boxer; |
| 345 boxer.SetKey(StringPiece(reinterpret_cast<char*>(key.get()), key_size)); |
| 346 const string box = boxer.Box(rand, message); |
| 347 MockClock clock; |
| 348 QuicWallTime now = clock.WallNow(); |
| 349 const QuicWallTime original_time = now; |
| 350 EXPECT_EQ(SERVER_NONCE_DECRYPTION_FAILURE, |
| 351 peer.ValidateServerNonce(box, now)); |
| 352 |
| 353 string server_nonce = peer.NewServerNonce(rand, now); |
| 354 EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now)); |
| 355 EXPECT_EQ(SERVER_NONCE_NOT_UNIQUE_FAILURE, |
| 356 peer.ValidateServerNonce(server_nonce, now)); |
| 357 |
| 358 now = original_time.Add(QuicTime::Delta::FromSeconds(1000 * 7)); |
| 359 server_nonce = peer.NewServerNonce(rand, now); |
| 360 EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now)); |
| 308 } | 361 } |
| 309 | 362 |
| 310 class CryptoServerConfigsTest : public ::testing::Test { | 363 class CryptoServerConfigsTest : public ::testing::Test { |
| 311 public: | 364 public: |
| 312 CryptoServerConfigsTest() | 365 CryptoServerConfigsTest() |
| 313 : rand_(QuicRandom::GetInstance()), | 366 : rand_(QuicRandom::GetInstance()), |
| 314 config_(QuicCryptoServerConfig::TESTING, rand_), | 367 config_(QuicCryptoServerConfig::TESTING, rand_), |
| 315 test_peer_(&config_) {} | 368 test_peer_(&config_) {} |
| 316 | 369 |
| 317 virtual void SetUp() { | 370 virtual void SetUp() { |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 NULL); | 661 NULL); |
| 609 test_peer_.CheckConfigs( | 662 test_peer_.CheckConfigs( |
| 610 "a", false, | 663 "a", false, |
| 611 "b", true, | 664 "b", true, |
| 612 "c", false, | 665 "c", false, |
| 613 NULL); | 666 NULL); |
| 614 } | 667 } |
| 615 | 668 |
| 616 } // namespace test | 669 } // namespace test |
| 617 } // namespace net | 670 } // namespace net |
| OLD | NEW |