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 virtual void OnError(CryptoFramer
* framer
) OVERRIDE
{
37 DLOG(ERROR
) << "CryptoFramer Error: " << framer
->error();
41 virtual void OnHandshakeMessage(
42 const CryptoHandshakeMessage
& message
) OVERRIDE
{
43 messages_
.push_back(message
);
46 // Counters from the visitor callbacks.
49 vector
<CryptoHandshakeMessage
> messages_
;
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");
59 unsigned char packet
[] = {
61 0x33, 0x77, 0xAA, 0xFF,
67 0x78, 0x56, 0x34, 0x12,
69 0x06, 0x00, 0x00, 0x00,
71 0x79, 0x56, 0x34, 0x12,
73 0x0b, 0x00, 0x00, 0x00,
75 0x7A, 0x56, 0x34, 0x12,
77 0x12, 0x00, 0x00, 0x00,
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
),
97 TEST(CryptoFramerTest
, ConstructHandshakeMessageWithTwoKeys
) {
98 CryptoHandshakeMessage message
;
99 message
.set_tag(0xFFAA7733);
100 message
.SetStringPiece(0x12345678, "abcdef");
101 message
.SetStringPiece(0x12345679, "ghijk");
103 unsigned char packet
[] = {
105 0x33, 0x77, 0xAA, 0xFF,
111 0x78, 0x56, 0x34, 0x12,
113 0x06, 0x00, 0x00, 0x00,
115 0x79, 0x56, 0x34, 0x12,
117 0x0b, 0x00, 0x00, 0x00,
127 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
128 ASSERT_TRUE(data
.get() != NULL
);
130 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
131 data
->length(), AsChars(packet
),
135 TEST(CryptoFramerTest
, ConstructHandshakeMessageZeroLength
) {
136 CryptoHandshakeMessage message
;
137 message
.set_tag(0xFFAA7733);
138 message
.SetStringPiece(0x12345678, "");
140 unsigned char packet
[] = {
142 0x33, 0x77, 0xAA, 0xFF,
148 0x78, 0x56, 0x34, 0x12,
150 0x00, 0x00, 0x00, 0x00,
154 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
155 ASSERT_TRUE(data
.get() != NULL
);
157 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
158 data
->length(), AsChars(packet
),
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");
170 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
171 EXPECT_TRUE(data
.get() == NULL
);
174 TEST(CryptoFramerTest
, ConstructHandshakeMessageMinimumSize
) {
175 CryptoHandshakeMessage message
;
176 message
.set_tag(0xFFAA7733);
177 message
.SetStringPiece(0x01020304, "test");
178 message
.set_minimum_size(64);
180 unsigned char packet
[] = {
182 0x33, 0x77, 0xAA, 0xFF,
190 0x24, 0x00, 0x00, 0x00,
192 0x04, 0x03, 0x02, 0x01,
194 0x28, 0x00, 0x00, 0x00,
195 // 36 bytes of padding.
196 '-', '-', '-', '-', '-', '-', '-', '-',
197 '-', '-', '-', '-', '-', '-', '-', '-',
198 '-', '-', '-', '-', '-', '-', '-', '-',
199 '-', '-', '-', '-', '-', '-', '-', '-',
206 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
207 ASSERT_TRUE(data
.get() != NULL
);
209 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
210 data
->length(), AsChars(packet
),
214 TEST(CryptoFramerTest
, ConstructHandshakeMessageMinimumSizePadLast
) {
215 CryptoHandshakeMessage message
;
216 message
.set_tag(0xFFAA7733);
217 message
.SetStringPiece(1, "");
218 message
.set_minimum_size(64);
220 unsigned char packet
[] = {
222 0x33, 0x77, 0xAA, 0xFF,
228 0x01, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00,
234 0x28, 0x00, 0x00, 0x00,
235 // 40 bytes of padding.
236 '-', '-', '-', '-', '-', '-', '-', '-',
237 '-', '-', '-', '-', '-', '-', '-', '-',
238 '-', '-', '-', '-', '-', '-', '-', '-',
239 '-', '-', '-', '-', '-', '-', '-', '-',
240 '-', '-', '-', '-', '-', '-', '-', '-',
244 scoped_ptr
<QuicData
> data(framer
.ConstructHandshakeMessage(message
));
245 ASSERT_TRUE(data
.get() != NULL
);
247 test::CompareCharArraysWithHexError("constructed packet", data
->data(),
248 data
->length(), AsChars(packet
),
252 TEST(CryptoFramerTest
, ProcessInput
) {
253 test::TestCryptoVisitor visitor
;
255 framer
.set_visitor(&visitor
);
257 unsigned char input
[] = {
259 0x33, 0x77, 0xAA, 0xFF,
265 0x78, 0x56, 0x34, 0x12,
267 0x06, 0x00, 0x00, 0x00,
269 0x79, 0x56, 0x34, 0x12,
271 0x0b, 0x00, 0x00, 0x00,
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));
292 TEST(CryptoFramerTest
, ProcessInputWithThreeKeys
) {
293 test::TestCryptoVisitor visitor
;
295 framer
.set_visitor(&visitor
);
297 unsigned char input
[] = {
299 0x33, 0x77, 0xAA, 0xFF,
305 0x78, 0x56, 0x34, 0x12,
307 0x06, 0x00, 0x00, 0x00,
309 0x79, 0x56, 0x34, 0x12,
311 0x0b, 0x00, 0x00, 0x00,
313 0x7A, 0x56, 0x34, 0x12,
315 0x12, 0x00, 0x00, 0x00,
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));
340 TEST(CryptoFramerTest
, ProcessInputIncrementally
) {
341 test::TestCryptoVisitor visitor
;
343 framer
.set_visitor(&visitor
);
345 unsigned char input
[] = {
347 0x33, 0x77, 0xAA, 0xFF,
353 0x78, 0x56, 0x34, 0x12,
355 0x06, 0x00, 0x00, 0x00,
357 0x79, 0x56, 0x34, 0x12,
359 0x0b, 0x00, 0x00, 0x00,
368 for (size_t i
= 0; i
< arraysize(input
); i
++) {
369 EXPECT_TRUE(framer
.ProcessInput(StringPiece(AsChars(input
) + i
, 1)));
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));
380 TEST(CryptoFramerTest
, ProcessInputTagsOutOfOrder
) {
381 test::TestCryptoVisitor visitor
;
383 framer
.set_visitor(&visitor
);
385 unsigned char input
[] = {
387 0x33, 0x77, 0xAA, 0xFF,
393 0x78, 0x56, 0x34, 0x13,
395 0x01, 0x00, 0x00, 0x00,
397 0x79, 0x56, 0x34, 0x12,
399 0x02, 0x00, 0x00, 0x00,
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_
);
408 TEST(CryptoFramerTest
, ProcessEndOffsetsOutOfOrder
) {
409 test::TestCryptoVisitor visitor
;
411 framer
.set_visitor(&visitor
);
413 unsigned char input
[] = {
415 0x33, 0x77, 0xAA, 0xFF,
421 0x79, 0x56, 0x34, 0x12,
423 0x01, 0x00, 0x00, 0x00,
425 0x78, 0x56, 0x34, 0x13,
427 0x00, 0x00, 0x00, 0x00,
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_
);
436 TEST(CryptoFramerTest
, ProcessInputTooManyEntries
) {
437 test::TestCryptoVisitor visitor
;
439 framer
.set_visitor(&visitor
);
441 unsigned char input
[] = {
443 0x33, 0x77, 0xAA, 0xFF,
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_
);
456 TEST(CryptoFramerTest
, ProcessInputZeroLength
) {
457 test::TestCryptoVisitor visitor
;
459 framer
.set_visitor(&visitor
);
461 unsigned char input
[] = {
463 0x33, 0x77, 0xAA, 0xFF,
469 0x78, 0x56, 0x34, 0x12,
471 0x00, 0x00, 0x00, 0x00,
473 0x79, 0x56, 0x34, 0x12,
475 0x05, 0x00, 0x00, 0x00,
479 framer
.ProcessInput(StringPiece(AsChars(input
), arraysize(input
))));
480 EXPECT_EQ(0, visitor
.error_count_
);