ce815a8a28f9cb5d5fa987b63861793515dc2c5f
[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   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