Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_crypto_server_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_server_stream.h"
6
7 #include <map>
8 #include <vector>
9
10 #include "base/memory/scoped_ptr.h"
11 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
12 #include "net/quic/crypto/crypto_framer.h"
13 #include "net/quic/crypto/crypto_handshake.h"
14 #include "net/quic/crypto/crypto_protocol.h"
15 #include "net/quic/crypto/crypto_utils.h"
16 #include "net/quic/crypto/quic_crypto_server_config.h"
17 #include "net/quic/crypto/quic_decrypter.h"
18 #include "net/quic/crypto/quic_encrypter.h"
19 #include "net/quic/crypto/quic_random.h"
20 #include "net/quic/quic_crypto_client_stream.h"
21 #include "net/quic/quic_protocol.h"
22 #include "net/quic/quic_session.h"
23 #include "net/quic/test_tools/crypto_test_utils.h"
24 #include "net/quic/test_tools/delayed_verify_strike_register_client.h"
25 #include "net/quic/test_tools/quic_test_utils.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace net {
30 class QuicConnection;
31 class ReliableQuicStream;
32 }  // namespace net
33
34 using std::pair;
35 using testing::_;
36
37 namespace net {
38 namespace test {
39
40 class QuicCryptoServerConfigPeer {
41  public:
42   static string GetPrimaryOrbit(const QuicCryptoServerConfig& config) {
43     base::AutoLock lock(config.configs_lock_);
44     CHECK(config.primary_config_ != NULL);
45     return string(reinterpret_cast<const char*>(config.primary_config_->orbit),
46                   kOrbitSize);
47   }
48 };
49
50 namespace {
51
52 const char kServerHostname[] = "test.example.com";
53 const uint16 kServerPort = 80;
54
55 class QuicCryptoServerStreamTest : public ::testing::TestWithParam<bool> {
56  public:
57   QuicCryptoServerStreamTest()
58       : connection_(new PacketSavingConnection(true)),
59         session_(connection_, DefaultQuicConfig()),
60         crypto_config_(QuicCryptoServerConfig::TESTING,
61                        QuicRandom::GetInstance()),
62         stream_(crypto_config_, &session_),
63         strike_register_client_(NULL) {
64     config_.SetDefaults();
65     session_.config()->SetDefaults();
66     session_.SetCryptoStream(&stream_);
67     // We advance the clock initially because the default time is zero and the
68     // strike register worries that we've just overflowed a uint32 time.
69     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
70     // TODO(rtenneti): Enable testing of ProofSource.
71     // crypto_config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting());
72     crypto_config_.set_strike_register_no_startup_period();
73
74     CryptoTestUtils::SetupCryptoServerConfigForTest(
75         connection_->clock(), connection_->random_generator(),
76         session_.config(), &crypto_config_);
77
78     if (AsyncStrikeRegisterVerification()) {
79       string orbit =
80           QuicCryptoServerConfigPeer::GetPrimaryOrbit(crypto_config_);
81       strike_register_client_ = new DelayedVerifyStrikeRegisterClient(
82           10000,  // strike_register_max_entries
83           static_cast<uint32>(connection_->clock()->WallNow().ToUNIXSeconds()),
84           60,  // strike_register_window_secs
85           reinterpret_cast<const uint8 *>(orbit.data()),
86           StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
87       strike_register_client_->StartDelayingVerification();
88       crypto_config_.SetStrikeRegisterClient(strike_register_client_);
89     }
90   }
91
92   bool AsyncStrikeRegisterVerification() {
93     return GetParam();
94   }
95
96   void ConstructHandshakeMessage() {
97     CryptoFramer framer;
98     message_data_.reset(framer.ConstructHandshakeMessage(message_));
99   }
100
101   int CompleteCryptoHandshake() {
102     return CryptoTestUtils::HandshakeWithFakeClient(connection_, &stream_,
103                                                     client_options_);
104   }
105
106  protected:
107   PacketSavingConnection* connection_;
108   TestClientSession session_;
109   QuicConfig config_;
110   QuicCryptoServerConfig crypto_config_;
111   QuicCryptoServerStream stream_;
112   CryptoHandshakeMessage message_;
113   scoped_ptr<QuicData> message_data_;
114   CryptoTestUtils::FakeClientOptions client_options_;
115   DelayedVerifyStrikeRegisterClient* strike_register_client_;
116 };
117
118 INSTANTIATE_TEST_CASE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
119
120 TEST_P(QuicCryptoServerStreamTest, NotInitiallyConected) {
121   EXPECT_FALSE(stream_.encryption_established());
122   EXPECT_FALSE(stream_.handshake_confirmed());
123 }
124
125 TEST_P(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
126   // CompleteCryptoHandshake returns the number of client hellos sent. This
127   // test should send:
128   //   * One to get a source-address token and certificates.
129   //   * One to complete the handshake.
130   EXPECT_EQ(2, CompleteCryptoHandshake());
131   EXPECT_TRUE(stream_.encryption_established());
132   EXPECT_TRUE(stream_.handshake_confirmed());
133 }
134
135 TEST_P(QuicCryptoServerStreamTest, ZeroRTT) {
136   PacketSavingConnection* client_conn = new PacketSavingConnection(false);
137   PacketSavingConnection* server_conn = new PacketSavingConnection(false);
138   client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
139   server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
140
141   QuicConfig client_config;
142   client_config.SetDefaults();
143   scoped_ptr<TestClientSession> client_session(
144       new TestClientSession(client_conn, client_config));
145   QuicCryptoClientConfig client_crypto_config;
146   client_crypto_config.SetDefaults();
147
148   QuicServerId server_id(kServerHostname, kServerPort, false,
149                          PRIVACY_MODE_DISABLED);
150   scoped_ptr<QuicCryptoClientStream> client(new QuicCryptoClientStream(
151       server_id, client_session.get(), NULL, &client_crypto_config));
152   client_session->SetCryptoStream(client.get());
153
154   // Do a first handshake in order to prime the client config with the server's
155   // information.
156   CHECK(client->CryptoConnect());
157   CHECK_EQ(1u, client_conn->packets_.size());
158
159   scoped_ptr<TestSession> server_session(new TestSession(server_conn, config_));
160   scoped_ptr<QuicCryptoServerStream> server(
161       new QuicCryptoServerStream(crypto_config_, server_session.get()));
162   server_session->SetCryptoStream(server.get());
163
164   CryptoTestUtils::CommunicateHandshakeMessages(
165       client_conn, client.get(), server_conn, server.get());
166   EXPECT_EQ(2, client->num_sent_client_hellos());
167
168   // Now do another handshake, hopefully in 0-RTT.
169   LOG(INFO) << "Resetting for 0-RTT handshake attempt";
170
171   client_conn = new PacketSavingConnection(false);
172   server_conn = new PacketSavingConnection(false);
173   // We need to advance time past the strike-server window so that it's
174   // authoritative in this time span.
175   client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
176   server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
177
178   // This causes the client's nonce to be different and thus stops the
179   // strike-register from rejecting the repeated nonce.
180   reinterpret_cast<MockRandom*>(client_conn->random_generator())->ChangeValue();
181   client_session.reset(new TestClientSession(client_conn, client_config));
182   server_session.reset(new TestSession(server_conn, config_));
183   client.reset(new QuicCryptoClientStream(
184       server_id, client_session.get(), NULL, &client_crypto_config));
185   client_session->SetCryptoStream(client.get());
186
187   server.reset(new QuicCryptoServerStream(crypto_config_,
188                                           server_session.get()));
189   server_session->SetCryptoStream(server.get());
190
191   CHECK(client->CryptoConnect());
192
193   if (AsyncStrikeRegisterVerification()) {
194     EXPECT_FALSE(client->handshake_confirmed());
195     EXPECT_FALSE(server->handshake_confirmed());
196
197     // Advance the handshake.  Expect that the server will be stuck
198     // waiting for client nonce verification to complete.
199     pair<size_t, size_t> messages_moved = CryptoTestUtils::AdvanceHandshake(
200         client_conn, client.get(), 0, server_conn, server.get(), 0);
201     EXPECT_EQ(1u, messages_moved.first);
202     EXPECT_EQ(0u, messages_moved.second);
203     EXPECT_EQ(1, strike_register_client_->PendingVerifications());
204     EXPECT_FALSE(client->handshake_confirmed());
205     EXPECT_FALSE(server->handshake_confirmed());
206
207     // The server handshake completes once the nonce verification completes.
208     strike_register_client_->RunPendingVerifications();
209     EXPECT_FALSE(client->handshake_confirmed());
210     EXPECT_TRUE(server->handshake_confirmed());
211
212     messages_moved = CryptoTestUtils::AdvanceHandshake(
213         client_conn, client.get(), messages_moved.first,
214         server_conn, server.get(), messages_moved.second);
215     EXPECT_EQ(1u, messages_moved.first);
216     EXPECT_EQ(1u, messages_moved.second);
217     EXPECT_TRUE(client->handshake_confirmed());
218     EXPECT_TRUE(server->handshake_confirmed());
219   } else {
220     CryptoTestUtils::CommunicateHandshakeMessages(
221         client_conn, client.get(), server_conn, server.get());
222   }
223
224   EXPECT_EQ(1, client->num_sent_client_hellos());
225 }
226
227 TEST_P(QuicCryptoServerStreamTest, MessageAfterHandshake) {
228   CompleteCryptoHandshake();
229   EXPECT_CALL(*connection_, SendConnectionClose(
230       QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
231   message_.set_tag(kCHLO);
232   ConstructHandshakeMessage();
233   stream_.ProcessRawData(message_data_->data(), message_data_->length());
234 }
235
236 TEST_P(QuicCryptoServerStreamTest, BadMessageType) {
237   message_.set_tag(kSHLO);
238   ConstructHandshakeMessage();
239   EXPECT_CALL(*connection_, SendConnectionClose(
240       QUIC_INVALID_CRYPTO_MESSAGE_TYPE));
241   stream_.ProcessRawData(message_data_->data(), message_data_->length());
242 }
243
244 TEST_P(QuicCryptoServerStreamTest, WithoutCertificates) {
245   crypto_config_.SetProofSource(NULL);
246   client_options_.dont_verify_certs = true;
247
248   // Only 2 client hellos need to be sent in the no-certs case: one to get the
249   // source-address token and the second to finish.
250   EXPECT_EQ(2, CompleteCryptoHandshake());
251   EXPECT_TRUE(stream_.encryption_established());
252   EXPECT_TRUE(stream_.handshake_confirmed());
253 }
254
255 TEST_P(QuicCryptoServerStreamTest, ChannelID) {
256   client_options_.channel_id_enabled = true;
257   // CompleteCryptoHandshake verifies
258   // stream_.crypto_negotiated_params().channel_id is correct.
259   EXPECT_EQ(2, CompleteCryptoHandshake());
260   EXPECT_TRUE(stream_.encryption_established());
261   EXPECT_TRUE(stream_.handshake_confirmed());
262 }
263
264 }  // namespace
265 }  // namespace test
266 }  // namespace net