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 |