OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <map> | |
6 #include <vector> | |
7 | |
8 #include "base/logging.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "net/quic/crypto/crypto_framer.h" | |
11 #include "net/quic/crypto/crypto_handshake.h" | |
12 #include "net/quic/crypto/crypto_protocol.h" | |
13 #include "net/quic/quic_protocol.h" | |
14 #include "net/quic/test_tools/crypto_test_utils.h" | |
15 #include "net/quic/test_tools/quic_test_utils.h" | |
16 | |
17 using base::StringPiece; | |
18 using std::map; | |
19 using std::string; | |
20 using std::vector; | |
21 | |
22 namespace net { | |
23 | |
24 namespace { | |
25 | |
26 char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); } | |
27 | |
28 } // namespace | |
29 | |
30 namespace test { | |
31 | |
32 class TestCryptoVisitor : public ::net::CryptoFramerVisitorInterface { | |
33 public: | |
34 TestCryptoVisitor() : error_count_(0) {} | |
35 | |
36 void OnError(CryptoFramer* framer) override { | |
37 DLOG(ERROR) << "CryptoFramer Error: " << framer->error(); | |
38 ++error_count_; | |
39 } | |
40 | |
41 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override { | |
42 messages_.push_back(message); | |
43 } | |
44 | |
45 // Counters from the visitor callbacks. | |
46 int error_count_; | |
47 | |
48 vector<CryptoHandshakeMessage> messages_; | |
49 }; | |
50 | |
51 TEST(CryptoFramerTest, ConstructHandshakeMessage) { | |
52 CryptoHandshakeMessage message; | |
53 message.set_tag(0xFFAA7733); | |
54 message.SetStringPiece(0x12345678, "abcdef"); | |
55 message.SetStringPiece(0x12345679, "ghijk"); | |
56 message.SetStringPiece(0x1234567A, "lmnopqr"); | |
57 | |
58 unsigned char packet[] = { | |
59 // tag | |
60 0x33, 0x77, 0xAA, 0xFF, | |
61 // num entries | |
62 0x03, 0x00, | |
63 // padding | |
64 0x00, 0x00, | |
65 // tag 1 | |
66 0x78, 0x56, 0x34, 0x12, | |
67 // end offset 1 | |
68 0x06, 0x00, 0x00, 0x00, | |
69 // tag 2 | |
70 0x79, 0x56, 0x34, 0x12, | |
71 // end offset 2 | |
72 0x0b, 0x00, 0x00, 0x00, | |
73 // tag 3 | |
74 0x7A, 0x56, 0x34, 0x12, | |
75 // end offset 3 | |
76 0x12, 0x00, 0x00, 0x00, | |
77 // value 1 | |
78 'a', 'b', 'c', 'd', | |
79 'e', 'f', | |
80 // value 2 | |
81 'g', 'h', 'i', 'j', | |
82 'k', | |
83 // value 3 | |
84 'l', 'm', 'n', 'o', | |
85 'p', 'q', 'r', | |
86 }; | |
87 | |
88 CryptoFramer framer; | |
89 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
90 ASSERT_TRUE(data.get() != nullptr); | |
91 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
92 data->length(), AsChars(packet), | |
93 arraysize(packet)); | |
94 } | |
95 | |
96 TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) { | |
97 CryptoHandshakeMessage message; | |
98 message.set_tag(0xFFAA7733); | |
99 message.SetStringPiece(0x12345678, "abcdef"); | |
100 message.SetStringPiece(0x12345679, "ghijk"); | |
101 | |
102 unsigned char packet[] = { | |
103 // tag | |
104 0x33, 0x77, 0xAA, 0xFF, | |
105 // num entries | |
106 0x02, 0x00, | |
107 // padding | |
108 0x00, 0x00, | |
109 // tag 1 | |
110 0x78, 0x56, 0x34, 0x12, | |
111 // end offset 1 | |
112 0x06, 0x00, 0x00, 0x00, | |
113 // tag 2 | |
114 0x79, 0x56, 0x34, 0x12, | |
115 // end offset 2 | |
116 0x0b, 0x00, 0x00, 0x00, | |
117 // value 1 | |
118 'a', 'b', 'c', 'd', | |
119 'e', 'f', | |
120 // value 2 | |
121 'g', 'h', 'i', 'j', | |
122 'k', | |
123 }; | |
124 | |
125 CryptoFramer framer; | |
126 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
127 ASSERT_TRUE(data.get() != nullptr); | |
128 | |
129 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
130 data->length(), AsChars(packet), | |
131 arraysize(packet)); | |
132 } | |
133 | |
134 TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) { | |
135 CryptoHandshakeMessage message; | |
136 message.set_tag(0xFFAA7733); | |
137 message.SetStringPiece(0x12345678, ""); | |
138 | |
139 unsigned char packet[] = { | |
140 // tag | |
141 0x33, 0x77, 0xAA, 0xFF, | |
142 // num entries | |
143 0x01, 0x00, | |
144 // padding | |
145 0x00, 0x00, | |
146 // tag 1 | |
147 0x78, 0x56, 0x34, 0x12, | |
148 // end offset 1 | |
149 0x00, 0x00, 0x00, 0x00, | |
150 }; | |
151 | |
152 CryptoFramer framer; | |
153 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
154 ASSERT_TRUE(data.get() != nullptr); | |
155 | |
156 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
157 data->length(), AsChars(packet), | |
158 arraysize(packet)); | |
159 } | |
160 | |
161 TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) { | |
162 CryptoHandshakeMessage message; | |
163 message.set_tag(0xFFAA7733); | |
164 for (uint32 key = 1; key <= kMaxEntries + 1; ++key) { | |
165 message.SetStringPiece(key, "abcdef"); | |
166 } | |
167 | |
168 CryptoFramer framer; | |
169 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
170 EXPECT_TRUE(data.get() == nullptr); | |
171 } | |
172 | |
173 TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) { | |
174 CryptoHandshakeMessage message; | |
175 message.set_tag(0xFFAA7733); | |
176 message.SetStringPiece(0x01020304, "test"); | |
177 message.set_minimum_size(64); | |
178 | |
179 unsigned char packet[] = { | |
180 // tag | |
181 0x33, 0x77, 0xAA, 0xFF, | |
182 // num entries | |
183 0x02, 0x00, | |
184 // padding | |
185 0x00, 0x00, | |
186 // tag 1 | |
187 'P', 'A', 'D', 0, | |
188 // end offset 1 | |
189 0x24, 0x00, 0x00, 0x00, | |
190 // tag 2 | |
191 0x04, 0x03, 0x02, 0x01, | |
192 // end offset 2 | |
193 0x28, 0x00, 0x00, 0x00, | |
194 // 36 bytes of padding. | |
195 '-', '-', '-', '-', '-', '-', '-', '-', | |
196 '-', '-', '-', '-', '-', '-', '-', '-', | |
197 '-', '-', '-', '-', '-', '-', '-', '-', | |
198 '-', '-', '-', '-', '-', '-', '-', '-', | |
199 '-', '-', '-', '-', | |
200 // value 2 | |
201 't', 'e', 's', 't', | |
202 }; | |
203 | |
204 CryptoFramer framer; | |
205 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
206 ASSERT_TRUE(data.get() != nullptr); | |
207 | |
208 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
209 data->length(), AsChars(packet), | |
210 arraysize(packet)); | |
211 } | |
212 | |
213 TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) { | |
214 CryptoHandshakeMessage message; | |
215 message.set_tag(0xFFAA7733); | |
216 message.SetStringPiece(1, ""); | |
217 message.set_minimum_size(64); | |
218 | |
219 unsigned char packet[] = { | |
220 // tag | |
221 0x33, 0x77, 0xAA, 0xFF, | |
222 // num entries | |
223 0x02, 0x00, | |
224 // padding | |
225 0x00, 0x00, | |
226 // tag 1 | |
227 0x01, 0x00, 0x00, 0x00, | |
228 // end offset 1 | |
229 0x00, 0x00, 0x00, 0x00, | |
230 // tag 2 | |
231 'P', 'A', 'D', 0, | |
232 // end offset 2 | |
233 0x28, 0x00, 0x00, 0x00, | |
234 // 40 bytes of padding. | |
235 '-', '-', '-', '-', '-', '-', '-', '-', | |
236 '-', '-', '-', '-', '-', '-', '-', '-', | |
237 '-', '-', '-', '-', '-', '-', '-', '-', | |
238 '-', '-', '-', '-', '-', '-', '-', '-', | |
239 '-', '-', '-', '-', '-', '-', '-', '-', | |
240 }; | |
241 | |
242 CryptoFramer framer; | |
243 scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message)); | |
244 ASSERT_TRUE(data.get() != nullptr); | |
245 | |
246 test::CompareCharArraysWithHexError("constructed packet", data->data(), | |
247 data->length(), AsChars(packet), | |
248 arraysize(packet)); | |
249 } | |
250 | |
251 TEST(CryptoFramerTest, ProcessInput) { | |
252 test::TestCryptoVisitor visitor; | |
253 CryptoFramer framer; | |
254 framer.set_visitor(&visitor); | |
255 | |
256 unsigned char input[] = { | |
257 // tag | |
258 0x33, 0x77, 0xAA, 0xFF, | |
259 // num entries | |
260 0x02, 0x00, | |
261 // padding | |
262 0x00, 0x00, | |
263 // tag 1 | |
264 0x78, 0x56, 0x34, 0x12, | |
265 // end offset 1 | |
266 0x06, 0x00, 0x00, 0x00, | |
267 // tag 2 | |
268 0x79, 0x56, 0x34, 0x12, | |
269 // end offset 2 | |
270 0x0b, 0x00, 0x00, 0x00, | |
271 // value 1 | |
272 'a', 'b', 'c', 'd', | |
273 'e', 'f', | |
274 // value 2 | |
275 'g', 'h', 'i', 'j', | |
276 'k', | |
277 }; | |
278 | |
279 EXPECT_TRUE( | |
280 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
281 EXPECT_EQ(0u, framer.InputBytesRemaining()); | |
282 EXPECT_EQ(0, visitor.error_count_); | |
283 ASSERT_EQ(1u, visitor.messages_.size()); | |
284 const CryptoHandshakeMessage& message = visitor.messages_[0]; | |
285 EXPECT_EQ(0xFFAA7733, message.tag()); | |
286 EXPECT_EQ(2u, message.tag_value_map().size()); | |
287 EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); | |
288 EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); | |
289 } | |
290 | |
291 TEST(CryptoFramerTest, ProcessInputWithThreeKeys) { | |
292 test::TestCryptoVisitor visitor; | |
293 CryptoFramer framer; | |
294 framer.set_visitor(&visitor); | |
295 | |
296 unsigned char input[] = { | |
297 // tag | |
298 0x33, 0x77, 0xAA, 0xFF, | |
299 // num entries | |
300 0x03, 0x00, | |
301 // padding | |
302 0x00, 0x00, | |
303 // tag 1 | |
304 0x78, 0x56, 0x34, 0x12, | |
305 // end offset 1 | |
306 0x06, 0x00, 0x00, 0x00, | |
307 // tag 2 | |
308 0x79, 0x56, 0x34, 0x12, | |
309 // end offset 2 | |
310 0x0b, 0x00, 0x00, 0x00, | |
311 // tag 3 | |
312 0x7A, 0x56, 0x34, 0x12, | |
313 // end offset 3 | |
314 0x12, 0x00, 0x00, 0x00, | |
315 // value 1 | |
316 'a', 'b', 'c', 'd', | |
317 'e', 'f', | |
318 // value 2 | |
319 'g', 'h', 'i', 'j', | |
320 'k', | |
321 // value 3 | |
322 'l', 'm', 'n', 'o', | |
323 'p', 'q', 'r', | |
324 }; | |
325 | |
326 EXPECT_TRUE( | |
327 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
328 EXPECT_EQ(0u, framer.InputBytesRemaining()); | |
329 EXPECT_EQ(0, visitor.error_count_); | |
330 ASSERT_EQ(1u, visitor.messages_.size()); | |
331 const CryptoHandshakeMessage& message = visitor.messages_[0]; | |
332 EXPECT_EQ(0xFFAA7733, message.tag()); | |
333 EXPECT_EQ(3u, message.tag_value_map().size()); | |
334 EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); | |
335 EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); | |
336 EXPECT_EQ("lmnopqr", CryptoTestUtils::GetValueForTag(message, 0x1234567A)); | |
337 } | |
338 | |
339 TEST(CryptoFramerTest, ProcessInputIncrementally) { | |
340 test::TestCryptoVisitor visitor; | |
341 CryptoFramer framer; | |
342 framer.set_visitor(&visitor); | |
343 | |
344 unsigned char input[] = { | |
345 // tag | |
346 0x33, 0x77, 0xAA, 0xFF, | |
347 // num entries | |
348 0x02, 0x00, | |
349 // padding | |
350 0x00, 0x00, | |
351 // tag 1 | |
352 0x78, 0x56, 0x34, 0x12, | |
353 // end offset 1 | |
354 0x06, 0x00, 0x00, 0x00, | |
355 // tag 2 | |
356 0x79, 0x56, 0x34, 0x12, | |
357 // end offset 2 | |
358 0x0b, 0x00, 0x00, 0x00, | |
359 // value 1 | |
360 'a', 'b', 'c', 'd', | |
361 'e', 'f', | |
362 // value 2 | |
363 'g', 'h', 'i', 'j', | |
364 'k', | |
365 }; | |
366 | |
367 for (size_t i = 0; i < arraysize(input); i++) { | |
368 EXPECT_TRUE(framer.ProcessInput(StringPiece(AsChars(input) + i, 1))); | |
369 } | |
370 EXPECT_EQ(0u, framer.InputBytesRemaining()); | |
371 ASSERT_EQ(1u, visitor.messages_.size()); | |
372 const CryptoHandshakeMessage& message = visitor.messages_[0]; | |
373 EXPECT_EQ(0xFFAA7733, message.tag()); | |
374 EXPECT_EQ(2u, message.tag_value_map().size()); | |
375 EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678)); | |
376 EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679)); | |
377 } | |
378 | |
379 TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) { | |
380 test::TestCryptoVisitor visitor; | |
381 CryptoFramer framer; | |
382 framer.set_visitor(&visitor); | |
383 | |
384 unsigned char input[] = { | |
385 // tag | |
386 0x33, 0x77, 0xAA, 0xFF, | |
387 // num entries | |
388 0x02, 0x00, | |
389 // padding | |
390 0x00, 0x00, | |
391 // tag 1 | |
392 0x78, 0x56, 0x34, 0x13, | |
393 // end offset 1 | |
394 0x01, 0x00, 0x00, 0x00, | |
395 // tag 2 | |
396 0x79, 0x56, 0x34, 0x12, | |
397 // end offset 2 | |
398 0x02, 0x00, 0x00, 0x00, | |
399 }; | |
400 | |
401 EXPECT_FALSE( | |
402 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
403 EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error()); | |
404 EXPECT_EQ(1, visitor.error_count_); | |
405 } | |
406 | |
407 TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) { | |
408 test::TestCryptoVisitor visitor; | |
409 CryptoFramer framer; | |
410 framer.set_visitor(&visitor); | |
411 | |
412 unsigned char input[] = { | |
413 // tag | |
414 0x33, 0x77, 0xAA, 0xFF, | |
415 // num entries | |
416 0x02, 0x00, | |
417 // padding | |
418 0x00, 0x00, | |
419 // tag 1 | |
420 0x79, 0x56, 0x34, 0x12, | |
421 // end offset 1 | |
422 0x01, 0x00, 0x00, 0x00, | |
423 // tag 2 | |
424 0x78, 0x56, 0x34, 0x13, | |
425 // end offset 2 | |
426 0x00, 0x00, 0x00, 0x00, | |
427 }; | |
428 | |
429 EXPECT_FALSE( | |
430 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
431 EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error()); | |
432 EXPECT_EQ(1, visitor.error_count_); | |
433 } | |
434 | |
435 TEST(CryptoFramerTest, ProcessInputTooManyEntries) { | |
436 test::TestCryptoVisitor visitor; | |
437 CryptoFramer framer; | |
438 framer.set_visitor(&visitor); | |
439 | |
440 unsigned char input[] = { | |
441 // tag | |
442 0x33, 0x77, 0xAA, 0xFF, | |
443 // num entries | |
444 0xA0, 0x00, | |
445 // padding | |
446 0x00, 0x00, | |
447 }; | |
448 | |
449 EXPECT_FALSE( | |
450 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
451 EXPECT_EQ(QUIC_CRYPTO_TOO_MANY_ENTRIES, framer.error()); | |
452 EXPECT_EQ(1, visitor.error_count_); | |
453 } | |
454 | |
455 TEST(CryptoFramerTest, ProcessInputZeroLength) { | |
456 test::TestCryptoVisitor visitor; | |
457 CryptoFramer framer; | |
458 framer.set_visitor(&visitor); | |
459 | |
460 unsigned char input[] = { | |
461 // tag | |
462 0x33, 0x77, 0xAA, 0xFF, | |
463 // num entries | |
464 0x02, 0x00, | |
465 // padding | |
466 0x00, 0x00, | |
467 // tag 1 | |
468 0x78, 0x56, 0x34, 0x12, | |
469 // end offset 1 | |
470 0x00, 0x00, 0x00, 0x00, | |
471 // tag 2 | |
472 0x79, 0x56, 0x34, 0x12, | |
473 // end offset 2 | |
474 0x05, 0x00, 0x00, 0x00, | |
475 }; | |
476 | |
477 EXPECT_TRUE( | |
478 framer.ProcessInput(StringPiece(AsChars(input), arraysize(input)))); | |
479 EXPECT_EQ(0, visitor.error_count_); | |
480 } | |
481 | |
482 } // namespace test | |
483 | |
484 } // namespace net | |
OLD | NEW |