blob: bcd6a1f536e5a56a53b2027e35d67613661596af [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
6
7#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
bnc463f2352019-10-10 04:49:34 -07009#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
11#include "net/third_party/quiche/src/quic/core/crypto/aes_128_gcm_12_encrypter.h"
12#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
13#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
14#include "net/third_party/quiche/src/quic/core/quic_packets.h"
15#include "net/third_party/quiche/src/quic/core/quic_server_id.h"
16#include "net/third_party/quiche/src/quic/core/quic_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
19#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
20#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
21#include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
22#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
23#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
nharperdf7a77b2019-11-11 13:12:45 -080024#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
bnc4e9283d2019-12-17 07:08:57 -080025#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardle8f7df532020-01-07 13:28:57 -080026#include "net/third_party/quiche/src/common/test_tools/quiche_test_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027
28using testing::_;
29
30namespace quic {
31namespace test {
32namespace {
33
34const char kServerHostname[] = "test.example.com";
35const uint16_t kServerPort = 443;
36
37class QuicCryptoClientStreamTest : public QuicTest {
38 public:
39 QuicCryptoClientStreamTest()
40 : supported_versions_(AllSupportedVersions()),
41 server_id_(kServerHostname, kServerPort, false),
nharperdf7a77b2019-11-11 13:12:45 -080042 crypto_config_(crypto_test_utils::ProofVerifierForTesting(),
43 std::make_unique<test::SimpleSessionCache>()),
44 server_crypto_config_(
45 crypto_test_utils::CryptoServerConfigForTesting()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050046 CreateConnection();
47 }
48
dschinazidffd2982020-03-02 10:25:11 -080049 void CreateSession() {
vasilvv0fc587f2019-09-06 13:33:08 -070050 session_ = std::make_unique<TestQuicSpdyClientSession>(
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 connection_, DefaultQuicConfig(), supported_versions_, server_id_,
52 &crypto_config_);
vasilvvefc6af82019-10-11 12:46:56 -070053 EXPECT_CALL(*session_, GetAlpnsToOffer())
54 .WillRepeatedly(testing::Return(std::vector<std::string>(
55 {AlpnForVersion(connection_->version())})));
QUICHE teama6ef0a62019-03-07 20:34:33 -050056 }
57
dschinazidffd2982020-03-02 10:25:11 -080058 void CreateConnection() {
59 connection_ =
60 new PacketSavingConnection(&client_helper_, &alarm_factory_,
61 Perspective::IS_CLIENT, supported_versions_);
62 // Advance the time, because timers do not like uninitialized times.
63 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
64 CreateSession();
65 }
66
nharperdf7a77b2019-11-11 13:12:45 -080067 void UseTlsHandshake() {
nharperdf7a77b2019-11-11 13:12:45 -080068 supported_versions_.clear();
69 for (ParsedQuicVersion version : AllSupportedVersions()) {
70 if (version.handshake_protocol != PROTOCOL_TLS1_3) {
71 continue;
72 }
73 supported_versions_.push_back(version);
74 }
75 }
76
dschinazidffd2982020-03-02 10:25:11 -080077 void UseQuicCryptoHandshake() {
78 supported_versions_.clear();
79 for (ParsedQuicVersion version : AllSupportedVersions()) {
80 if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
81 continue;
82 }
83 supported_versions_.push_back(version);
84 }
85 }
86
QUICHE teama6ef0a62019-03-07 20:34:33 -050087 void CompleteCryptoHandshake() {
nharper1473c092019-11-11 13:13:19 -080088 int proof_verify_details_calls = 1;
QUICHE teama6ef0a62019-03-07 20:34:33 -050089 if (stream()->handshake_protocol() != PROTOCOL_TLS1_3) {
90 EXPECT_CALL(*session_, OnProofValid(testing::_));
nharper1473c092019-11-11 13:13:19 -080091 proof_verify_details_calls = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 }
93 EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
nharper1473c092019-11-11 13:13:19 -080094 .Times(testing::AtLeast(proof_verify_details_calls));
QUICHE teama6ef0a62019-03-07 20:34:33 -050095 stream()->CryptoConnect();
96 QuicConfig config;
nharperba5f32c2019-05-13 12:21:31 -070097 crypto_test_utils::HandshakeWithFakeServer(
rch83f29bd2019-11-13 11:47:34 -080098 &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
nharperdf7a77b2019-11-11 13:12:45 -080099 connection_, stream(), AlpnForVersion(connection_->version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 }
101
102 QuicCryptoClientStream* stream() {
103 return session_->GetMutableCryptoStream();
104 }
105
106 MockQuicConnectionHelper server_helper_;
107 MockQuicConnectionHelper client_helper_;
108 MockAlarmFactory alarm_factory_;
109 PacketSavingConnection* connection_;
110 ParsedQuicVersionVector supported_versions_;
111 std::unique_ptr<TestQuicSpdyClientSession> session_;
112 QuicServerId server_id_;
113 CryptoHandshakeMessage message_;
114 QuicCryptoClientConfig crypto_config_;
rch83f29bd2019-11-13 11:47:34 -0800115 std::unique_ptr<QuicCryptoServerConfig> server_crypto_config_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116};
117
118TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) {
119 EXPECT_FALSE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800120 EXPECT_FALSE(stream()->one_rtt_keys_available());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121}
122
123TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) {
124 CompleteCryptoHandshake();
125 EXPECT_TRUE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800126 EXPECT_TRUE(stream()->one_rtt_keys_available());
nharper02703962019-11-07 12:23:13 -0800127 EXPECT_FALSE(stream()->IsResumption());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500128}
129
130TEST_F(QuicCryptoClientStreamTest, ConnectedAfterTlsHandshake) {
nharperdf7a77b2019-11-11 13:12:45 -0800131 UseTlsHandshake();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132 CreateConnection();
133 CompleteCryptoHandshake();
134 EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
135 EXPECT_TRUE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800136 EXPECT_TRUE(stream()->one_rtt_keys_available());
nharper02703962019-11-07 12:23:13 -0800137 EXPECT_FALSE(stream()->IsResumption());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138}
139
nharper40bdf532019-10-03 11:16:22 -0700140TEST_F(QuicCryptoClientStreamTest,
141 ProofVerifyDetailsAvailableAfterTlsHandshake) {
nharperdf7a77b2019-11-11 13:12:45 -0800142 UseTlsHandshake();
nharper40bdf532019-10-03 11:16:22 -0700143 CreateConnection();
144
145 EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_));
146 stream()->CryptoConnect();
147 QuicConfig config;
148 crypto_test_utils::HandshakeWithFakeServer(
rch83f29bd2019-11-13 11:47:34 -0800149 &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_,
nharperdf7a77b2019-11-11 13:12:45 -0800150 connection_, stream(), AlpnForVersion(connection_->version()));
nharper40bdf532019-10-03 11:16:22 -0700151 EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
152 EXPECT_TRUE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800153 EXPECT_TRUE(stream()->one_rtt_keys_available());
nharper40bdf532019-10-03 11:16:22 -0700154}
155
nharperdf7a77b2019-11-11 13:12:45 -0800156TEST_F(QuicCryptoClientStreamTest, TlsResumption) {
157 UseTlsHandshake();
158 // Enable resumption on the server:
rch83f29bd2019-11-13 11:47:34 -0800159 SSL_CTX_clear_options(server_crypto_config_->ssl_ctx(), SSL_OP_NO_TICKET);
nharperdf7a77b2019-11-11 13:12:45 -0800160 CreateConnection();
161
162 // Finish establishing the first connection:
163 CompleteCryptoHandshake();
164
165 EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
166 EXPECT_TRUE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800167 EXPECT_TRUE(stream()->one_rtt_keys_available());
nharperdf7a77b2019-11-11 13:12:45 -0800168 EXPECT_FALSE(stream()->IsResumption());
169
170 // Create a second connection
171 CreateConnection();
172 CompleteCryptoHandshake();
173
174 EXPECT_EQ(PROTOCOL_TLS1_3, stream()->handshake_protocol());
175 EXPECT_TRUE(stream()->encryption_established());
fayang685367a2020-01-14 10:40:15 -0800176 EXPECT_TRUE(stream()->one_rtt_keys_available());
nharperdf7a77b2019-11-11 13:12:45 -0800177 EXPECT_TRUE(stream()->IsResumption());
178}
179
QUICHE teama6ef0a62019-03-07 20:34:33 -0500180TEST_F(QuicCryptoClientStreamTest, MessageAfterHandshake) {
dschinazidffd2982020-03-02 10:25:11 -0800181 UseQuicCryptoHandshake();
182 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183 CompleteCryptoHandshake();
184
185 EXPECT_CALL(
186 *connection_,
187 CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE, _, _));
188 message_.set_tag(kCHLO);
189 crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
190 Perspective::IS_CLIENT);
191}
192
193TEST_F(QuicCryptoClientStreamTest, BadMessageType) {
dschinazidffd2982020-03-02 10:25:11 -0800194 UseQuicCryptoHandshake();
195 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500196 stream()->CryptoConnect();
197
198 message_.set_tag(kCHLO);
199
200 EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
201 "Expected REJ", _));
202 crypto_test_utils::SendHandshakeMessageToStream(stream(), message_,
203 Perspective::IS_CLIENT);
204}
205
206TEST_F(QuicCryptoClientStreamTest, NegotiatedParameters) {
dschinazidffd2982020-03-02 10:25:11 -0800207 UseQuicCryptoHandshake();
208 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 CompleteCryptoHandshake();
210
211 const QuicConfig* config = session_->config();
212 EXPECT_EQ(kMaximumIdleTimeoutSecs, config->IdleNetworkTimeout().ToSeconds());
213
214 const QuicCryptoNegotiatedParameters& crypto_params(
215 stream()->crypto_negotiated_params());
216 EXPECT_EQ(crypto_config_.aead[0], crypto_params.aead);
217 EXPECT_EQ(crypto_config_.kexs[0], crypto_params.key_exchange);
218}
219
220TEST_F(QuicCryptoClientStreamTest, ExpiredServerConfig) {
dschinazidffd2982020-03-02 10:25:11 -0800221 UseQuicCryptoHandshake();
222 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 // Seed the config with a cached server config.
224 CompleteCryptoHandshake();
225
226 // Recreate connection with the new config.
227 CreateConnection();
228
229 // Advance time 5 years to ensure that we pass the expiry time of the cached
230 // server config.
231 connection_->AdvanceTime(
232 QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
233
234 EXPECT_CALL(*session_, OnProofValid(testing::_));
235 stream()->CryptoConnect();
236 // Check that a client hello was sent.
237 ASSERT_EQ(1u, connection_->encrypted_packets_.size());
QUICHE team6987b4a2019-03-15 16:23:04 -0700238 EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500239}
240
241TEST_F(QuicCryptoClientStreamTest, ClockSkew) {
242 // Test that if the client's clock is skewed with respect to the server,
243 // the handshake succeeds. In the past, the client would get the server
244 // config, notice that it had already expired and then close the connection.
245
246 // Advance time 5 years to ensure that we pass the expiry time in the server
247 // config, but the TTL is used instead.
248 connection_->AdvanceTime(
249 QuicTime::Delta::FromSeconds(60 * 60 * 24 * 365 * 5));
250
251 // The handshakes completes!
252 CompleteCryptoHandshake();
253}
254
255TEST_F(QuicCryptoClientStreamTest, InvalidCachedServerConfig) {
256 // Seed the config with a cached server config.
257 CompleteCryptoHandshake();
258
259 // Recreate connection with the new config.
260 CreateConnection();
261
262 QuicCryptoClientConfig::CachedState* state =
263 crypto_config_.LookupOrCreate(server_id_);
264
vasilvvc48c8712019-03-11 13:38:16 -0700265 std::vector<std::string> certs = state->certs();
266 std::string cert_sct = state->cert_sct();
267 std::string signature = state->signature();
268 std::string chlo_hash = state->chlo_hash();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500269 state->SetProof(certs, cert_sct, chlo_hash, signature + signature);
270
271 EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
272 .Times(testing::AnyNumber());
273 stream()->CryptoConnect();
274 // Check that a client hello was sent.
275 ASSERT_EQ(1u, connection_->encrypted_packets_.size());
276}
277
278TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdate) {
279 // Test that the crypto client stream can receive server config updates after
280 // the connection has been established.
dschinazidffd2982020-03-02 10:25:11 -0800281 UseQuicCryptoHandshake();
282 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500283 CompleteCryptoHandshake();
284
285 QuicCryptoClientConfig::CachedState* state =
286 crypto_config_.LookupOrCreate(server_id_);
287
288 // Ensure cached STK is different to what we send in the handshake.
289 EXPECT_NE("xstk", state->source_address_token());
290
291 // Initialize using {...} syntax to avoid trailing \0 if converting from
292 // string.
293 unsigned char stk[] = {'x', 's', 't', 'k'};
294
295 // Minimum SCFG that passes config validation checks.
296 unsigned char scfg[] = {// SCFG
297 0x53, 0x43, 0x46, 0x47,
298 // num entries
299 0x01, 0x00,
300 // padding
301 0x00, 0x00,
302 // EXPY
303 0x45, 0x58, 0x50, 0x59,
304 // EXPY end offset
305 0x08, 0x00, 0x00, 0x00,
306 // Value
307 '1', '2', '3', '4', '5', '6', '7', '8'};
308
309 CryptoHandshakeMessage server_config_update;
310 server_config_update.set_tag(kSCUP);
311 server_config_update.SetValue(kSourceAddressTokenTag, stk);
312 server_config_update.SetValue(kSCFG, scfg);
313 const uint64_t expiry_seconds = 60 * 60 * 24 * 2;
314 server_config_update.SetValue(kSTTL, expiry_seconds);
315
316 crypto_test_utils::SendHandshakeMessageToStream(
317 stream(), server_config_update, Perspective::IS_SERVER);
318
319 // Make sure that the STK and SCFG are cached correctly.
320 EXPECT_EQ("xstk", state->source_address_token());
321
vasilvvc48c8712019-03-11 13:38:16 -0700322 const std::string& cached_scfg = state->server_config();
dmcardle8f7df532020-01-07 13:28:57 -0800323 quiche::test::CompareCharArraysWithHexError(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500324 "scfg", cached_scfg.data(), cached_scfg.length(),
bnc4e9283d2019-12-17 07:08:57 -0800325 reinterpret_cast<char*>(scfg), QUICHE_ARRAYSIZE(scfg));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500326
327 QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
328 EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
329}
330
331TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
332 // Test that the crypto client stream can receive and use server config
333 // updates with certificates after the connection has been established.
dschinazidffd2982020-03-02 10:25:11 -0800334 UseQuicCryptoHandshake();
335 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336 CompleteCryptoHandshake();
337
338 // Build a server config update message with certificates
339 QuicCryptoServerConfig crypto_config(
340 QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
nharper6ebe83b2019-06-13 17:43:52 -0700341 crypto_test_utils::ProofSourceForTesting(), KeyExchangeSource::Default());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342 crypto_test_utils::SetupCryptoServerConfigForTest(
nharperba5f32c2019-05-13 12:21:31 -0700343 connection_->clock(), QuicRandom::GetInstance(), &crypto_config);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344 SourceAddressTokens tokens;
345 QuicCompressedCertsCache cache(1);
346 CachedNetworkParameters network_params;
347 CryptoHandshakeMessage server_config_update;
348
349 class Callback : public BuildServerConfigUpdateMessageResultCallback {
350 public:
351 Callback(bool* ok, CryptoHandshakeMessage* message)
352 : ok_(ok), message_(message) {}
353 void Run(bool ok, const CryptoHandshakeMessage& message) override {
354 *ok_ = ok;
355 *message_ = message;
356 }
357
358 private:
359 bool* ok_;
360 CryptoHandshakeMessage* message_;
361 };
362
363 // Note: relies on the callback being invoked synchronously
364 bool ok = false;
365 crypto_config.BuildServerConfigUpdateMessage(
renjietangd1d00852019-09-06 10:43:12 -0700366 session_->transport_version(), stream()->chlo_hash(), tokens,
367 QuicSocketAddress(QuicIpAddress::Loopback6(), 1234),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500368 QuicIpAddress::Loopback6(), connection_->clock(),
369 QuicRandom::GetInstance(), &cache, stream()->crypto_negotiated_params(),
370 &network_params,
371 std::unique_ptr<BuildServerConfigUpdateMessageResultCallback>(
372 new Callback(&ok, &server_config_update)));
373 EXPECT_TRUE(ok);
374
375 EXPECT_CALL(*session_, OnProofValid(testing::_));
376 crypto_test_utils::SendHandshakeMessageToStream(
377 stream(), server_config_update, Perspective::IS_SERVER);
378
379 // Recreate connection with the new config and verify a 0-RTT attempt.
380 CreateConnection();
381
382 EXPECT_CALL(*connection_, OnCanWrite());
383 EXPECT_CALL(*session_, OnProofValid(testing::_));
384 EXPECT_CALL(*session_, OnProofVerifyDetailsAvailable(testing::_))
385 .Times(testing::AnyNumber());
386 stream()->CryptoConnect();
387 EXPECT_TRUE(session_->IsEncryptionEstablished());
388}
389
390TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateBeforeHandshake) {
dschinazidffd2982020-03-02 10:25:11 -0800391 UseQuicCryptoHandshake();
392 CreateConnection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500393 EXPECT_CALL(
394 *connection_,
395 CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE, _, _));
396 CryptoHandshakeMessage server_config_update;
397 server_config_update.set_tag(kSCUP);
398 crypto_test_utils::SendHandshakeMessageToStream(
399 stream(), server_config_update, Perspective::IS_SERVER);
400}
401
QUICHE teama6ef0a62019-03-07 20:34:33 -0500402TEST_F(QuicCryptoClientStreamTest, PreferredVersion) {
403 // This mimics the case where client receives version negotiation packet, such
404 // that, the preferred version is different from the packets' version.
dschinazidffd2982020-03-02 10:25:11 -0800405 UseQuicCryptoHandshake();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500406 connection_ = new PacketSavingConnection(
407 &client_helper_, &alarm_factory_, Perspective::IS_CLIENT,
408 ParsedVersionOfIndex(supported_versions_, 1));
409 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
410
dschinazidffd2982020-03-02 10:25:11 -0800411 CreateSession();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500412 CompleteCryptoHandshake();
413 // 2 CHLOs are sent.
414 ASSERT_EQ(2u, session_->sent_crypto_handshake_messages().size());
415 // Verify preferred version is the highest version that session supports, and
416 // is different from connection's version.
417 QuicVersionLabel client_version_label;
bncf54082a2019-11-27 10:19:47 -0800418 EXPECT_THAT(session_->sent_crypto_handshake_messages()[0].GetVersionLabel(
419 kVER, &client_version_label),
420 IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500421 EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
422 client_version_label);
bncf54082a2019-11-27 10:19:47 -0800423 EXPECT_THAT(session_->sent_crypto_handshake_messages()[1].GetVersionLabel(
424 kVER, &client_version_label),
425 IsQuicNoError());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 EXPECT_EQ(CreateQuicVersionLabel(supported_versions_[0]),
427 client_version_label);
428 EXPECT_NE(CreateQuicVersionLabel(connection_->version()),
429 client_version_label);
430}
431
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432} // namespace
433} // namespace test
434} // namespace quic