| 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 "net/quic/crypto/strike_register.h" | 5 #include "net/quic/crypto/strike_register.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // The set must reject values created on or before its own creation time. | 37 // The set must reject values created on or before its own creation time. |
| 38 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 38 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 39 100 /* window secs */, kOrbit, | 39 100 /* window secs */, kOrbit, |
| 40 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 40 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 41 uint8 nonce[32]; | 41 uint8 nonce[32]; |
| 42 SetNonce(nonce, 999, kOrbit); | 42 SetNonce(nonce, 999, kOrbit); |
| 43 ASSERT_FALSE(set.Insert(nonce, 1000)); | 43 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 44 SetNonce(nonce, 1000, kOrbit); | 44 SetNonce(nonce, 1000, kOrbit); |
| 45 ASSERT_FALSE(set.Insert(nonce, 1000)); | 45 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 46 | 46 |
| 47 EXPECT_EQ(0u, set.EffectiveWindowSecs(1000 /* current time */)); | 47 EXPECT_EQ(0u, set.GetCurrentValidWindowSecs(1000 /* current time */)); |
| 48 EXPECT_EQ(49u, set.EffectiveWindowSecs(1050 /* current time */)); | 48 EXPECT_EQ(0u, set.GetCurrentValidWindowSecs(1100 /* current time */)); |
| 49 EXPECT_EQ(99u, set.EffectiveWindowSecs(1100 /* current time */)); | 49 EXPECT_EQ(1u, set.GetCurrentValidWindowSecs(1101 /* current time */)); |
| 50 EXPECT_EQ(199u, set.EffectiveWindowSecs(1200 /* current time */)); | 50 EXPECT_EQ(50u, set.GetCurrentValidWindowSecs(1150 /* current time */)); |
| 51 EXPECT_EQ(200u, set.EffectiveWindowSecs(1300 /* current time */)); | 51 EXPECT_EQ(100u, set.GetCurrentValidWindowSecs(1200 /* current time */)); |
| 52 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1300 /* current time */)); |
| 52 } | 53 } |
| 53 | 54 |
| 54 TEST(StrikeRegisterTest, NoStartupMode) { | 55 TEST(StrikeRegisterTest, NoStartupMode) { |
| 55 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED | 56 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED |
| 56 // is specified. | 57 // is specified. |
| 57 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 58 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 58 100 /* window secs */, kOrbit, | 59 100 /* window secs */, kOrbit, |
| 59 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | 60 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); |
| 60 uint8 nonce[32]; | 61 uint8 nonce[32]; |
| 61 SetNonce(nonce, 1000, kOrbit); | 62 SetNonce(nonce, 1000, kOrbit); |
| 62 ASSERT_TRUE(set.Insert(nonce, 1000)); | 63 ASSERT_TRUE(set.Insert(nonce, 1000)); |
| 63 ASSERT_FALSE(set.Insert(nonce, 1000)); | 64 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 64 | 65 |
| 65 EXPECT_EQ(200u, set.EffectiveWindowSecs(1000 /* current time */)); | 66 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1000 /* current time */)); |
| 66 EXPECT_EQ(200u, set.EffectiveWindowSecs(1050 /* current time */)); | 67 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1050 /* current time */)); |
| 67 EXPECT_EQ(200u, set.EffectiveWindowSecs(1100 /* current time */)); | 68 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1100 /* current time */)); |
| 68 EXPECT_EQ(200u, set.EffectiveWindowSecs(1200 /* current time */)); | 69 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1200 /* current time */)); |
| 69 EXPECT_EQ(200u, set.EffectiveWindowSecs(1300 /* current time */)); | 70 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1300 /* current time */)); |
| 70 } | 71 } |
| 71 | 72 |
| 72 TEST(StrikeRegisterTest, WindowFuture) { | 73 TEST(StrikeRegisterTest, WindowFuture) { |
| 73 // The set must reject values outside the window. | 74 // The set must reject values outside the window. |
| 74 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 75 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 75 100 /* window secs */, kOrbit, | 76 100 /* window secs */, kOrbit, |
| 76 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 77 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 77 uint8 nonce[32]; | 78 uint8 nonce[32]; |
| 78 SetNonce(nonce, 1101, kOrbit); | 79 SetNonce(nonce, 1101, kOrbit); |
| 79 ASSERT_FALSE(set.Insert(nonce, 1000)); | 80 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 91 SetNonce(nonce, 1101, kBadOrbit); | 92 SetNonce(nonce, 1101, kBadOrbit); |
| 92 ASSERT_FALSE(set.Insert(nonce, 1100)); | 93 ASSERT_FALSE(set.Insert(nonce, 1100)); |
| 93 } | 94 } |
| 94 | 95 |
| 95 TEST(StrikeRegisterTest, OneValue) { | 96 TEST(StrikeRegisterTest, OneValue) { |
| 96 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 97 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 97 100 /* window secs */, kOrbit, | 98 100 /* window secs */, kOrbit, |
| 98 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 99 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 99 uint8 nonce[32]; | 100 uint8 nonce[32]; |
| 100 SetNonce(nonce, 1101, kOrbit); | 101 SetNonce(nonce, 1101, kOrbit); |
| 101 ASSERT_TRUE(set.Insert(nonce, 1100)); | 102 ASSERT_TRUE(set.Insert(nonce, 1101)); |
| 102 } | 103 } |
| 103 | 104 |
| 104 TEST(StrikeRegisterTest, RejectDuplicate) { | 105 TEST(StrikeRegisterTest, RejectDuplicate) { |
| 105 // The set must reject values with the wrong orbit | 106 // The set must reject values with the wrong orbit |
| 106 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 107 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 107 100 /* window secs */, kOrbit, | 108 100 /* window secs */, kOrbit, |
| 108 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 109 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 109 uint8 nonce[32]; | 110 uint8 nonce[32]; |
| 110 SetNonce(nonce, 1101, kOrbit); | 111 SetNonce(nonce, 1101, kOrbit); |
| 111 ASSERT_TRUE(set.Insert(nonce, 1100)); | 112 ASSERT_TRUE(set.Insert(nonce, 1101)); |
| 112 ASSERT_FALSE(set.Insert(nonce, 1100)); | 113 ASSERT_FALSE(set.Insert(nonce, 1101)); |
| 113 } | 114 } |
| 114 | 115 |
| 115 TEST(StrikeRegisterTest, HorizonUpdating) { | 116 TEST(StrikeRegisterTest, HorizonUpdating) { |
| 116 StrikeRegister::StartupType startup_types[] = { | 117 StrikeRegister::StartupType startup_types[] = { |
| 117 StrikeRegister::DENY_REQUESTS_AT_STARTUP, | 118 StrikeRegister::DENY_REQUESTS_AT_STARTUP, |
| 118 StrikeRegister::NO_STARTUP_PERIOD_NEEDED | 119 StrikeRegister::NO_STARTUP_PERIOD_NEEDED |
| 119 }; | 120 }; |
| 120 | 121 |
| 121 for (size_t type_idx = 0; type_idx < arraysize(startup_types); ++type_idx) { | 122 for (size_t type_idx = 0; type_idx < arraysize(startup_types); ++type_idx) { |
| 122 StrikeRegister set(5 /* max size */, 500 /* current time */, | 123 StrikeRegister set(5 /* max size */, 500 /* current time */, |
| 123 100 /* window secs */, kOrbit, | 124 100 /* window secs */, kOrbit, |
| 124 startup_types[type_idx]); | 125 startup_types[type_idx]); |
| 125 uint8 nonce[6][32]; | 126 uint8 nonce[6][32]; |
| 126 for (unsigned i = 0; i < 5; i++) { | 127 for (unsigned i = 0; i < 5; i++) { |
| 127 SetNonce(nonce[i], 1101 + i, kOrbit); | 128 SetNonce(nonce[i], 1101 + i, kOrbit); |
| 128 nonce[i][31] = i; | 129 nonce[i][31] = i; |
| 129 ASSERT_TRUE(set.Insert(nonce[i], 1100)); | 130 ASSERT_TRUE(set.Insert(nonce[i], 1100)); |
| 130 } | 131 } |
| 131 | 132 |
| 132 // Effective horizon is still 2 * window. | 133 // Valid window is still equal to |window_secs + 1|. |
| 133 EXPECT_EQ(200u, set.EffectiveWindowSecs(1100)); | 134 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1100)); |
| 134 | 135 |
| 135 // This should push the oldest value out and force the horizon to | 136 // This should push the oldest value out and force the horizon to |
| 136 // be updated. | 137 // be updated. |
| 137 SetNonce(nonce[5], 1110, kOrbit); | 138 SetNonce(nonce[5], 1110, kOrbit); |
| 138 ASSERT_TRUE(set.Insert(nonce[5], 1100)); | 139 ASSERT_TRUE(set.Insert(nonce[5], 1110)); |
| 139 // Effective horizon is computed based on the timestamp of the | 140 // Effective horizon is computed based on the timestamp of the |
| 140 // value that was pushed out. | 141 // value that was pushed out. |
| 141 EXPECT_EQ(98u, set.EffectiveWindowSecs(1100)); | 142 EXPECT_EQ(9u, set.GetCurrentValidWindowSecs(1110)); |
| 142 | 143 |
| 143 SetNonce(nonce[5], 1111, kOrbit); | 144 SetNonce(nonce[5], 1111, kOrbit); |
| 144 EXPECT_TRUE(set.Insert(nonce[5], 1100)); | 145 EXPECT_TRUE(set.Insert(nonce[5], 1110)); |
| 145 EXPECT_EQ(97u, set.EffectiveWindowSecs(1100)); | 146 EXPECT_EQ(8u, set.GetCurrentValidWindowSecs(1110)); |
| 146 | 147 |
| 147 // This should be behind the horizon now: | 148 // This should be behind the horizon now: |
| 148 SetNonce(nonce[5], 1101, kOrbit); | 149 SetNonce(nonce[5], 1101, kOrbit); |
| 149 nonce[5][31] = 10; | 150 nonce[5][31] = 10; |
| 150 ASSERT_FALSE(set.Insert(nonce[5], 1100)); | 151 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
| 152 |
| 153 // Insert beyond the valid range. |
| 154 SetNonce(nonce[5], 1117, kOrbit); |
| 155 nonce[5][31] = 2; |
| 156 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
| 157 |
| 158 // Insert at the upper valid range. |
| 159 SetNonce(nonce[5], 1116, kOrbit); |
| 160 nonce[5][31] = 1; |
| 161 EXPECT_TRUE(set.Insert(nonce[5], 1110)); |
| 162 |
| 163 // This should be beyond the upper valid range now: |
| 164 SetNonce(nonce[5], 1116, kOrbit); |
| 165 nonce[5][31] = 2; |
| 166 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
| 151 } | 167 } |
| 152 } | 168 } |
| 153 | 169 |
| 154 TEST(StrikeRegisterTest, InsertMany) { | 170 TEST(StrikeRegisterTest, InsertMany) { |
| 155 StrikeRegister set(5000 /* max size */, 1000 /* current time */, | 171 StrikeRegister set(5000 /* max size */, 1000 /* current time */, |
| 156 500 /* window secs */, kOrbit, | 172 500 /* window secs */, kOrbit, |
| 157 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 173 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 158 | 174 |
| 159 uint8 nonce[32]; | 175 uint8 nonce[32]; |
| 160 SetNonce(nonce, 1101, kOrbit); | 176 SetNonce(nonce, 1101, kOrbit); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 237 |
| 222 set<pair<uint32, string> >::const_iterator it = nonces_.find(nonce); | 238 set<pair<uint32, string> >::const_iterator it = nonces_.find(nonce); |
| 223 if (it != nonces_.end()) { | 239 if (it != nonces_.end()) { |
| 224 return false; | 240 return false; |
| 225 } | 241 } |
| 226 | 242 |
| 227 nonces_.insert(nonce); | 243 nonces_.insert(nonce); |
| 228 return true; | 244 return true; |
| 229 } | 245 } |
| 230 | 246 |
| 231 uint32 EffectiveWindowSecs(const uint32 current_time_external) const { | 247 uint32 GetCurrentValidWindowSecs(const uint32 current_time_external) const { |
| 232 const uint32 future_horizon = | 248 const uint32 current_time = ExternalTimeToInternal(current_time_external); |
| 233 ExternalTimeToInternal(current_time_external) + window_secs_; | 249 if (horizon_ > current_time) { |
| 234 if (horizon_ > future_horizon) { | |
| 235 return 0; | 250 return 0; |
| 236 } | 251 } |
| 237 return min(future_horizon - horizon_, 2 * window_secs_); | 252 return 1 + min(current_time - horizon_, window_secs_); |
| 238 } | 253 } |
| 239 | 254 |
| 240 private: | 255 private: |
| 241 // TimeFromBytes returns a big-endian uint32 from |d|. | 256 // TimeFromBytes returns a big-endian uint32 from |d|. |
| 242 static uint32 TimeFromBytes(const uint8 d[4]) { | 257 static uint32 TimeFromBytes(const uint8 d[4]) { |
| 243 return static_cast<uint32>(d[0]) << 24 | | 258 return static_cast<uint32>(d[0]) << 24 | |
| 244 static_cast<uint32>(d[1]) << 16 | | 259 static_cast<uint32>(d[1]) << 16 | |
| 245 static_cast<uint32>(d[2]) << 8 | | 260 static_cast<uint32>(d[2]) << 8 | |
| 246 static_cast<uint32>(d[3]); | 261 static_cast<uint32>(d[3]); |
| 247 } | 262 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 // There are 2048 possible nonce values: | 312 // There are 2048 possible nonce values: |
| 298 const uint32 v = rand() % 2048; | 313 const uint32 v = rand() % 2048; |
| 299 nonce[30] = v >> 8; | 314 nonce[30] = v >> 8; |
| 300 nonce[31] = v; | 315 nonce[31] = v; |
| 301 | 316 |
| 302 const bool r2 = s2->Insert(nonce, time, time); | 317 const bool r2 = s2->Insert(nonce, time, time); |
| 303 const bool r1 = s1->Insert(nonce, time); | 318 const bool r1 = s1->Insert(nonce, time); |
| 304 EXPECT_EQ(r1, r2); | 319 EXPECT_EQ(r1, r2); |
| 305 // Inserts succeed after the startup period. | 320 // Inserts succeed after the startup period. |
| 306 EXPECT_EQ(time > current_time + window, r1); | 321 EXPECT_EQ(time > current_time + window, r1); |
| 307 EXPECT_EQ(s1->EffectiveWindowSecs(time), | 322 EXPECT_EQ(s1->GetCurrentValidWindowSecs(time), |
| 308 s2->EffectiveWindowSecs(time)); | 323 s2->GetCurrentValidWindowSecs(time)); |
| 309 | 324 |
| 310 if (i % 10 == 0) { | 325 if (i % 10 == 0) { |
| 311 s1->Validate(); | 326 s1->Validate(); |
| 312 } | 327 } |
| 313 | 328 |
| 314 if (HasFailure()) { | 329 if (HasFailure()) { |
| 315 break; | 330 break; |
| 316 } | 331 } |
| 317 } | 332 } |
| 318 | 333 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 SetNonce(nonce, time, kOrbit); | 375 SetNonce(nonce, time, kOrbit); |
| 361 | 376 |
| 362 // There are 2048 possible nonce values: | 377 // There are 2048 possible nonce values: |
| 363 const uint32 v = rand() % 2048; | 378 const uint32 v = rand() % 2048; |
| 364 nonce[30] = v >> 8; | 379 nonce[30] = v >> 8; |
| 365 nonce[31] = v; | 380 nonce[31] = v; |
| 366 | 381 |
| 367 const bool r2 = s2->Insert(nonce, time, time); | 382 const bool r2 = s2->Insert(nonce, time, time); |
| 368 const bool r1 = s1->Insert(nonce, time); | 383 const bool r1 = s1->Insert(nonce, time); |
| 369 EXPECT_EQ(r1, r2); | 384 EXPECT_EQ(r1, r2); |
| 370 EXPECT_EQ(s1->EffectiveWindowSecs(time), | 385 EXPECT_EQ(s1->GetCurrentValidWindowSecs(time), |
| 371 s2->EffectiveWindowSecs(time)); | 386 s2->GetCurrentValidWindowSecs(time)); |
| 372 | 387 |
| 373 if (i % 10 == 0) { | 388 if (i % 10 == 0) { |
| 374 s1->Validate(); | 389 s1->Validate(); |
| 375 } | 390 } |
| 376 | 391 |
| 377 if (HasFailure()) { | 392 if (HasFailure()) { |
| 378 break; | 393 break; |
| 379 } | 394 } |
| 380 } | 395 } |
| 381 | 396 |
| 382 if (i != kMaxIterations) { | 397 if (i != kMaxIterations) { |
| 383 FAIL() << "Failed after " << i << " iterations"; | 398 FAIL() << "Failed after " << i << " iterations"; |
| 384 } | 399 } |
| 385 } | 400 } |
| 386 | 401 |
| 387 } // anonymous namespace | 402 } // anonymous namespace |
| OLD | NEW |