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.
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"
17 using base::StringPiece
;
26 char* AsChars(unsigned char* data
) { return reinterpret_cast<char*>(data
); }
32 class TestCryptoVisitor
: public ::net::CryptoFramerVisitorInterface
{
34 TestCryptoVisitor() : error_count_(0) {}
36 void OnError(CryptoFramer
* framer
) override
{
37 DLOG(ERROR
) << "CryptoFramer Error: " << framer
->error();
41 void OnHandshakeMessage(const CryptoHandshakeMessage
& message
) override
{
42 messages_
.push_back(message
);
45 // Counters from the visitor callbacks.
48 vector
<CryptoHandshakeMessage
> messages_
;
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");
58 unsigned char packet
[] = {
60 0x33, 0x77, 0xAA, 0xFF,
66 0x78, 0x56, 0x34, 0x12,
68 0x06, 0x00, 0x00, 0x00,
70 0x79, 0x56, 0x34, 0x12,
72 0x0b, 0x00, 0x00, 0x00,
74 0x7A, 0x56, 0x34, 0x12,
76 0x12, 0x00, 0x00, 0x00,
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
),
96 TEST(CryptoFramerTest
, ConstructHandshakeMessageWithTwoKeys
) {
97 CryptoHandshakeMessage message
;
98 message
.set_tag(0xFFAA7733);
99 message
.SetStringPiece(0x12345678, "abcdef");
100 message
.SetStringPiece(0x12345679, "ghijk");
102 unsigned char packet
[] = {
104 0x33, 0x77, 0xAA, 0xFF,
110 0x78, 0x56, 0x34, 0x12,
112 0x06, 0x00, 0x00, 0x00,
114 0x79, 0x56, 0x34, 0x12,
116 0x0b, 0x00, 0x00, 0x00,
126 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
127 ASSERT_TRUE(data
.get() != nullptr);
129 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
130 data
->length(), AsChars(packet
),
134 TEST(CryptoFramerTest
, ConstructHandshakeMessageZeroLength
) {
135 CryptoHandshakeMessage message
;
136 message
.set_tag(0xFFAA7733);
137 message
.SetStringPiece(0x12345678, "");
139 unsigned char packet
[] = {
141 0x33, 0x77, 0xAA, 0xFF,
147 0x78, 0x56, 0x34, 0x12,
149 0x00, 0x00, 0x00, 0x00,
153 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
154 ASSERT_TRUE(data
.get() != nullptr);
156 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
157 data
->length(), AsChars(packet
),
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");
169 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
170 EXPECT_TRUE(data
.get() == nullptr);
173 TEST(CryptoFramerTest
, ConstructHandshakeMessageMinimumSize
) {
174 CryptoHandshakeMessage message
;
175 message
.set_tag(0xFFAA7733);
176 message
.SetStringPiece(0x01020304, "test");
177 message
.set_minimum_size(64);
179 unsigned char packet
[] = {
181 0x33, 0x77, 0xAA, 0xFF,
189 0x24, 0x00, 0x00, 0x00,
191 0x04, 0x03, 0x02, 0x01,
193 0x28, 0x00, 0x00, 0x00,
194 // 36 bytes of padding.
195 '-', '-', '-', '-', '-', '-', '-', '-',
196 '-', '-', '-', '-', '-', '-', '-', '-',
197 '-', '-', '-', '-', '-', '-', '-', '-',
198 '-', '-', '-', '-', '-', '-', '-', '-',
205 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
206 ASSERT_TRUE(data
.get() != nullptr);
208 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
209 data
->length(), AsChars(packet
),
213 TEST(CryptoFramerTest
, ConstructHandshakeMessageMinimumSizePadLast
) {
214 CryptoHandshakeMessage message
;
215 message
.set_tag(0xFFAA7733);
216 message
.SetStringPiece(1, "");
217 message
.set_minimum_size(64);
219 unsigned char packet
[] = {
221 0x33, 0x77, 0xAA, 0xFF,
227 0x01, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00,
233 0x28, 0x00, 0x00, 0x00,
234 // 40 bytes of padding.
235 '-', '-', '-', '-', '-', '-', '-', '-',
236 '-', '-', '-', '-', '-', '-', '-', '-',
237 '-', '-', '-', '-', '-', '-', '-', '-',
238 '-', '-', '-', '-', '-', '-', '-', '-',
239 '-', '-', '-', '-', '-', '-', '-', '-',
243 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
244 ASSERT_TRUE(data
.get() != nullptr);
246 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
247 data
->length(), AsChars(packet
),
251 TEST(CryptoFramerTest
, ProcessInput
) {
252 test::TestCryptoVisitor visitor
;
254 framer
.set_visitor(&visitor
);
256 unsigned char input
[] = {
258 0x33, 0x77, 0xAA, 0xFF,
264 0x78, 0x56, 0x34, 0x12,
266 0x06, 0x00, 0x00, 0x00,
268 0x79, 0x56, 0x34, 0x12,
270 0x0b, 0x00, 0x00, 0x00,
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));
291 TEST(CryptoFramerTest
, ProcessInputWithThreeKeys
) {
292 test::TestCryptoVisitor visitor
;
294 framer
.set_visitor(&visitor
);
296 unsigned char input
[] = {
298 0x33, 0x77, 0xAA, 0xFF,
304 0x78, 0x56, 0x34, 0x12,
306 0x06, 0x00, 0x00, 0x00,
308 0x79, 0x56, 0x34, 0x12,
310 0x0b, 0x00, 0x00, 0x00,
312 0x7A, 0x56, 0x34, 0x12,
314 0x12, 0x00, 0x00, 0x00,
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));
339 TEST(CryptoFramerTest
, ProcessInputIncrementally
) {
340 test::TestCryptoVisitor visitor
;
342 framer
.set_visitor(&visitor
);
344 unsigned char input
[] = {
346 0x33, 0x77, 0xAA, 0xFF,
352 0x78, 0x56, 0x34, 0x12,
354 0x06, 0x00, 0x00, 0x00,
356 0x79, 0x56, 0x34, 0x12,
358 0x0b, 0x00, 0x00, 0x00,
367 for (size_t i
= 0; i
< arraysize(input
); i
++) {
368 EXPECT_TRUE(framer
.ProcessInput(StringPiece(AsChars(input
) + i
, 1)));
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));
379 TEST(CryptoFramerTest
, ProcessInputTagsOutOfOrder
) {
380 test::TestCryptoVisitor visitor
;
382 framer
.set_visitor(&visitor
);
384 unsigned char input
[] = {
386 0x33, 0x77, 0xAA, 0xFF,
392 0x78, 0x56, 0x34, 0x13,
394 0x01, 0x00, 0x00, 0x00,
396 0x79, 0x56, 0x34, 0x12,
398 0x02, 0x00, 0x00, 0x00,
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_
);
407 TEST(CryptoFramerTest
, ProcessEndOffsetsOutOfOrder
) {
408 test::TestCryptoVisitor visitor
;
410 framer
.set_visitor(&visitor
);
412 unsigned char input
[] = {
414 0x33, 0x77, 0xAA, 0xFF,
420 0x79, 0x56, 0x34, 0x12,
422 0x01, 0x00, 0x00, 0x00,
424 0x78, 0x56, 0x34, 0x13,
426 0x00, 0x00, 0x00, 0x00,
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_
);
435 TEST(CryptoFramerTest
, ProcessInputTooManyEntries
) {
436 test::TestCryptoVisitor visitor
;
438 framer
.set_visitor(&visitor
);
440 unsigned char input
[] = {
442 0x33, 0x77, 0xAA, 0xFF,
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_
);
455 TEST(CryptoFramerTest
, ProcessInputZeroLength
) {
456 test::TestCryptoVisitor visitor
;
458 framer
.set_visitor(&visitor
);
460 unsigned char input
[] = {
462 0x33, 0x77, 0xAA, 0xFF,
468 0x78, 0x56, 0x34, 0x12,
470 0x00, 0x00, 0x00, 0x00,
472 0x79, 0x56, 0x34, 0x12,
474 0x05, 0x00, 0x00, 0x00,
478 framer
.ProcessInput(StringPiece(AsChars(input
), arraysize(input
))));
479 EXPECT_EQ(0, visitor
.error_count_
);