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