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