Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_crypto_client_stream_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 "net/quic/quic_crypto_client_stream.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
9 #include "net/quic/crypto/quic_decrypter.h"
10 #include "net/quic/crypto/quic_encrypter.h"
11 #include "net/quic/quic_flags.h"
12 #include "net/quic/quic_protocol.h"
13 #include "net/quic/quic_server_id.h"
14 #include "net/quic/quic_utils.h"
15 #include "net/quic/test_tools/crypto_test_utils.h"
16 #include "net/quic/test_tools/quic_test_utils.h"
17 #include "net/quic/test_tools/simple_quic_framer.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace net {
22 namespace test {
23 namespace {
24
25 const char kServerHostname[] = "example.com";
26 const uint16 kServerPort = 80;
27
28 class QuicCryptoClientStreamTest : public ::testing::Test {
29  public:
30   QuicCryptoClientStreamTest()
31       : connection_(new PacketSavingConnection(false)),
32         session_(new TestClientSession(connection_, DefaultQuicConfig())),
33         server_id_(kServerHostname, kServerPort, false, PRIVACY_MODE_DISABLED),
34         stream_(new QuicCryptoClientStream(server_id_, session_.get(), nullptr,
35                                            &crypto_config_)) {
36     session_->SetCryptoStream(stream_.get());
37   }
38
39   void CompleteCryptoHandshake() {
40     EXPECT_TRUE(stream_->CryptoConnect());
41     CryptoTestUtils::HandshakeWithFakeServer(connection_, stream_.get());
42   }
43
44   void ConstructHandshakeMessage() {
45     CryptoFramer framer;
46     message_data_.reset(framer.ConstructHandshakeMessage(message_));
47   }
48
49   PacketSavingConnection* connection_;
50   scoped_ptr<TestClientSession> session_;
51   QuicServerId server_id_;
52   scoped_ptr<QuicCryptoClientStream> stream_;
53   CryptoHandshakeMessage message_;
54   scoped_ptr<QuicData> message_data_;
55   QuicCryptoClientConfig crypto_config_;
56 };
57
58 TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
59   EXPECT_FALSE(stream_->encryption_established());
60   EXPECT_FALSE(stream_->handshake_confirmed());
61 }
62
63 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
64   CompleteCryptoHandshake();
65   EXPECT_TRUE(stream_->encryption_established());
66   EXPECT_TRUE(stream_->handshake_confirmed());
67 }
68
69 TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
70   CompleteCryptoHandshake();
71
72   EXPECT_CALL(*connection_, SendConnectionClose(
73       QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
74   message_.set_tag(kCHLO);
75   ConstructHandshakeMessage();
76   stream_->ProcessRawData(message_data_->data(), message_data_->length());
77 }
78
79 TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
80   EXPECT_TRUE(stream_->CryptoConnect());
81
82   message_.set_tag(kCHLO);
83   ConstructHandshakeMessage();
84
85   EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(
86         QUIC_INVALID_CRYPTO_MESSAGE_TYPE, "Expected REJ"));
87   stream_->ProcessRawData(message_data_->data(), message_data_->length());
88 }
89
90 TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
91   CompleteCryptoHandshake();
92
93   const QuicConfig* config = session_->config();
94   EXPECT_EQ(kQBIC, config->CongestionFeedback());
95   EXPECT_EQ(kMaximumIdleTimeoutSecs,
96             config->IdleConnectionStateLifetime().ToSeconds());
97   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
98             config->MaxStreamsPerConnection());
99   EXPECT_EQ(0, config->KeepaliveTimeout().ToSeconds());
100
101   const QuicCryptoNegotiatedParameters& crypto_params(
102       stream_->crypto_negotiated_params());
103   EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
104   EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
105 }
106
107 TEST_F(QuicCryptoClientStreamTest, InvalidHostname) {
108   QuicServerId server_id("invalid", 80, false, PRIVACY_MODE_DISABLED);
109   stream_.reset(new QuicCryptoClientStream(server_id, session_.get(), nullptr,
110                                            &crypto_config_));
111   session_->SetCryptoStream(stream_.get());
112
113   CompleteCryptoHandshake();
114   EXPECT_TRUE(stream_->encryption_established());
115   EXPECT_TRUE(stream_->handshake_confirmed());
116 }
117
118 TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
119   // Seed the config with a cached server config.
120   CompleteCryptoHandshake();
121
122   connection_ = new PacketSavingConnection(true);
123   session_.reset(new TestClientSession(connection_, DefaultQuicConfig()));
124   stream_.reset(new QuicCryptoClientStream(server_id_, session_.get(), nullptr,
125                                            &crypto_config_));
126
127   session_->SetCryptoStream(stream_.get());
128
129   // Advance time 5 years to ensure that we pass the expiry time of the cached
130   // server config.
131   reinterpret_cast<MockClock*>(const_cast<QuicClock*>(connection_->clock()))
132       ->AdvanceTime(QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
133
134   // Check that a client hello was sent and that CryptoConnect doesn't fail
135   // with an error.
136   EXPECT_TRUE(stream_->CryptoConnect());
137   ASSERT_EQ(1u, connection_->packets_.size());
138 }
139
140 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
141   // Test that the crypto client stream can receive server config updates after
142   // the connection has been established.
143   CompleteCryptoHandshake();
144
145   QuicCryptoClientConfig::CachedState* state =
146       crypto_config_.LookupOrCreate(server_id_);
147
148   // Ensure cached STK is different to what we send in the handshake.
149   EXPECT_NE("xstk", state->source_address_token());
150
151   // Initialize using {...} syntax to avoid trailing \0 if converting from
152   // string.
153   unsigned char stk[] = { 'x', 's', 't', 'k' };
154
155   // Minimum SCFG that passes config validation checks.
156   unsigned char scfg[] = {
157     // SCFG
158     0x53, 0x43, 0x46, 0x47,
159     // num entries
160     0x01, 0x00,
161     // padding
162     0x00, 0x00,
163     // EXPY
164     0x45, 0x58, 0x50, 0x59,
165     // EXPY end offset
166     0x08, 0x00, 0x00, 0x00,
167     // Value
168     '1',  '2',  '3',  '4',
169     '5',  '6',  '7',  '8'
170   };
171
172   CryptoHandshakeMessage server_config_update;
173   server_config_update.set_tag(kSCUP);
174   server_config_update.SetValue(kSourceAddressTokenTag, stk);
175   server_config_update.SetValue(kSCFG, scfg);
176
177   scoped_ptr<QuicData> data(
178       CryptoFramer::ConstructHandshakeMessage(server_config_update));
179   stream_->ProcessRawData(data->data(), data->length());
180
181   // Make sure that the STK and SCFG are cached correctly.
182   EXPECT_EQ("xstk", state->source_address_token());
183
184   string cached_scfg = state->server_config();
185   test::CompareCharArraysWithHexError(
186       "scfg", cached_scfg.data(), cached_scfg.length(),
187       QuicUtils::AsChars(scfg), arraysize(scfg));
188 }
189
190 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
191   EXPECT_CALL(*connection_, SendConnectionClose(
192       QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE));
193   CryptoHandshakeMessage server_config_update;
194   server_config_update.set_tag(kSCUP);
195   scoped_ptr<QuicData> data(
196       CryptoFramer::ConstructHandshakeMessage(server_config_update));
197   stream_->ProcessRawData(data->data(), data->length());
198 }
199
200 }  // namespace
201 }  // namespace test
202 }  // namespace net