Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / crypto / quic_crypto_server_config_test.cc
index fbf25f0..4453b76 100644 (file)
@@ -9,11 +9,13 @@
 #include "base/stl_util.h"
 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
 #include "net/quic/crypto/crypto_handshake_message.h"
+#include "net/quic/crypto/crypto_secret_boxer.h"
 #include "net/quic/crypto/crypto_server_config_protobuf.h"
 #include "net/quic/crypto/quic_random.h"
 #include "net/quic/crypto/strike_register_client.h"
 #include "net/quic/quic_time.h"
 #include "net/quic/test_tools/mock_clock.h"
+#include "net/quic/test_tools/quic_test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -32,16 +34,64 @@ class QuicCryptoServerConfigPeer {
   explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
       : server_config_(server_config) {}
 
-  string NewSourceAddressToken(IPEndPoint ip,
-                               QuicRandom* rand,
-                               QuicWallTime now) {
-    return server_config_->NewSourceAddressToken(ip, rand, now);
+  scoped_refptr<QuicCryptoServerConfig::Config> GetConfig(string config_id) {
+    base::AutoLock locked(server_config_->configs_lock_);
+    if (config_id == "<primary>") {
+      return scoped_refptr<QuicCryptoServerConfig::Config>(
+          server_config_->primary_config_);
+    } else {
+      return server_config_->GetConfigWithScid(config_id);
+    }
+  }
+
+  bool ConfigHasDefaultSourceAddressTokenBoxer(string config_id) {
+    scoped_refptr<QuicCryptoServerConfig::Config> config = GetConfig(config_id);
+    return config->source_address_token_boxer ==
+        &(server_config_->default_source_address_token_boxer_);
   }
 
-  bool ValidateSourceAddressToken(StringPiece srct,
-                                  IPEndPoint ip,
-                                  QuicWallTime now) {
-    return server_config_->ValidateSourceAddressToken(srct, ip, now);
+  string NewSourceAddressToken(
+      string config_id,
+      const IPEndPoint& ip,
+      QuicRandom* rand,
+      QuicWallTime now) {
+    return NewSourceAddressToken(config_id, ip, rand, now, NULL);
+  }
+
+  string NewSourceAddressToken(
+      string config_id,
+      const IPEndPoint& ip,
+      QuicRandom* rand,
+      QuicWallTime now,
+      CachedNetworkParameters* cached_network_params) {
+    return server_config_->NewSourceAddressToken(
+        *GetConfig(config_id), ip, rand, now, cached_network_params);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressToken(string config_id,
+                                                    StringPiece srct,
+                                                    const IPEndPoint& ip,
+                                                    QuicWallTime now) {
+    return ValidateSourceAddressToken(config_id, srct, ip, now, NULL);
+  }
+
+  HandshakeFailureReason ValidateSourceAddressToken(
+      string config_id,
+      StringPiece srct,
+      const IPEndPoint& ip,
+      QuicWallTime now,
+      CachedNetworkParameters* cached_network_params) {
+    return server_config_->ValidateSourceAddressToken(
+        *GetConfig(config_id), srct, ip, now, cached_network_params);
+  }
+
+  string NewServerNonce(QuicRandom* rand, QuicWallTime now) const {
+    return server_config_->NewServerNonce(rand, now);
+  }
+
+  HandshakeFailureReason ValidateServerNonce(StringPiece token,
+                                             QuicWallTime now) {
+    return server_config_->ValidateServerNonce(token, now);
   }
 
   base::Lock* GetStrikeRegisterClientLock() {
@@ -49,11 +99,11 @@ class QuicCryptoServerConfigPeer {
   }
 
   // CheckConfigs compares the state of the Configs in |server_config_| to the
-  // description given as arguments. The arguments are given as NULL-terminated
-  // pairs. The first of each pair is the server config ID of a Config. The
-  // second is a boolean describing whether the config is the primary. For
-  // example:
-  //   CheckConfigs(NULL);  // checks that no Configs are loaded.
+  // description given as arguments. The arguments are given as
+  // nullptr-terminated pairs. The first of each pair is the server config ID of
+  // a Config. The second is a boolean describing whether the config is the
+  // primary. For example:
+  //   CheckConfigs(nullptr);  // checks that no Configs are loaded.
   //
   //   // Checks that exactly three Configs are loaded with the given IDs and
   //   // status.
@@ -61,7 +111,7 @@ class QuicCryptoServerConfigPeer {
   //     "id1", false,
   //     "id2", true,
   //     "id3", false,
-  //     NULL);
+  //     nullptr);
   void CheckConfigs(const char* server_config_id1, ...) {
     va_list ap;
     va_start(ap, server_config_id1);
@@ -156,7 +206,7 @@ class TestStrikeRegisterClient : public StrikeRegisterClient {
         is_known_orbit_called_(false) {
   }
 
-  virtual bool IsKnownOrbit(StringPiece orbit) const OVERRIDE {
+  bool IsKnownOrbit(StringPiece orbit) const override {
     // Ensure that the strike register client lock is not held.
     QuicCryptoServerConfigPeer peer(config_);
     base::Lock* m = peer.GetStrikeRegisterClientLock();
@@ -169,10 +219,9 @@ class TestStrikeRegisterClient : public StrikeRegisterClient {
     return true;
   }
 
-  virtual void VerifyNonceIsValidAndUnique(
-      StringPiece nonce,
-      QuicWallTime now,
-      ResultCallback* cb) OVERRIDE {
+  void VerifyNonceIsValidAndUnique(StringPiece nonce,
+                                   QuicWallTime now,
+                                   ResultCallback* cb) override {
     LOG(FATAL) << "Not implemented";
   }
 
@@ -209,31 +258,138 @@ TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) {
 }
 
 TEST(QuicCryptoServerConfigTest, SourceAddressTokens) {
-  QuicRandom* rand = QuicRandom::GetInstance();
-  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
-  IPAddressNumber ip;
-  CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
-  IPEndPoint ip4 = IPEndPoint(ip, 1);
-  CHECK(ParseIPLiteralToNumber("2001:db8:0::42", &ip));
-  IPEndPoint ip6 = IPEndPoint(ip, 2);
+  const string kPrimary = "<primary>";
+  const string kOverride = "Config with custom source address token key";
+
   MockClock clock;
   clock.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
-  QuicCryptoServerConfigPeer peer(&server);
 
   QuicWallTime now = clock.WallNow();
   const QuicWallTime original_time = now;
 
-  const string token4 = peer.NewSourceAddressToken(ip4, rand, now);
-  const string token6 = peer.NewSourceAddressToken(ip6, rand, now);
-  EXPECT_TRUE(peer.ValidateSourceAddressToken(token4, ip4, now));
-  EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip6, now));
-  EXPECT_TRUE(peer.ValidateSourceAddressToken(token6, ip6, now));
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
+  QuicCryptoServerConfigPeer peer(&server);
 
+  scoped_ptr<CryptoHandshakeMessage>(
+      server.AddDefaultConfig(rand, &clock,
+                              QuicCryptoServerConfig::ConfigOptions()));
+
+  // Add a config that overrides the default boxer.
+  QuicCryptoServerConfig::ConfigOptions options;
+  options.id = kOverride;
+  scoped_ptr<QuicServerConfigProtobuf> protobuf(
+      QuicCryptoServerConfig::GenerateConfig(rand, &clock, options));
+  protobuf->set_source_address_token_secret_override("a secret key");
+  // Lower priority than the default config.
+  protobuf->set_priority(1);
+  scoped_ptr<CryptoHandshakeMessage>(
+      server.AddConfig(protobuf.get(), now));
+
+  EXPECT_TRUE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kPrimary));
+  EXPECT_FALSE(peer.ConfigHasDefaultSourceAddressTokenBoxer(kOverride));
+
+  IPEndPoint ip4 = IPEndPoint(Loopback4(), 1);
+  IPEndPoint ip4d = IPEndPoint(ConvertIPv4NumberToIPv6Number(ip4.address()), 1);
+  IPEndPoint ip6 = IPEndPoint(Loopback6(), 2);
+
+  // Primary config generates configs that validate successfully.
+  const string token4 = peer.NewSourceAddressToken(kPrimary, ip4, rand, now);
+  const string token4d = peer.NewSourceAddressToken(kPrimary, ip4d, rand, now);
+  const string token6 = peer.NewSourceAddressToken(kPrimary, ip6, rand, now);
+  EXPECT_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kPrimary, token4, ip4, now));
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kPrimary, token4, ip4d, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, token4, ip6, now));
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kPrimary, token4d, ip4, now));
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kPrimary, token4d, ip4d, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, token4d, ip6, now));
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kPrimary, token6, ip6, now));
+
+  // Override config generates configs that validate successfully.
+  const string override_token4 = peer.NewSourceAddressToken(
+      kOverride, ip4, rand, now);
+  const string override_token6 = peer.NewSourceAddressToken(
+      kOverride, ip6, rand, now);
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kOverride, override_token4, ip4, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
+            peer.ValidateSourceAddressToken(kOverride, override_token4, ip6,
+                                            now));
+  DCHECK_EQ(HANDSHAKE_OK, peer.ValidateSourceAddressToken(
+      kOverride, override_token6, ip6, now));
+
+  // Tokens generated by the primary config do not validate
+  // successfully against the override config, and vice versa.
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+            peer.ValidateSourceAddressToken(kOverride, token4, ip4, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+            peer.ValidateSourceAddressToken(kOverride, token6, ip6, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, override_token4, ip4,
+                                            now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, override_token6, ip6,
+                                            now));
+
+  // Validation fails after tokens expire.
   now = original_time.Add(QuicTime::Delta::FromSeconds(86400 * 7));
-  EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip4, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now));
 
   now = original_time.Subtract(QuicTime::Delta::FromSeconds(3600 * 2));
-  EXPECT_FALSE(peer.ValidateSourceAddressToken(token4, ip4, now));
+  DCHECK_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
+            peer.ValidateSourceAddressToken(kPrimary, token4, ip4, now));
+
+  // Make sure that if the source address token contains CachedNetworkParameters
+  // that this gets written to ValidateSourceAddressToken output argument.
+  CachedNetworkParameters cached_network_params_input;
+  cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
+  const string token4_with_cached_network_params = peer.NewSourceAddressToken(
+      kPrimary, ip4, rand, now, &cached_network_params_input);
+
+  CachedNetworkParameters cached_network_params_output;
+  EXPECT_NE(cached_network_params_output, cached_network_params_input);
+  peer.ValidateSourceAddressToken(kPrimary, token4_with_cached_network_params,
+                                  ip4, now, &cached_network_params_output);
+  // TODO(rtenneti): For server, enable the following check after serialization
+  // of optional CachedNetworkParameters is implemented.
+  // EXPECT_EQ(cached_network_params_output, cached_network_params_input);
+}
+
+TEST(QuicCryptoServerConfigTest, ValidateServerNonce) {
+  QuicRandom* rand = QuicRandom::GetInstance();
+  QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
+  QuicCryptoServerConfigPeer peer(&server);
+
+  StringPiece message("hello world");
+  const size_t key_size = CryptoSecretBoxer::GetKeySize();
+  scoped_ptr<uint8[]> key(new uint8[key_size]);
+  memset(key.get(), 0x11, key_size);
+
+  CryptoSecretBoxer boxer;
+  boxer.SetKey(StringPiece(reinterpret_cast<char*>(key.get()), key_size));
+  const string box = boxer.Box(rand, message);
+  MockClock clock;
+  QuicWallTime now = clock.WallNow();
+  const QuicWallTime original_time = now;
+  EXPECT_EQ(SERVER_NONCE_DECRYPTION_FAILURE,
+            peer.ValidateServerNonce(box, now));
+
+  string server_nonce = peer.NewServerNonce(rand, now);
+  EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
+  EXPECT_EQ(SERVER_NONCE_NOT_UNIQUE_FAILURE,
+            peer.ValidateServerNonce(server_nonce, now));
+
+  now = original_time.Add(QuicTime::Delta::FromSeconds(1000 * 7));
+  server_nonce = peer.NewServerNonce(rand, now);
+  EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
 }
 
 class CryptoServerConfigsTest : public ::testing::Test {
@@ -243,17 +399,16 @@ class CryptoServerConfigsTest : public ::testing::Test {
         config_(QuicCryptoServerConfig::TESTING, rand_),
         test_peer_(&config_) {}
 
-  virtual void SetUp() {
+  void SetUp() override {
     clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
   }
 
   // SetConfigs constructs suitable config protobufs and calls SetConfigs on
-  // |config_|. The arguments are given as NULL-terminated pairs. The first of
-  // each pair is the server config ID of a Config. The second is the
-  // |primary_time| of that Config, given in epoch seconds. (Although note
-  // that, in these tests, time is set to 1000 seconds since the epoch.) For
-  // example:
-  //   SetConfigs(NULL);  // calls |config_.SetConfigs| with no protobufs.
+  // |config_|. The arguments are given as nullptr-terminated pairs. The first
+  // of each pair is the server config ID of a Config. The second is the
+  // |primary_time| of that Config, given in epoch seconds. (Although note that,
+  // in these tests, time is set to 1000 seconds since the epoch.) For example:
+  //   SetConfigs(nullptr);  // calls |config_.SetConfigs| with no protobufs.
   //
   //   // Calls |config_.SetConfigs| with two protobufs: one for a Config with
   //   // a |primary_time| of 900 and priority 1, and another with
@@ -262,7 +417,7 @@ class CryptoServerConfigsTest : public ::testing::Test {
   //   CheckConfigs(
   //     "id1", 900, 1,
   //     "id2", 1000, 2,
-  //     NULL);
+  //     nullptr);
   //
   // If the server config id starts with "INVALID" then the generated protobuf
   // will be invalid.
@@ -320,29 +475,29 @@ class CryptoServerConfigsTest : public ::testing::Test {
 };
 
 TEST_F(CryptoServerConfigsTest, NoConfigs) {
-  test_peer_.CheckConfigs(NULL);
+  test_peer_.CheckConfigs(nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
   // Make sure that "b" is primary even though "a" comes first.
   SetConfigs("a", 1100, 1,
              "b", 900, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
   // Make sure that a remains primary after b is added.
   SetConfigs("a", 900, 1,
              "b", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, Delete) {
@@ -350,19 +505,19 @@ TEST_F(CryptoServerConfigsTest, Delete) {
   SetConfigs("a", 800, 1,
              "b", 900, 1,
              "c", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
       "c", false,
-      NULL);
+      nullptr);
   SetConfigs("b", 900, 1,
              "c", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "b", true,
       "c", false,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, DeletePrimary) {
@@ -370,36 +525,36 @@ TEST_F(CryptoServerConfigsTest, DeletePrimary) {
   SetConfigs("a", 800, 1,
              "b", 900, 1,
              "c", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
       "c", false,
-      NULL);
+      nullptr);
   SetConfigs("a", 800, 1,
              "c", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", true,
       "c", false,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
   // Ensure that configs get deleted when removed.
   SetConfigs("a", 800, 1,
              "b", 900, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
-      NULL);
-  SetConfigs(NULL);
+      nullptr);
+  SetConfigs(nullptr);
   // Config change is rejected, still using old configs.
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
@@ -407,23 +562,23 @@ TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
   SetConfigs("a", 400, 1,
              "b", 800, 1,
              "c", 1200, 1,
-             NULL);
+             nullptr);
   test_peer_.SelectNewPrimaryConfig(500);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
       "c", false,
-      NULL);
+      nullptr);
   SetConfigs("a", 1200, 1,
              "b", 800, 1,
              "c", 400, 1,
-             NULL);
+             nullptr);
   test_peer_.SelectNewPrimaryConfig(500);
   test_peer_.CheckConfigs(
       "a", false,
       "b", false,
       "c", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
@@ -431,13 +586,13 @@ TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
   SetConfigs("a", 400, 1,
              "b", 800, 1,
              "c", 1200, 1,
-             NULL);
+             nullptr);
   test_peer_.SelectNewPrimaryConfig(1500);
   test_peer_.CheckConfigs(
       "a", false,
       "b", false,
       "c", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
@@ -445,13 +600,13 @@ TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
   SetConfigs("a", 400, 1,
              "b", 800, 1,
              "c", 1200, 1,
-             NULL);
+             nullptr);
   test_peer_.SelectNewPrimaryConfig(100);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
       "c", false,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, SortByPriority) {
@@ -460,64 +615,64 @@ TEST_F(CryptoServerConfigsTest, SortByPriority) {
   SetConfigs("a", 900, 1,
              "b", 900, 2,
              "c", 900, 3,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
       "c", false,
-      NULL);
+      nullptr);
   test_peer_.SelectNewPrimaryConfig(800);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
       "c", false,
-      NULL);
+      nullptr);
   test_peer_.SelectNewPrimaryConfig(1000);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
       "c", false,
-      NULL);
+      nullptr);
 
   // Change priorities and expect sort order to change.
   SetConfigs("a", 900, 2,
              "b", 900, 1,
              "c", 900, 0,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", false,
       "c", true,
-      NULL);
+      nullptr);
   test_peer_.SelectNewPrimaryConfig(800);
   test_peer_.CheckConfigs(
       "a", false,
       "b", false,
       "c", true,
-      NULL);
+      nullptr);
   test_peer_.SelectNewPrimaryConfig(1000);
   test_peer_.CheckConfigs(
       "a", false,
       "b", false,
       "c", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
   // Check that a new primary config is enabled at the right time.
   SetConfigs("a", 900, 1,
              "b", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.SelectNewPrimaryConfig(1000);
   test_peer_.CheckConfigs(
       "a", true,
       "b", false,
-      NULL);
+      nullptr);
   test_peer_.SelectNewPrimaryConfig(1101);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
-      NULL);
+      nullptr);
 }
 
 TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
@@ -525,21 +680,21 @@ TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
   SetConfigs("a", 800, 1,
              "b", 900, 1,
              "c", 1100, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
       "c", false,
-      NULL);
+      nullptr);
   SetConfigs("a", 800, 1,
              "c", 1100, 1,
              "INVALID1", 1000, 1,
-             NULL);
+             nullptr);
   test_peer_.CheckConfigs(
       "a", false,
       "b", true,
       "c", false,
-      NULL);
+      nullptr);
 }
 
 }  // namespace test