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.
5 #include "net/quic/quic_crypto_server_stream.h"
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/quic_test_utils.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
30 class ReliableQuicStream;
39 class QuicCryptoServerStreamTest : public ::testing::Test {
41 QuicCryptoServerStreamTest()
43 addr_(ParseIPLiteralToNumber("192.0.2.33", &ip_) ?
44 ip_ : IPAddressNumber(), 1),
45 connection_(new PacketSavingConnection(guid_, addr_, true)),
46 session_(connection_, DefaultQuicConfig(), true),
47 crypto_config_(QuicCryptoServerConfig::TESTING,
48 QuicRandom::GetInstance()),
49 stream_(crypto_config_, &session_) {
50 config_.SetDefaults();
51 session_.config()->SetDefaults();
52 session_.SetCryptoStream(&stream_);
53 // We advance the clock initially because the default time is zero and the
54 // strike register worries that we've just overflowed a uint32 time.
55 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
56 // TODO(rtenneti): Enable testing of ProofSource.
57 // crypto_config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting());
59 CryptoTestUtils::SetupCryptoServerConfigForTest(
60 connection_->clock(), connection_->random_generator(),
61 session_.config(), &crypto_config_);
64 void ConstructHandshakeMessage() {
66 message_data_.reset(framer.ConstructHandshakeMessage(message_));
69 int CompleteCryptoHandshake() {
70 return CryptoTestUtils::HandshakeWithFakeClient(connection_, &stream_,
78 PacketSavingConnection* connection_;
81 QuicCryptoServerConfig crypto_config_;
82 QuicCryptoServerStream stream_;
83 CryptoHandshakeMessage message_;
84 scoped_ptr<QuicData> message_data_;
85 CryptoTestUtils::FakeClientOptions client_options_;
88 TEST_F(QuicCryptoServerStreamTest, NotInitiallyConected) {
89 EXPECT_FALSE(stream_.encryption_established());
90 EXPECT_FALSE(stream_.handshake_confirmed());
93 TEST_F(QuicCryptoServerStreamTest, ConnectedAfterCHLO) {
94 // CompleteCryptoHandshake returns the number of client hellos sent. This
96 // * One to get a source-address token and certificates.
97 // * One to complete the handshake.
98 EXPECT_EQ(2, CompleteCryptoHandshake());
99 EXPECT_TRUE(stream_.encryption_established());
100 EXPECT_TRUE(stream_.handshake_confirmed());
103 TEST_F(QuicCryptoServerStreamTest, ZeroRTT) {
106 ParseIPLiteralToNumber("127.0.0.1", &ip);
107 IPEndPoint addr(ip, 0);
108 PacketSavingConnection* client_conn =
109 new PacketSavingConnection(guid, addr, false);
110 PacketSavingConnection* server_conn =
111 new PacketSavingConnection(guid, addr, false);
112 client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
113 server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(100000));
115 QuicConfig client_config;
116 client_config.SetDefaults();
117 scoped_ptr<TestSession> client_session(
118 new TestSession(client_conn, client_config, false));
119 QuicCryptoClientConfig client_crypto_config;
120 client_crypto_config.SetDefaults();
122 scoped_ptr<QuicCryptoClientStream> client(new QuicCryptoClientStream(
123 "test.example.com", client_session.get(), &client_crypto_config));
124 client_session->SetCryptoStream(client.get());
126 // Do a first handshake in order to prime the client config with the server's
128 CHECK(client->CryptoConnect());
129 CHECK_EQ(1u, client_conn->packets_.size());
131 scoped_ptr<TestSession> server_session(
132 new TestSession(server_conn, config_, true));
133 scoped_ptr<QuicCryptoServerStream> server(
134 new QuicCryptoServerStream(crypto_config_, server_session.get()));
135 server_session->SetCryptoStream(server.get());
137 CryptoTestUtils::CommunicateHandshakeMessages(
138 client_conn, client.get(), server_conn, server.get());
139 EXPECT_EQ(2, client->num_sent_client_hellos());
141 // Now do another handshake, hopefully in 0-RTT.
142 LOG(INFO) << "Resetting for 0-RTT handshake attempt";
144 client_conn = new PacketSavingConnection(guid, addr, false);
145 server_conn = new PacketSavingConnection(guid, addr, false);
146 // We need to advance time past the strike-server window so that it's
147 // authoritative in this time span.
148 client_conn->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
149 server_conn->AdvanceTime(QuicTime::Delta::FromSeconds(102000));
151 // This causes the client's nonce to be different and thus stops the
152 // strike-register from rejecting the repeated nonce.
153 reinterpret_cast<MockRandom*>(client_conn->random_generator())->ChangeValue();
154 client_session.reset(new TestSession(client_conn, client_config, false));
155 server_session.reset(new TestSession(server_conn, config_, true));
156 client.reset(new QuicCryptoClientStream(
157 "test.example.com", client_session.get(), &client_crypto_config));
158 client_session->SetCryptoStream(client.get());
160 server.reset(new QuicCryptoServerStream(crypto_config_,
161 server_session.get()));
162 server_session->SetCryptoStream(server.get());
164 CHECK(client->CryptoConnect());
166 CryptoTestUtils::CommunicateHandshakeMessages(
167 client_conn, client.get(), server_conn, server.get());
168 EXPECT_EQ(1, client->num_sent_client_hellos());
171 TEST_F(QuicCryptoServerStreamTest, MessageAfterHandshake) {
172 CompleteCryptoHandshake();
173 EXPECT_CALL(*connection_, SendConnectionClose(
174 QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE));
175 message_.set_tag(kCHLO);
176 ConstructHandshakeMessage();
177 stream_.ProcessData(message_data_->data(), message_data_->length());
180 TEST_F(QuicCryptoServerStreamTest, BadMessageType) {
181 message_.set_tag(kSHLO);
182 ConstructHandshakeMessage();
183 EXPECT_CALL(*connection_, SendConnectionClose(
184 QUIC_INVALID_CRYPTO_MESSAGE_TYPE));
185 stream_.ProcessData(message_data_->data(), message_data_->length());
188 TEST_F(QuicCryptoServerStreamTest, WithoutCertificates) {
189 crypto_config_.SetProofSource(NULL);
190 client_options_.dont_verify_certs = true;
192 // Only 2 client hellos need to be sent in the no-certs case: one to get the
193 // source-address token and the second to finish.
194 EXPECT_EQ(2, CompleteCryptoHandshake());
195 EXPECT_TRUE(stream_.encryption_established());
196 EXPECT_TRUE(stream_.handshake_confirmed());
199 TEST_F(QuicCryptoServerStreamTest, ChannelID) {
200 client_options_.channel_id_enabled = true;
201 // TODO(rtenneti): Enable testing of ProofVerifier.
202 // CompleteCryptoHandshake verifies
203 // stream_.crypto_negotiated_params().channel_id is correct.
204 EXPECT_EQ(2, CompleteCryptoHandshake());
205 EXPECT_TRUE(stream_.encryption_established());
206 EXPECT_TRUE(stream_.handshake_confirmed());