| 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" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 using net::StrikeRegister; | 15 using net::StrikeRegister; |
| 16 using std::set; | 16 using std::set; |
| 17 using std::string; | 17 using std::string; |
| 18 | 18 |
| 19 const uint8 kOrbit[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; | 19 const uint8 kOrbit[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; |
| 20 | 20 |
| 21 void | 21 // StrikeRegisterTests don't look at the random bytes so this function can |
| 22 NonceSetTimeAndOrbit(uint8 nonce[32], unsigned time, const uint8 orbit[8]) { | 22 // simply set the random bytes to 0. |
| 23 void SetNonce(uint8 nonce[32], unsigned time, const uint8 orbit[8]) { |
| 23 nonce[0] = time >> 24; | 24 nonce[0] = time >> 24; |
| 24 nonce[1] = time >> 16; | 25 nonce[1] = time >> 16; |
| 25 nonce[2] = time >> 8; | 26 nonce[2] = time >> 8; |
| 26 nonce[3] = time; | 27 nonce[3] = time; |
| 27 memcpy(nonce + 4, orbit, 8); | 28 memcpy(nonce + 4, orbit, 8); |
| 28 memset(nonce + 12, 0, 20); | 29 memset(nonce + 12, 0, 20); |
| 29 } | 30 } |
| 30 | 31 |
| 31 TEST(StrikeRegisterTest, SimpleHorizon) { | 32 TEST(StrikeRegisterTest, SimpleHorizon) { |
| 32 // The set must reject values created on or before its own creation time. | 33 // The set must reject values created on or before its own creation time. |
| 33 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 34 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 34 100 /* window secs */, kOrbit, | 35 100 /* window secs */, kOrbit, |
| 35 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 36 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 36 uint8 nonce[32]; | 37 uint8 nonce[32]; |
| 37 NonceSetTimeAndOrbit(nonce, 999, kOrbit); | 38 SetNonce(nonce, 999, kOrbit); |
| 38 ASSERT_FALSE(set.Insert(nonce, 1000)); | 39 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 39 NonceSetTimeAndOrbit(nonce, 1000, kOrbit); | 40 SetNonce(nonce, 1000, kOrbit); |
| 40 ASSERT_FALSE(set.Insert(nonce, 1000)); | 41 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 41 } | 42 } |
| 42 | 43 |
| 43 TEST(StrikeRegisterTest, NoStartupMode) { | 44 TEST(StrikeRegisterTest, NoStartupMode) { |
| 44 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED | 45 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED |
| 45 // is specified. | 46 // is specified. |
| 46 StrikeRegister set(10 /* max size */, 0 /* current time */, | 47 StrikeRegister set(10 /* max size */, 0 /* current time */, |
| 47 100 /* window secs */, kOrbit, | 48 100 /* window secs */, kOrbit, |
| 48 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | 49 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); |
| 49 uint8 nonce[32]; | 50 uint8 nonce[32]; |
| 50 NonceSetTimeAndOrbit(nonce, 0, kOrbit); | 51 SetNonce(nonce, 0, kOrbit); |
| 51 ASSERT_TRUE(set.Insert(nonce, 0)); | 52 ASSERT_TRUE(set.Insert(nonce, 0)); |
| 52 ASSERT_FALSE(set.Insert(nonce, 0)); | 53 ASSERT_FALSE(set.Insert(nonce, 0)); |
| 53 } | 54 } |
| 54 | 55 |
| 55 TEST(StrikeRegisterTest, WindowFuture) { | 56 TEST(StrikeRegisterTest, WindowFuture) { |
| 56 // The set must reject values outside the window. | 57 // The set must reject values outside the window. |
| 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::DENY_REQUESTS_AT_STARTUP); | 60 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 60 uint8 nonce[32]; | 61 uint8 nonce[32]; |
| 61 NonceSetTimeAndOrbit(nonce, 1101, kOrbit); | 62 SetNonce(nonce, 1101, kOrbit); |
| 62 ASSERT_FALSE(set.Insert(nonce, 1000)); | 63 ASSERT_FALSE(set.Insert(nonce, 1000)); |
| 63 NonceSetTimeAndOrbit(nonce, 999, kOrbit); | 64 SetNonce(nonce, 999, kOrbit); |
| 64 ASSERT_FALSE(set.Insert(nonce, 1100)); | 65 ASSERT_FALSE(set.Insert(nonce, 1100)); |
| 65 } | 66 } |
| 66 | 67 |
| 67 TEST(StrikeRegisterTest, BadOrbit) { | 68 TEST(StrikeRegisterTest, BadOrbit) { |
| 68 // The set must reject values with the wrong orbit | 69 // The set must reject values with the wrong orbit |
| 69 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 70 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 70 100 /* window secs */, kOrbit, | 71 100 /* window secs */, kOrbit, |
| 71 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 72 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 72 uint8 nonce[32]; | 73 uint8 nonce[32]; |
| 73 static const uint8 kBadOrbit[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; | 74 static const uint8 kBadOrbit[8] = { 0, 0, 0, 0, 1, 1, 1, 1 }; |
| 74 NonceSetTimeAndOrbit(nonce, 1101, kBadOrbit); | 75 SetNonce(nonce, 1101, kBadOrbit); |
| 75 ASSERT_FALSE(set.Insert(nonce, 1100)); | 76 ASSERT_FALSE(set.Insert(nonce, 1100)); |
| 76 } | 77 } |
| 77 | 78 |
| 78 TEST(StrikeRegisterTest, OneValue) { | 79 TEST(StrikeRegisterTest, OneValue) { |
| 79 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 80 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 80 100 /* window secs */, kOrbit, | 81 100 /* window secs */, kOrbit, |
| 81 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 82 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 82 uint8 nonce[32]; | 83 uint8 nonce[32]; |
| 83 NonceSetTimeAndOrbit(nonce, 1101, kOrbit); | 84 SetNonce(nonce, 1101, kOrbit); |
| 84 ASSERT_TRUE(set.Insert(nonce, 1100)); | 85 ASSERT_TRUE(set.Insert(nonce, 1100)); |
| 85 } | 86 } |
| 86 | 87 |
| 87 TEST(StrikeRegisterTest, RejectDuplicate) { | 88 TEST(StrikeRegisterTest, RejectDuplicate) { |
| 88 // The set must reject values with the wrong orbit | 89 // The set must reject values with the wrong orbit |
| 89 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 90 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
| 90 100 /* window secs */, kOrbit, | 91 100 /* window secs */, kOrbit, |
| 91 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 92 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 92 uint8 nonce[32]; | 93 uint8 nonce[32]; |
| 93 memset(nonce, 0, sizeof(nonce)); | 94 SetNonce(nonce, 1101, kOrbit); |
| 94 NonceSetTimeAndOrbit(nonce, 1101, kOrbit); | |
| 95 ASSERT_TRUE(set.Insert(nonce, 1100)); | 95 ASSERT_TRUE(set.Insert(nonce, 1100)); |
| 96 ASSERT_FALSE(set.Insert(nonce, 1100)); | 96 ASSERT_FALSE(set.Insert(nonce, 1100)); |
| 97 } | 97 } |
| 98 | 98 |
| 99 TEST(StrikeRegisterTest, HorizonUpdating) { | 99 TEST(StrikeRegisterTest, HorizonUpdating) { |
| 100 StrikeRegister set(5 /* max size */, 1000 /* current time */, | 100 StrikeRegister set(5 /* max size */, 1000 /* current time */, |
| 101 100 /* window secs */, kOrbit, | 101 100 /* window secs */, kOrbit, |
| 102 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 102 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 103 uint8 nonce[6][32]; | 103 uint8 nonce[6][32]; |
| 104 for (unsigned i = 0; i < 5; i++) { | 104 for (unsigned i = 0; i < 5; i++) { |
| 105 NonceSetTimeAndOrbit(nonce[i], 1101, kOrbit); | 105 SetNonce(nonce[i], 1101, kOrbit); |
| 106 memset(nonce[i] + 12, 0, 20); | |
| 107 nonce[i][31] = i; | 106 nonce[i][31] = i; |
| 108 ASSERT_TRUE(set.Insert(nonce[i], 1100)); | 107 ASSERT_TRUE(set.Insert(nonce[i], 1100)); |
| 109 } | 108 } |
| 110 | 109 |
| 111 // This should push the oldest value out and force the horizon to be updated. | 110 // This should push the oldest value out and force the horizon to be updated. |
| 112 NonceSetTimeAndOrbit(nonce[5], 1102, kOrbit); | 111 SetNonce(nonce[5], 1102, kOrbit); |
| 113 memset(nonce[5] + 12, 0, 20); | |
| 114 ASSERT_TRUE(set.Insert(nonce[5], 1100)); | 112 ASSERT_TRUE(set.Insert(nonce[5], 1100)); |
| 115 | 113 |
| 116 // This should be behind the horizon now: | 114 // This should be behind the horizon now: |
| 117 NonceSetTimeAndOrbit(nonce[5], 1101, kOrbit); | 115 SetNonce(nonce[5], 1101, kOrbit); |
| 118 memset(nonce[5] + 12, 0, 20); | |
| 119 nonce[5][31] = 10; | 116 nonce[5][31] = 10; |
| 120 ASSERT_FALSE(set.Insert(nonce[5], 1100)); | 117 ASSERT_FALSE(set.Insert(nonce[5], 1100)); |
| 121 } | 118 } |
| 122 | 119 |
| 123 TEST(StrikeRegisterTest, InsertMany) { | 120 TEST(StrikeRegisterTest, InsertMany) { |
| 124 StrikeRegister set(5000 /* max size */, 1000 /* current time */, | 121 StrikeRegister set(5000 /* max size */, 1000 /* current time */, |
| 125 500 /* window secs */, kOrbit, | 122 500 /* window secs */, kOrbit, |
| 126 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 123 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
| 127 | 124 |
| 128 uint8 nonce[32]; | 125 uint8 nonce[32]; |
| 129 NonceSetTimeAndOrbit(nonce, 1101, kOrbit); | 126 SetNonce(nonce, 1101, kOrbit); |
| 130 for (unsigned i = 0; i < 100000; i++) { | 127 for (unsigned i = 0; i < 100000; i++) { |
| 131 NonceSetTimeAndOrbit(nonce, 1101 + i/500, kOrbit); | 128 SetNonce(nonce, 1101 + i/500, kOrbit); |
| 132 memcpy(nonce + 12, &i, sizeof(i)); | 129 memcpy(nonce + 12, &i, sizeof(i)); |
| 133 set.Insert(nonce, 1100); | 130 set.Insert(nonce, 1100); |
| 134 } | 131 } |
| 135 } | 132 } |
| 136 | 133 |
| 137 | 134 |
| 138 // For the following test we create a slow, but simple, version of a | 135 // For the following test we create a slow, but simple, version of a |
| 139 // StrikeRegister. The behaviour of this object is much easier to understand | 136 // StrikeRegister. The behaviour of this object is much easier to understand |
| 140 // than the fully fledged version. We then create a test to show, empirically, | 137 // than the fully fledged version. We then create a test to show, empirically, |
| 141 // that the two objects have identical behaviour. | 138 // that the two objects have identical behaviour. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 } | 269 } |
| 273 | 270 |
| 274 int32 time_delta = rand() % (window * 4); | 271 int32 time_delta = rand() % (window * 4); |
| 275 time_delta -= window * 2; | 272 time_delta -= window * 2; |
| 276 const uint32 time = current_time + time_delta; | 273 const uint32 time = current_time + time_delta; |
| 277 if (time_delta < 0 && time > current_time) { | 274 if (time_delta < 0 && time > current_time) { |
| 278 continue; // overflow | 275 continue; // overflow |
| 279 } | 276 } |
| 280 | 277 |
| 281 uint8 nonce[32]; | 278 uint8 nonce[32]; |
| 282 NonceSetTimeAndOrbit(nonce, time, kOrbit); | 279 SetNonce(nonce, time, kOrbit); |
| 283 memset(nonce + 12, 0, 20); | |
| 284 | 280 |
| 285 // There are 2048 possible nonce values: | 281 // There are 2048 possible nonce values: |
| 286 const uint32 v = rand() % 2048; | 282 const uint32 v = rand() % 2048; |
| 287 nonce[30] = v >> 8; | 283 nonce[30] = v >> 8; |
| 288 nonce[31] = v; | 284 nonce[31] = v; |
| 289 | 285 |
| 290 const bool r2 = s2->Insert(nonce, time); | 286 const bool r2 = s2->Insert(nonce, time); |
| 291 const bool r1 = s1->Insert(nonce, time); | 287 const bool r1 = s1->Insert(nonce, time); |
| 292 | 288 |
| 293 if (r1 != r2) { | 289 if (r1 != r2) { |
| 294 break; | 290 break; |
| 295 } | 291 } |
| 296 | 292 |
| 297 if (i % 10 == 0) { | 293 if (i % 10 == 0) { |
| 298 s1->Validate(); | 294 s1->Validate(); |
| 299 } | 295 } |
| 300 } | 296 } |
| 301 | 297 |
| 302 if (i != kMaxIterations) { | 298 if (i != kMaxIterations) { |
| 303 FAIL() << "Failed after " << i << " iterations"; | 299 FAIL() << "Failed after " << i << " iterations"; |
| 304 } | 300 } |
| 305 } | 301 } |
| 306 | 302 |
| 307 } // anonymous namespace | 303 } // anonymous namespace |
| OLD | NEW |