blob: 96691fa2af8db70d49e6b92947516b27f06d1610 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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
vasilvv872e7a32019-03-12 16:42:44 -07005#include <string>
bnc463f2352019-10-10 04:49:34 -07006#include <utility>
vasilvv872e7a32019-03-12 16:42:44 -07007
nharper6ebe83b2019-06-13 17:43:52 -07008#include "net/third_party/quiche/src/quic/core/crypto/tls_client_connection.h"
9#include "net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "net/third_party/quiche/src/quic/core/quic_utils.h"
11#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
12#include "net/third_party/quiche/src/quic/core/tls_server_handshaker.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
vasilvv4724c9c2019-08-29 11:52:11 -070014#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
16#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
17#include "net/third_party/quiche/src/quic/test_tools/fake_proof_source.h"
18#include "net/third_party/quiche/src/quic/test_tools/mock_quic_session_visitor.h"
19#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
20
21namespace quic {
22namespace test {
23namespace {
24
25using ::testing::_;
vasilvvad7424f2019-08-30 00:27:14 -070026using ::testing::ElementsAreArray;
vasilvv4724c9c2019-08-29 11:52:11 -070027using ::testing::Return;
QUICHE teama6ef0a62019-03-07 20:34:33 -050028
29class FakeProofVerifier : public ProofVerifier {
30 public:
31 FakeProofVerifier()
32 : verifier_(crypto_test_utils::ProofVerifierForTesting()) {}
33
34 QuicAsyncStatus VerifyProof(
vasilvvc48c8712019-03-11 13:38:16 -070035 const std::string& hostname,
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 const uint16_t port,
vasilvvc48c8712019-03-11 13:38:16 -070037 const std::string& server_config,
QUICHE teama6ef0a62019-03-07 20:34:33 -050038 QuicTransportVersion quic_version,
39 QuicStringPiece chlo_hash,
vasilvvc48c8712019-03-11 13:38:16 -070040 const std::vector<std::string>& certs,
41 const std::string& cert_sct,
42 const std::string& signature,
QUICHE teama6ef0a62019-03-07 20:34:33 -050043 const ProofVerifyContext* context,
vasilvvc48c8712019-03-11 13:38:16 -070044 std::string* error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050045 std::unique_ptr<ProofVerifyDetails>* details,
46 std::unique_ptr<ProofVerifierCallback> callback) override {
47 return verifier_->VerifyProof(
48 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
49 signature, context, error_details, details, std::move(callback));
50 }
51
52 QuicAsyncStatus VerifyCertChain(
vasilvvc48c8712019-03-11 13:38:16 -070053 const std::string& hostname,
54 const std::vector<std::string>& certs,
QUICHE team38c190b2019-05-08 09:12:01 -070055 const std::string& ocsp_response,
56 const std::string& cert_sct,
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 const ProofVerifyContext* context,
vasilvvc48c8712019-03-11 13:38:16 -070058 std::string* error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 std::unique_ptr<ProofVerifyDetails>* details,
60 std::unique_ptr<ProofVerifierCallback> callback) override {
61 if (!active_) {
QUICHE team38c190b2019-05-08 09:12:01 -070062 return verifier_->VerifyCertChain(hostname, certs, ocsp_response,
63 cert_sct, context, error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050064 details, std::move(callback));
65 }
vasilvv0fc587f2019-09-06 13:33:08 -070066 pending_ops_.push_back(std::make_unique<VerifyChainPendingOp>(
QUICHE team38c190b2019-05-08 09:12:01 -070067 hostname, certs, ocsp_response, cert_sct, context, error_details,
68 details, std::move(callback), verifier_.get()));
QUICHE teama6ef0a62019-03-07 20:34:33 -050069 return QUIC_PENDING;
70 }
71
72 std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override {
73 return nullptr;
74 }
75
76 void Activate() { active_ = true; }
77
78 size_t NumPendingCallbacks() const { return pending_ops_.size(); }
79
80 void InvokePendingCallback(size_t n) {
81 CHECK(NumPendingCallbacks() > n);
82 pending_ops_[n]->Run();
83 auto it = pending_ops_.begin() + n;
84 pending_ops_.erase(it);
85 }
86
87 private:
88 // Implementation of ProofVerifierCallback that fails if the callback is ever
89 // run.
90 class FailingProofVerifierCallback : public ProofVerifierCallback {
91 public:
dschinazi17d42422019-06-18 16:35:07 -070092 void Run(bool /*ok*/,
93 const std::string& /*error_details*/,
94 std::unique_ptr<ProofVerifyDetails>* /*details*/) override {
QUICHE teama6ef0a62019-03-07 20:34:33 -050095 FAIL();
96 }
97 };
98
99 class VerifyChainPendingOp {
100 public:
vasilvvc48c8712019-03-11 13:38:16 -0700101 VerifyChainPendingOp(const std::string& hostname,
102 const std::vector<std::string>& certs,
QUICHE team38c190b2019-05-08 09:12:01 -0700103 const std::string& ocsp_response,
104 const std::string& cert_sct,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 const ProofVerifyContext* context,
vasilvvc48c8712019-03-11 13:38:16 -0700106 std::string* error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 std::unique_ptr<ProofVerifyDetails>* details,
108 std::unique_ptr<ProofVerifierCallback> callback,
109 ProofVerifier* delegate)
110 : hostname_(hostname),
111 certs_(certs),
QUICHE team38c190b2019-05-08 09:12:01 -0700112 ocsp_response_(ocsp_response),
113 cert_sct_(cert_sct),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114 context_(context),
115 error_details_(error_details),
116 details_(details),
117 callback_(std::move(callback)),
118 delegate_(delegate) {}
119
120 void Run() {
121 // FakeProofVerifier depends on crypto_test_utils::ProofVerifierForTesting
122 // running synchronously. It passes a FailingProofVerifierCallback and
123 // runs the original callback after asserting that the verification ran
124 // synchronously.
125 QuicAsyncStatus status = delegate_->VerifyCertChain(
QUICHE team38c190b2019-05-08 09:12:01 -0700126 hostname_, certs_, ocsp_response_, cert_sct_, context_,
127 error_details_, details_,
vasilvv0fc587f2019-09-06 13:33:08 -0700128 std::make_unique<FailingProofVerifierCallback>());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129 ASSERT_NE(status, QUIC_PENDING);
130 callback_->Run(status == QUIC_SUCCESS, *error_details_, details_);
131 }
132
133 private:
vasilvvc48c8712019-03-11 13:38:16 -0700134 std::string hostname_;
135 std::vector<std::string> certs_;
QUICHE team38c190b2019-05-08 09:12:01 -0700136 std::string ocsp_response_;
137 std::string cert_sct_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138 const ProofVerifyContext* context_;
vasilvvc48c8712019-03-11 13:38:16 -0700139 std::string* error_details_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500140 std::unique_ptr<ProofVerifyDetails>* details_;
141 std::unique_ptr<ProofVerifierCallback> callback_;
142 ProofVerifier* delegate_;
143 };
144
145 std::unique_ptr<ProofVerifier> verifier_;
146 bool active_ = false;
147 std::vector<std::unique_ptr<VerifyChainPendingOp>> pending_ops_;
148};
149
150class TestQuicCryptoStream : public QuicCryptoStream {
151 public:
152 explicit TestQuicCryptoStream(QuicSession* session)
153 : QuicCryptoStream(session) {}
154
155 ~TestQuicCryptoStream() override = default;
156
157 virtual TlsHandshaker* handshaker() const = 0;
158
159 bool encryption_established() const override {
160 return handshaker()->encryption_established();
161 }
162
163 bool handshake_confirmed() const override {
164 return handshaker()->handshake_confirmed();
165 }
166
167 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
168 const override {
169 return handshaker()->crypto_negotiated_params();
170 }
171
172 CryptoMessageParser* crypto_message_parser() override {
173 return handshaker()->crypto_message_parser();
174 }
175
176 void WriteCryptoData(EncryptionLevel level, QuicStringPiece data) override {
vasilvvc48c8712019-03-11 13:38:16 -0700177 pending_writes_.push_back(std::make_pair(std::string(data), level));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178 }
179
vasilvvc48c8712019-03-11 13:38:16 -0700180 const std::vector<std::pair<std::string, EncryptionLevel>>& pending_writes() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 return pending_writes_;
182 }
183
184 // Sends the pending frames to |stream| and clears the array of pending
185 // writes.
186 void SendCryptoMessagesToPeer(QuicCryptoStream* stream) {
187 QUIC_LOG(INFO) << "Sending " << pending_writes_.size() << " frames";
188 // This is a minimal re-implementation of QuicCryptoStream::OnDataAvailable.
189 // It doesn't work to call QuicStream::OnStreamFrame because
190 // QuicCryptoStream::OnDataAvailable currently (as an implementation detail)
191 // relies on the QuicConnection to know the EncryptionLevel to pass into
192 // CryptoMessageParser::ProcessInput. Since the crypto messages in this test
193 // never reach the framer or connection and never get encrypted/decrypted,
194 // QuicCryptoStream::OnDataAvailable isn't able to call ProcessInput with
195 // the correct EncryptionLevel. Instead, that can be short-circuited by
196 // directly calling ProcessInput here.
197 for (size_t i = 0; i < pending_writes_.size(); ++i) {
198 if (!stream->crypto_message_parser()->ProcessInput(
199 pending_writes_[i].first, pending_writes_[i].second)) {
200 CloseConnectionWithDetails(
201 stream->crypto_message_parser()->error(),
202 stream->crypto_message_parser()->error_detail());
203 break;
204 }
205 }
206 pending_writes_.clear();
207 }
208
209 private:
vasilvvc48c8712019-03-11 13:38:16 -0700210 std::vector<std::pair<std::string, EncryptionLevel>> pending_writes_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211};
212
nharper40bdf532019-10-03 11:16:22 -0700213class MockProofHandler : public QuicCryptoClientStream::ProofHandler {
214 public:
215 MockProofHandler() = default;
216 ~MockProofHandler() override {}
217
218 MOCK_METHOD1(OnProofValid, void(const QuicCryptoClientConfig::CachedState&));
219 MOCK_METHOD1(OnProofVerifyDetailsAvailable, void(const ProofVerifyDetails&));
220};
221
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222class TestQuicCryptoClientStream : public TestQuicCryptoStream {
223 public:
224 explicit TestQuicCryptoClientStream(QuicSession* session)
225 : TestQuicCryptoStream(session),
226 proof_verifier_(new FakeProofVerifier),
nharper6ebe83b2019-06-13 17:43:52 -0700227 ssl_ctx_(TlsClientConnection::CreateSslCtx()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228 handshaker_(new TlsClientHandshaker(
229 this,
230 session,
231 QuicServerId("test.example.com", 443, false),
232 proof_verifier_.get(),
233 ssl_ctx_.get(),
234 crypto_test_utils::ProofVerifyContextForTesting(),
nharper40bdf532019-10-03 11:16:22 -0700235 &proof_handler_,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 "quic-tester")) {}
237
238 ~TestQuicCryptoClientStream() override = default;
239
240 TlsHandshaker* handshaker() const override { return handshaker_.get(); }
vasilvv4724c9c2019-08-29 11:52:11 -0700241 TlsClientHandshaker* client_handshaker() const { return handshaker_.get(); }
nharper40bdf532019-10-03 11:16:22 -0700242 const MockProofHandler& proof_handler() { return proof_handler_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500243
244 bool CryptoConnect() { return handshaker_->CryptoConnect(); }
245
246 FakeProofVerifier* GetFakeProofVerifier() const {
247 return proof_verifier_.get();
248 }
249
250 private:
251 std::unique_ptr<FakeProofVerifier> proof_verifier_;
nharper40bdf532019-10-03 11:16:22 -0700252 MockProofHandler proof_handler_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 bssl::UniquePtr<SSL_CTX> ssl_ctx_;
254 std::unique_ptr<TlsClientHandshaker> handshaker_;
255};
256
257class TestQuicCryptoServerStream : public TestQuicCryptoStream {
258 public:
259 TestQuicCryptoServerStream(QuicSession* session,
260 FakeProofSource* proof_source)
261 : TestQuicCryptoStream(session),
262 proof_source_(proof_source),
nharper6ebe83b2019-06-13 17:43:52 -0700263 ssl_ctx_(TlsServerConnection::CreateSslCtx()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 handshaker_(new TlsServerHandshaker(this,
265 session,
266 ssl_ctx_.get(),
267 proof_source_)) {}
268
269 ~TestQuicCryptoServerStream() override = default;
270
271 void CancelOutstandingCallbacks() {
272 handshaker_->CancelOutstandingCallbacks();
273 }
274
275 TlsHandshaker* handshaker() const override { return handshaker_.get(); }
276
277 FakeProofSource* GetFakeProofSource() const { return proof_source_; }
278
279 private:
280 FakeProofSource* proof_source_;
281 bssl::UniquePtr<SSL_CTX> ssl_ctx_;
282 std::unique_ptr<TlsServerHandshaker> handshaker_;
283};
284
285void ExchangeHandshakeMessages(TestQuicCryptoStream* client,
286 TestQuicCryptoStream* server) {
287 while (!client->pending_writes().empty() ||
288 !server->pending_writes().empty()) {
289 client->SendCryptoMessagesToPeer(server);
290 server->SendCryptoMessagesToPeer(client);
291 }
292}
293
294class TlsHandshakerTest : public QuicTest {
295 public:
296 TlsHandshakerTest()
nharper107ba5f2019-07-02 21:33:39 -0700297 : client_conn_(new MockQuicConnection(
298 &conn_helper_,
299 &alarm_factory_,
300 Perspective::IS_CLIENT,
301 {ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)})),
302 server_conn_(new MockQuicConnection(
303 &conn_helper_,
304 &alarm_factory_,
305 Perspective::IS_SERVER,
306 {ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)})),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 client_session_(client_conn_, /*create_mock_crypto_stream=*/false),
308 server_session_(server_conn_, /*create_mock_crypto_stream=*/false) {
rch16df2a52019-09-10 10:50:09 -0700309 SetQuicReloadableFlag(quic_supports_tls_handshake, true);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310 client_stream_ = new TestQuicCryptoClientStream(&client_session_);
311 client_session_.SetCryptoStream(client_stream_);
312 server_stream_ =
313 new TestQuicCryptoServerStream(&server_session_, &proof_source_);
314 server_session_.SetCryptoStream(server_stream_);
315 client_session_.Initialize();
316 server_session_.Initialize();
317 EXPECT_FALSE(client_stream_->encryption_established());
318 EXPECT_FALSE(client_stream_->handshake_confirmed());
319 EXPECT_FALSE(server_stream_->encryption_established());
320 EXPECT_FALSE(server_stream_->handshake_confirmed());
vasilvvad7424f2019-08-30 00:27:14 -0700321 const std::string default_alpn =
322 AlpnForVersion(client_session_.connection()->version());
vasilvv4724c9c2019-08-29 11:52:11 -0700323 ON_CALL(client_session_, GetAlpnsToOffer())
vasilvvad7424f2019-08-30 00:27:14 -0700324 .WillByDefault(Return(std::vector<std::string>({default_alpn})));
325 ON_CALL(server_session_, SelectAlpn(_))
326 .WillByDefault(
327 [default_alpn](const std::vector<QuicStringPiece>& alpns) {
328 return std::find(alpns.begin(), alpns.end(), default_alpn);
329 });
QUICHE teama6ef0a62019-03-07 20:34:33 -0500330 }
331
nharper8f759922019-10-09 11:08:36 -0700332 void ExpectHandshakeSuccessful() {
333 EXPECT_TRUE(client_stream_->handshake_confirmed());
334 EXPECT_TRUE(client_stream_->encryption_established());
335 EXPECT_TRUE(server_stream_->handshake_confirmed());
336 EXPECT_TRUE(server_stream_->encryption_established());
337 EXPECT_TRUE(client_conn_->IsHandshakeConfirmed());
338 EXPECT_TRUE(server_conn_->IsHandshakeConfirmed());
339
340 const auto& client_crypto_params =
341 client_stream_->crypto_negotiated_params();
342 const auto& server_crypto_params =
343 server_stream_->crypto_negotiated_params();
344 // The TLS params should be filled in on the client.
345 EXPECT_NE(0, client_crypto_params.cipher_suite);
346 EXPECT_NE(0, client_crypto_params.key_exchange_group);
347 EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
348
349 // The cipher suite and key exchange group should match on the client and
350 // server.
351 EXPECT_EQ(client_crypto_params.cipher_suite,
352 server_crypto_params.cipher_suite);
353 EXPECT_EQ(client_crypto_params.key_exchange_group,
354 server_crypto_params.key_exchange_group);
355 // We don't support client certs on the server (yet), so the server
356 // shouldn't have a peer signature algorithm to report.
357 EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
358 }
359
QUICHE teama6ef0a62019-03-07 20:34:33 -0500360 MockQuicConnectionHelper conn_helper_;
361 MockAlarmFactory alarm_factory_;
362 MockQuicConnection* client_conn_;
363 MockQuicConnection* server_conn_;
364 MockQuicSession client_session_;
365 MockQuicSession server_session_;
366
367 FakeProofSource proof_source_;
368 TestQuicCryptoClientStream* client_stream_;
369 TestQuicCryptoServerStream* server_stream_;
370};
371
372TEST_F(TlsHandshakerTest, CryptoHandshake) {
fayangbd793922019-08-26 14:19:24 -0700373 EXPECT_FALSE(client_conn_->IsHandshakeConfirmed());
374 EXPECT_FALSE(server_conn_->IsHandshakeConfirmed());
375
QUICHE teama6ef0a62019-03-07 20:34:33 -0500376 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
377 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
nharper8a72e4f2019-08-13 19:17:08 -0700378 EXPECT_CALL(client_session_,
renjietangea71d6f2019-08-19 12:22:28 -0700379 OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_ESTABLISHED));
nharper8a72e4f2019-08-13 19:17:08 -0700380 EXPECT_CALL(client_session_,
381 OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
382 EXPECT_CALL(server_session_,
383 OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
nharper40bdf532019-10-03 11:16:22 -0700384 EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385 client_stream_->CryptoConnect();
386 ExchangeHandshakeMessages(client_stream_, server_stream_);
387
nharper8f759922019-10-09 11:08:36 -0700388 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500389}
390
391TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
392 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
393 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
394 // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
395 // asynchronously.
396 FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
397 proof_source->Activate();
398
399 // Start handshake.
400 client_stream_->CryptoConnect();
401 ExchangeHandshakeMessages(client_stream_, server_stream_);
402
403 ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
404 proof_source->InvokePendingCallback(0);
405
406 ExchangeHandshakeMessages(client_stream_, server_stream_);
407
nharper8f759922019-10-09 11:08:36 -0700408 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409}
410
411TEST_F(TlsHandshakerTest, CancelPendingProofSource) {
412 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
413 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
414 // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
415 // asynchronously.
416 FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
417 proof_source->Activate();
418
419 // Start handshake.
420 client_stream_->CryptoConnect();
421 ExchangeHandshakeMessages(client_stream_, server_stream_);
422
423 ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
424 server_stream_ = nullptr;
425
426 proof_source->InvokePendingCallback(0);
427}
428
429TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofVerifier) {
430 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
431 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
432 // Enable FakeProofVerifier to capture call to VerifyCertChain and run it
433 // asynchronously.
434 FakeProofVerifier* proof_verifier = client_stream_->GetFakeProofVerifier();
435 proof_verifier->Activate();
436
nharper40bdf532019-10-03 11:16:22 -0700437 EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
438
QUICHE teama6ef0a62019-03-07 20:34:33 -0500439 // Start handshake.
440 client_stream_->CryptoConnect();
441 ExchangeHandshakeMessages(client_stream_, server_stream_);
442
443 ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
444 proof_verifier->InvokePendingCallback(0);
445
446 ExchangeHandshakeMessages(client_stream_, server_stream_);
447
nharper8f759922019-10-09 11:08:36 -0700448 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449}
450
451TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsError) {
452 // Have client send ClientHello.
453 client_stream_->CryptoConnect();
454 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
455
456 // Send a zero-length ServerHello from server to client.
457 char bogus_handshake_message[] = {
458 // Handshake struct (RFC 8446 appendix B.3)
459 2, // HandshakeType server_hello
460 0, 0, 0, // uint24 length
461 };
462 server_stream_->WriteCryptoData(
QUICHE team6987b4a2019-03-15 16:23:04 -0700463 ENCRYPTION_INITIAL,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500464 QuicStringPiece(bogus_handshake_message,
465 QUIC_ARRAYSIZE(bogus_handshake_message)));
466 server_stream_->SendCryptoMessagesToPeer(client_stream_);
467
468 EXPECT_FALSE(client_stream_->handshake_confirmed());
469}
470
471TEST_F(TlsHandshakerTest, ServerConnectionClosedOnTlsError) {
472 EXPECT_CALL(*server_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
473
474 // Send a zero-length ClientHello from client to server.
475 char bogus_handshake_message[] = {
476 // Handshake struct (RFC 8446 appendix B.3)
477 1, // HandshakeType client_hello
478 0, 0, 0, // uint24 length
479 };
480 client_stream_->WriteCryptoData(
QUICHE team6987b4a2019-03-15 16:23:04 -0700481 ENCRYPTION_INITIAL,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500482 QuicStringPiece(bogus_handshake_message,
483 QUIC_ARRAYSIZE(bogus_handshake_message)));
484 client_stream_->SendCryptoMessagesToPeer(server_stream_);
485
486 EXPECT_FALSE(server_stream_->handshake_confirmed());
487}
488
dschinazi91453642019-08-01 11:12:15 -0700489TEST_F(TlsHandshakerTest, ClientNotSendingALPN) {
vasilvv4724c9c2019-08-29 11:52:11 -0700490 client_stream_->client_handshaker()->AllowEmptyAlpnForTests();
491 EXPECT_CALL(client_session_, GetAlpnsToOffer())
492 .WillOnce(Return(std::vector<std::string>()));
dschinazi91453642019-08-01 11:12:15 -0700493 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
494 "Server did not select ALPN", _));
495 EXPECT_CALL(*server_conn_,
496 CloseConnection(QUIC_HANDSHAKE_FAILED,
497 "Server did not receive a known ALPN", _));
498 client_stream_->CryptoConnect();
499 ExchangeHandshakeMessages(client_stream_, server_stream_);
500
501 EXPECT_FALSE(client_stream_->handshake_confirmed());
502 EXPECT_FALSE(client_stream_->encryption_established());
503 EXPECT_FALSE(server_stream_->handshake_confirmed());
504 EXPECT_FALSE(server_stream_->encryption_established());
dschinazi91453642019-08-01 11:12:15 -0700505}
506
507TEST_F(TlsHandshakerTest, ClientSendingBadALPN) {
dschinazi423adc72019-10-23 09:58:55 -0700508 const std::string kTestBadClientAlpn = "bad-client-alpn";
vasilvv4724c9c2019-08-29 11:52:11 -0700509 EXPECT_CALL(client_session_, GetAlpnsToOffer())
510 .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
dschinazi91453642019-08-01 11:12:15 -0700511 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
512 "Server did not select ALPN", _));
513 EXPECT_CALL(*server_conn_,
514 CloseConnection(QUIC_HANDSHAKE_FAILED,
515 "Server did not receive a known ALPN", _));
516 client_stream_->CryptoConnect();
517 ExchangeHandshakeMessages(client_stream_, server_stream_);
518
519 EXPECT_FALSE(client_stream_->handshake_confirmed());
520 EXPECT_FALSE(client_stream_->encryption_established());
521 EXPECT_FALSE(server_stream_->handshake_confirmed());
522 EXPECT_FALSE(server_stream_->encryption_established());
vasilvv4724c9c2019-08-29 11:52:11 -0700523}
524
525TEST_F(TlsHandshakerTest, ClientSendingTooManyALPNs) {
526 std::string long_alpn(250, 'A');
527 EXPECT_CALL(client_session_, GetAlpnsToOffer())
528 .WillOnce(Return(std::vector<std::string>({
529 long_alpn + "1",
530 long_alpn + "2",
531 long_alpn + "3",
532 long_alpn + "4",
533 long_alpn + "5",
534 long_alpn + "6",
535 long_alpn + "7",
536 long_alpn + "8",
537 })));
538 EXPECT_QUIC_BUG(client_stream_->CryptoConnect(), "Failed to set ALPN");
dschinazi91453642019-08-01 11:12:15 -0700539}
540
vasilvvad7424f2019-08-30 00:27:14 -0700541TEST_F(TlsHandshakerTest, ServerRequiresCustomALPN) {
dschinazi423adc72019-10-23 09:58:55 -0700542 const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
vasilvvad7424f2019-08-30 00:27:14 -0700543 EXPECT_CALL(server_session_, SelectAlpn(_))
dschinazi423adc72019-10-23 09:58:55 -0700544 .WillOnce([kTestAlpn](const std::vector<QuicStringPiece>& alpns) {
vasilvvad7424f2019-08-30 00:27:14 -0700545 return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
546 });
547 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
548 "Server did not select ALPN", _));
549 EXPECT_CALL(*server_conn_,
550 CloseConnection(QUIC_HANDSHAKE_FAILED,
551 "Server did not receive a known ALPN", _));
552 client_stream_->CryptoConnect();
553 ExchangeHandshakeMessages(client_stream_, server_stream_);
554
555 EXPECT_FALSE(client_stream_->handshake_confirmed());
556 EXPECT_FALSE(client_stream_->encryption_established());
557 EXPECT_FALSE(server_stream_->handshake_confirmed());
558 EXPECT_FALSE(server_stream_->encryption_established());
559}
560
561TEST_F(TlsHandshakerTest, CustomALPNNegotiation) {
562 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
563 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
564 EXPECT_CALL(client_session_,
565 OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_ESTABLISHED));
566 EXPECT_CALL(client_session_,
567 OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
568 EXPECT_CALL(server_session_,
569 OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED));
570
dschinazi423adc72019-10-23 09:58:55 -0700571 const std::string kTestAlpn = "A Custom ALPN Value";
572 const std::vector<std::string> kTestAlpns(
vasilvvad7424f2019-08-30 00:27:14 -0700573 {"foo", "bar", kTestAlpn, "something else"});
574 EXPECT_CALL(client_session_, GetAlpnsToOffer())
575 .WillRepeatedly(Return(kTestAlpns));
576 EXPECT_CALL(server_session_, SelectAlpn(_))
dschinazi423adc72019-10-23 09:58:55 -0700577 .WillOnce(
578 [kTestAlpn, kTestAlpns](const std::vector<QuicStringPiece>& alpns) {
579 EXPECT_THAT(alpns, ElementsAreArray(kTestAlpns));
580 return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
581 });
vasilvvad7424f2019-08-30 00:27:14 -0700582 EXPECT_CALL(client_session_, OnAlpnSelected(QuicStringPiece(kTestAlpn)));
583 EXPECT_CALL(server_session_, OnAlpnSelected(QuicStringPiece(kTestAlpn)));
584 client_stream_->CryptoConnect();
585 ExchangeHandshakeMessages(client_stream_, server_stream_);
586
nharper8f759922019-10-09 11:08:36 -0700587 ExpectHandshakeSuccessful();
vasilvvad7424f2019-08-30 00:27:14 -0700588}
589
QUICHE teama6ef0a62019-03-07 20:34:33 -0500590} // namespace
591} // namespace test
592} // namespace quic