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