15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/crypto/crypto_framer.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/crypto_handshake.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/crypto/crypto_protocol.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/crypto_test_utils.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::map;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)char* AsChars(unsigned char* data) { return reinterpret_cast<char*>(data); }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCryptoVisitor : public ::net::CryptoFramerVisitorInterface {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCryptoVisitor() : error_count_(0) {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnError(CryptoFramer* framer) OVERRIDE {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "CryptoFramer Error: " << framer->error();
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ++error_count_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHandshakeMessage(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const CryptoHandshakeMessage& message) OVERRIDE {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    messages_.push_back(message);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Counters from the visitor callbacks.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int error_count_;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  vector<CryptoHandshakeMessage> messages_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessage) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoHandshakeMessage message;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.set_tag(0xFFAA7733);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x12345678, "abcdef");
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x12345679, "ghijk");
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x1234567A, "lmnopqr");
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03, 0x00,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 1
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x06, 0x00, 0x00, 0x00,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 2
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0b, 0x00, 0x00, 0x00,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 3
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x7A, 0x56, 0x34, 0x12,
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 3
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x12, 0x00, 0x00, 0x00,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 1
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 2
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'g',  'h',  'i',  'j',
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'k',
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 3
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'l',  'm',  'n',  'o',
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'p',  'q',  'r',
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(data.get() != NULL);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet", data->data(),
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      data->length(), AsChars(packet),
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      arraysize(packet));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessageWithTwoKeys) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoHandshakeMessage message;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.set_tag(0xFFAA7733);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x12345678, "abcdef");
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x12345679, "ghijk");
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char packet[] = {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 0x00,
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 1
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x06, 0x00, 0x00, 0x00,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 2
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0b, 0x00, 0x00, 0x00,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 1
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 2
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'g',  'h',  'i',  'j',
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'k',
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(data.get() != NULL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet", data->data(),
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      data->length(), AsChars(packet),
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      arraysize(packet));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessageZeroLength) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoHandshakeMessage message;
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.set_tag(0xFFAA7733);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.SetStringPiece(0x12345678, "");
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char packet[] = {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // num entries
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x01, 0x00,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // padding
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x00, 0x00,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tag 1
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(data.get() != NULL);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet", data->data(),
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      data->length(), AsChars(packet),
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      arraysize(packet));
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessageTooManyEntries) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoHandshakeMessage message;
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message.set_tag(0xFFAA7733);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (uint32 key = 1; key <= kMaxEntries + 1; ++key) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message.SetStringPiece(key, "abcdef");
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(data.get() == NULL);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSize) {
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CryptoHandshakeMessage message;
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.set_tag(0xFFAA7733);
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.SetStringPiece(0x01020304, "test");
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.set_minimum_size(64);
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  unsigned char packet[] = {
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // num entries
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x02, 0x00,
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // padding
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag 1
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    'P', 'A', 'D', 0,
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // end offset 1
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x24, 0x00, 0x00, 0x00,
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag 2
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x04, 0x03, 0x02, 0x01,
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // end offset 2
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x28, 0x00, 0x00, 0x00,
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // 36 bytes of padding.
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-',
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // value 2
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    't', 'e', 's', 't',
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CryptoFramer framer;
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(data.get() != NULL);
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet", data->data(),
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      data->length(), AsChars(packet),
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      arraysize(packet));
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(CryptoFramerTest, ConstructHandshakeMessageMinimumSizePadLast) {
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CryptoHandshakeMessage message;
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.set_tag(0xFFAA7733);
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.SetStringPiece(1, "");
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  message.set_minimum_size(64);
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  unsigned char packet[] = {
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // num entries
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x02, 0x00,
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // padding
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00,
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag 1
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x01, 0x00, 0x00, 0x00,
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // end offset 1
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // tag 2
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    'P', 'A', 'D', 0,
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // end offset 2
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    0x28, 0x00, 0x00, 0x00,
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // 40 bytes of padding.
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    '-', '-', '-', '-', '-', '-', '-', '-',
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CryptoFramer framer;
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<QuicData> data(framer.ConstructHandshakeMessage(message));
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(data.get() != NULL);
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test::CompareCharArraysWithHexError("constructed packet", data->data(),
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      data->length(), AsChars(packet),
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      arraysize(packet));
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CryptoFramerTest, ProcessInput) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestCryptoVisitor visitor;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char input[] = {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 0x00,
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 1
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x06, 0x00, 0x00, 0x00,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 2
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0b, 0x00, 0x00, 0x00,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 1
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 2
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'g',  'h',  'i',  'j',
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'k',
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, framer.InputBytesRemaining());
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, visitor.messages_.size());
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CryptoHandshakeMessage& message = visitor.messages_[0];
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0xFFAA7733, message.tag());
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2u, message.tag_value_map().size());
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678));
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(CryptoFramerTest, ProcessInputWithThreeKeys) {
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestCryptoVisitor visitor;
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CryptoFramer framer;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&visitor);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char input[] = {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // num entries
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x03, 0x00,
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag 1
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x06, 0x00, 0x00, 0x00,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag 2
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0b, 0x00, 0x00, 0x00,
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag 3
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x7A, 0x56, 0x34, 0x12,
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 3
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x12, 0x00, 0x00, 0x00,
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // value 1
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'a',  'b',  'c',  'd',
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'e',  'f',
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // value 2
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'g',  'h',  'i',  'j',
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'k',
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // value 3
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'l',  'm',  'n',  'o',
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'p',  'q',  'r',
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, framer.InputBytesRemaining());
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, visitor.messages_.size());
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CryptoHandshakeMessage& message = visitor.messages_[0];
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0xFFAA7733, message.tag());
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3u, message.tag_value_map().size());
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678));
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679));
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("lmnopqr", CryptoTestUtils::GetValueForTag(message, 0x1234567A));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CryptoFramerTest, ProcessInputIncrementally) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestCryptoVisitor visitor;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char input[] = {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 0x00,
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 1
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x06, 0x00, 0x00, 0x00,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 2
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x0b, 0x00, 0x00, 0x00,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 1
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'a',  'b',  'c',  'd',
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'e',  'f',
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value 2
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'g',  'h',  'i',  'j',
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'k',
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(input); i++) {
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(framer.ProcessInput(StringPiece(AsChars(input) + i, 1)));
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, framer.InputBytesRemaining());
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1u, visitor.messages_.size());
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const CryptoHandshakeMessage& message = visitor.messages_[0];
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0xFFAA7733, message.tag());
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2u, message.tag_value_map().size());
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("abcdef", CryptoTestUtils::GetValueForTag(message, 0x12345678));
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("ghijk", CryptoTestUtils::GetValueForTag(message, 0x12345679));
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CryptoFramerTest, ProcessInputTagsOutOfOrder) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestCryptoVisitor visitor;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char input[] = {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x02, 0x00,
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 1
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x78, 0x56, 0x34, 0x13,
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x01, 0x00, 0x00, 0x00,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag 2
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x02, 0x00, 0x00, 0x00,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error());
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(CryptoFramerTest, ProcessEndOffsetsOutOfOrder) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestCryptoVisitor visitor;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char input[] = {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x02, 0x00,
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tag 1
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x01, 0x00, 0x00, 0x00,
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tag 2
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x78, 0x56, 0x34, 0x13,
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(
431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QUIC_CRYPTO_TAGS_OUT_OF_ORDER, framer.error());
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(CryptoFramerTest, ProcessInputTooManyEntries) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test::TestCryptoVisitor visitor;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CryptoFramer framer;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  framer.set_visitor(&visitor);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char input[] = {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tag
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // num entries
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0xA0, 0x00,
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x00,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(
451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QUIC_CRYPTO_TOO_MANY_ENTRIES, framer.error());
45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, visitor.error_count_);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(CryptoFramerTest, ProcessInputZeroLength) {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test::TestCryptoVisitor visitor;
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CryptoFramer framer;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framer.set_visitor(&visitor);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned char input[] = {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x33, 0x77, 0xAA, 0xFF,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // num entries
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x02, 0x00,
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // padding
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00,
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // tag 1
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x78, 0x56, 0x34, 0x12,
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 1
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x00, 0x00, 0x00, 0x00,
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // tag 2
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x79, 0x56, 0x34, 0x12,
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // end offset 2
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    0x05, 0x00, 0x00, 0x00,
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
478b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_TRUE(
479b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      framer.ProcessInput(StringPiece(AsChars(input), arraysize(input))));
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0, visitor.error_count_);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace test
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
486