blob: 75f07aaf93e6a3fa01d1e94e9e15df32f3c76932 [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
fayangd58736d2019-11-27 13:35:31 -0800180 void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
181
vasilvvc48c8712019-03-11 13:38:16 -0700182 const std::vector<std::pair<std::string, EncryptionLevel>>& pending_writes() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183 return pending_writes_;
184 }
185
186 // Sends the pending frames to |stream| and clears the array of pending
187 // writes.
188 void SendCryptoMessagesToPeer(QuicCryptoStream* stream) {
189 QUIC_LOG(INFO) << "Sending " << pending_writes_.size() << " frames";
190 // This is a minimal re-implementation of QuicCryptoStream::OnDataAvailable.
191 // It doesn't work to call QuicStream::OnStreamFrame because
192 // QuicCryptoStream::OnDataAvailable currently (as an implementation detail)
193 // relies on the QuicConnection to know the EncryptionLevel to pass into
194 // CryptoMessageParser::ProcessInput. Since the crypto messages in this test
195 // never reach the framer or connection and never get encrypted/decrypted,
196 // QuicCryptoStream::OnDataAvailable isn't able to call ProcessInput with
197 // the correct EncryptionLevel. Instead, that can be short-circuited by
198 // directly calling ProcessInput here.
199 for (size_t i = 0; i < pending_writes_.size(); ++i) {
200 if (!stream->crypto_message_parser()->ProcessInput(
201 pending_writes_[i].first, pending_writes_[i].second)) {
202 CloseConnectionWithDetails(
203 stream->crypto_message_parser()->error(),
204 stream->crypto_message_parser()->error_detail());
205 break;
206 }
207 }
208 pending_writes_.clear();
209 }
210
211 private:
vasilvvc48c8712019-03-11 13:38:16 -0700212 std::vector<std::pair<std::string, EncryptionLevel>> pending_writes_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213};
214
nharper40bdf532019-10-03 11:16:22 -0700215class MockProofHandler : public QuicCryptoClientStream::ProofHandler {
216 public:
217 MockProofHandler() = default;
218 ~MockProofHandler() override {}
219
220 MOCK_METHOD1(OnProofValid, void(const QuicCryptoClientConfig::CachedState&));
221 MOCK_METHOD1(OnProofVerifyDetailsAvailable, void(const ProofVerifyDetails&));
222};
223
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224class TestQuicCryptoClientStream : public TestQuicCryptoStream {
225 public:
226 explicit TestQuicCryptoClientStream(QuicSession* session)
227 : TestQuicCryptoStream(session),
nharperdf7a77b2019-11-11 13:12:45 -0800228 crypto_config_(std::make_unique<FakeProofVerifier>(),
229 /*session_cache*/ nullptr),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 handshaker_(new TlsClientHandshaker(
nharperdf7a77b2019-11-11 13:12:45 -0800231 QuicServerId("test.example.com", 443, false),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 this,
233 session,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500234 crypto_test_utils::ProofVerifyContextForTesting(),
nharperdf7a77b2019-11-11 13:12:45 -0800235 &crypto_config_,
236 &proof_handler_)) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500237
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 {
nharperdf7a77b2019-11-11 13:12:45 -0800247 return static_cast<FakeProofVerifier*>(crypto_config_.proof_verifier());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500248 }
249
250 private:
nharper40bdf532019-10-03 11:16:22 -0700251 MockProofHandler proof_handler_;
nharperdf7a77b2019-11-11 13:12:45 -0800252 QuicCryptoClientConfig crypto_config_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 std::unique_ptr<TlsClientHandshaker> handshaker_;
254};
255
256class TestQuicCryptoServerStream : public TestQuicCryptoStream {
257 public:
258 TestQuicCryptoServerStream(QuicSession* session,
259 FakeProofSource* proof_source)
260 : TestQuicCryptoStream(session),
261 proof_source_(proof_source),
nharper6ebe83b2019-06-13 17:43:52 -0700262 ssl_ctx_(TlsServerConnection::CreateSslCtx()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500263 handshaker_(new TlsServerHandshaker(this,
264 session,
265 ssl_ctx_.get(),
266 proof_source_)) {}
267
268 ~TestQuicCryptoServerStream() override = default;
269
270 void CancelOutstandingCallbacks() {
271 handshaker_->CancelOutstandingCallbacks();
272 }
273
fayangd58736d2019-11-27 13:35:31 -0800274 void OnPacketDecrypted(EncryptionLevel level) override {
275 handshaker_->OnPacketDecrypted(level);
276 }
277
QUICHE teama6ef0a62019-03-07 20:34:33 -0500278 TlsHandshaker* handshaker() const override { return handshaker_.get(); }
279
280 FakeProofSource* GetFakeProofSource() const { return proof_source_; }
281
282 private:
283 FakeProofSource* proof_source_;
284 bssl::UniquePtr<SSL_CTX> ssl_ctx_;
285 std::unique_ptr<TlsServerHandshaker> handshaker_;
286};
287
288void ExchangeHandshakeMessages(TestQuicCryptoStream* client,
289 TestQuicCryptoStream* server) {
290 while (!client->pending_writes().empty() ||
291 !server->pending_writes().empty()) {
292 client->SendCryptoMessagesToPeer(server);
293 server->SendCryptoMessagesToPeer(client);
294 }
295}
296
297class TlsHandshakerTest : public QuicTest {
298 public:
299 TlsHandshakerTest()
nharper107ba5f2019-07-02 21:33:39 -0700300 : client_conn_(new MockQuicConnection(
301 &conn_helper_,
302 &alarm_factory_,
303 Perspective::IS_CLIENT,
304 {ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)})),
305 server_conn_(new MockQuicConnection(
306 &conn_helper_,
307 &alarm_factory_,
308 Perspective::IS_SERVER,
309 {ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)})),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310 client_session_(client_conn_, /*create_mock_crypto_stream=*/false),
311 server_session_(server_conn_, /*create_mock_crypto_stream=*/false) {
312 client_stream_ = new TestQuicCryptoClientStream(&client_session_);
313 client_session_.SetCryptoStream(client_stream_);
314 server_stream_ =
315 new TestQuicCryptoServerStream(&server_session_, &proof_source_);
316 server_session_.SetCryptoStream(server_stream_);
317 client_session_.Initialize();
318 server_session_.Initialize();
319 EXPECT_FALSE(client_stream_->encryption_established());
320 EXPECT_FALSE(client_stream_->handshake_confirmed());
321 EXPECT_FALSE(server_stream_->encryption_established());
322 EXPECT_FALSE(server_stream_->handshake_confirmed());
vasilvvad7424f2019-08-30 00:27:14 -0700323 const std::string default_alpn =
324 AlpnForVersion(client_session_.connection()->version());
vasilvv4724c9c2019-08-29 11:52:11 -0700325 ON_CALL(client_session_, GetAlpnsToOffer())
vasilvvad7424f2019-08-30 00:27:14 -0700326 .WillByDefault(Return(std::vector<std::string>({default_alpn})));
327 ON_CALL(server_session_, SelectAlpn(_))
328 .WillByDefault(
329 [default_alpn](const std::vector<QuicStringPiece>& alpns) {
330 return std::find(alpns.begin(), alpns.end(), default_alpn);
331 });
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332 }
333
nharper8f759922019-10-09 11:08:36 -0700334 void ExpectHandshakeSuccessful() {
335 EXPECT_TRUE(client_stream_->handshake_confirmed());
336 EXPECT_TRUE(client_stream_->encryption_established());
337 EXPECT_TRUE(server_stream_->handshake_confirmed());
338 EXPECT_TRUE(server_stream_->encryption_established());
fayangfa3b1d62019-11-18 08:02:13 -0800339 EXPECT_TRUE(client_conn_->IsHandshakeComplete());
340 EXPECT_TRUE(server_conn_->IsHandshakeComplete());
nharper8f759922019-10-09 11:08:36 -0700341
342 const auto& client_crypto_params =
343 client_stream_->crypto_negotiated_params();
344 const auto& server_crypto_params =
345 server_stream_->crypto_negotiated_params();
346 // The TLS params should be filled in on the client.
347 EXPECT_NE(0, client_crypto_params.cipher_suite);
348 EXPECT_NE(0, client_crypto_params.key_exchange_group);
349 EXPECT_NE(0, client_crypto_params.peer_signature_algorithm);
350
351 // The cipher suite and key exchange group should match on the client and
352 // server.
353 EXPECT_EQ(client_crypto_params.cipher_suite,
354 server_crypto_params.cipher_suite);
355 EXPECT_EQ(client_crypto_params.key_exchange_group,
356 server_crypto_params.key_exchange_group);
357 // We don't support client certs on the server (yet), so the server
358 // shouldn't have a peer signature algorithm to report.
359 EXPECT_EQ(0, server_crypto_params.peer_signature_algorithm);
360 }
361
QUICHE teama6ef0a62019-03-07 20:34:33 -0500362 MockQuicConnectionHelper conn_helper_;
363 MockAlarmFactory alarm_factory_;
364 MockQuicConnection* client_conn_;
365 MockQuicConnection* server_conn_;
366 MockQuicSession client_session_;
367 MockQuicSession server_session_;
368
369 FakeProofSource proof_source_;
370 TestQuicCryptoClientStream* client_stream_;
371 TestQuicCryptoServerStream* server_stream_;
372};
373
374TEST_F(TlsHandshakerTest, CryptoHandshake) {
fayangfa3b1d62019-11-18 08:02:13 -0800375 EXPECT_FALSE(client_conn_->IsHandshakeComplete());
376 EXPECT_FALSE(server_conn_->IsHandshakeComplete());
fayangbd793922019-08-26 14:19:24 -0700377
QUICHE teama6ef0a62019-03-07 20:34:33 -0500378 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
379 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
nharper40bdf532019-10-03 11:16:22 -0700380 EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500381 client_stream_->CryptoConnect();
382 ExchangeHandshakeMessages(client_stream_, server_stream_);
383
nharper8f759922019-10-09 11:08:36 -0700384 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385}
386
387TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofSource) {
388 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
389 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
390 // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
391 // asynchronously.
392 FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
393 proof_source->Activate();
394
395 // Start handshake.
396 client_stream_->CryptoConnect();
397 ExchangeHandshakeMessages(client_stream_, server_stream_);
398
399 ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
400 proof_source->InvokePendingCallback(0);
401
402 ExchangeHandshakeMessages(client_stream_, server_stream_);
403
nharper8f759922019-10-09 11:08:36 -0700404 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500405}
406
407TEST_F(TlsHandshakerTest, CancelPendingProofSource) {
408 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
409 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
410 // Enable FakeProofSource to capture call to ComputeTlsSignature and run it
411 // asynchronously.
412 FakeProofSource* proof_source = server_stream_->GetFakeProofSource();
413 proof_source->Activate();
414
415 // Start handshake.
416 client_stream_->CryptoConnect();
417 ExchangeHandshakeMessages(client_stream_, server_stream_);
418
419 ASSERT_EQ(proof_source->NumPendingCallbacks(), 1);
420 server_stream_ = nullptr;
421
422 proof_source->InvokePendingCallback(0);
423}
424
425TEST_F(TlsHandshakerTest, HandshakeWithAsyncProofVerifier) {
426 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
427 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
428 // Enable FakeProofVerifier to capture call to VerifyCertChain and run it
429 // asynchronously.
430 FakeProofVerifier* proof_verifier = client_stream_->GetFakeProofVerifier();
431 proof_verifier->Activate();
432
nharper40bdf532019-10-03 11:16:22 -0700433 EXPECT_CALL(client_stream_->proof_handler(), OnProofVerifyDetailsAvailable);
434
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435 // Start handshake.
436 client_stream_->CryptoConnect();
437 ExchangeHandshakeMessages(client_stream_, server_stream_);
438
439 ASSERT_EQ(proof_verifier->NumPendingCallbacks(), 1u);
440 proof_verifier->InvokePendingCallback(0);
441
442 ExchangeHandshakeMessages(client_stream_, server_stream_);
443
nharper8f759922019-10-09 11:08:36 -0700444 ExpectHandshakeSuccessful();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500445}
446
447TEST_F(TlsHandshakerTest, ClientConnectionClosedOnTlsError) {
448 // Have client send ClientHello.
449 client_stream_->CryptoConnect();
450 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
451
452 // Send a zero-length ServerHello from server to client.
453 char bogus_handshake_message[] = {
454 // Handshake struct (RFC 8446 appendix B.3)
455 2, // HandshakeType server_hello
456 0, 0, 0, // uint24 length
457 };
458 server_stream_->WriteCryptoData(
QUICHE team6987b4a2019-03-15 16:23:04 -0700459 ENCRYPTION_INITIAL,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500460 QuicStringPiece(bogus_handshake_message,
461 QUIC_ARRAYSIZE(bogus_handshake_message)));
462 server_stream_->SendCryptoMessagesToPeer(client_stream_);
463
464 EXPECT_FALSE(client_stream_->handshake_confirmed());
465}
466
467TEST_F(TlsHandshakerTest, ServerConnectionClosedOnTlsError) {
468 EXPECT_CALL(*server_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _));
469
470 // Send a zero-length ClientHello from client to server.
471 char bogus_handshake_message[] = {
472 // Handshake struct (RFC 8446 appendix B.3)
473 1, // HandshakeType client_hello
474 0, 0, 0, // uint24 length
475 };
476 client_stream_->WriteCryptoData(
QUICHE team6987b4a2019-03-15 16:23:04 -0700477 ENCRYPTION_INITIAL,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500478 QuicStringPiece(bogus_handshake_message,
479 QUIC_ARRAYSIZE(bogus_handshake_message)));
480 client_stream_->SendCryptoMessagesToPeer(server_stream_);
481
482 EXPECT_FALSE(server_stream_->handshake_confirmed());
483}
484
dschinazi91453642019-08-01 11:12:15 -0700485TEST_F(TlsHandshakerTest, ClientNotSendingALPN) {
vasilvv4724c9c2019-08-29 11:52:11 -0700486 client_stream_->client_handshaker()->AllowEmptyAlpnForTests();
487 EXPECT_CALL(client_session_, GetAlpnsToOffer())
488 .WillOnce(Return(std::vector<std::string>()));
dschinazi91453642019-08-01 11:12:15 -0700489 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
490 "Server did not select ALPN", _));
491 EXPECT_CALL(*server_conn_,
492 CloseConnection(QUIC_HANDSHAKE_FAILED,
493 "Server did not receive a known ALPN", _));
494 client_stream_->CryptoConnect();
495 ExchangeHandshakeMessages(client_stream_, server_stream_);
496
497 EXPECT_FALSE(client_stream_->handshake_confirmed());
498 EXPECT_FALSE(client_stream_->encryption_established());
499 EXPECT_FALSE(server_stream_->handshake_confirmed());
500 EXPECT_FALSE(server_stream_->encryption_established());
dschinazi91453642019-08-01 11:12:15 -0700501}
502
503TEST_F(TlsHandshakerTest, ClientSendingBadALPN) {
dschinazi423adc72019-10-23 09:58:55 -0700504 const std::string kTestBadClientAlpn = "bad-client-alpn";
vasilvv4724c9c2019-08-29 11:52:11 -0700505 EXPECT_CALL(client_session_, GetAlpnsToOffer())
506 .WillOnce(Return(std::vector<std::string>({kTestBadClientAlpn})));
dschinazi91453642019-08-01 11:12:15 -0700507 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
508 "Server did not select ALPN", _));
509 EXPECT_CALL(*server_conn_,
510 CloseConnection(QUIC_HANDSHAKE_FAILED,
511 "Server did not receive a known ALPN", _));
512 client_stream_->CryptoConnect();
513 ExchangeHandshakeMessages(client_stream_, server_stream_);
514
515 EXPECT_FALSE(client_stream_->handshake_confirmed());
516 EXPECT_FALSE(client_stream_->encryption_established());
517 EXPECT_FALSE(server_stream_->handshake_confirmed());
518 EXPECT_FALSE(server_stream_->encryption_established());
vasilvv4724c9c2019-08-29 11:52:11 -0700519}
520
521TEST_F(TlsHandshakerTest, ClientSendingTooManyALPNs) {
522 std::string long_alpn(250, 'A');
523 EXPECT_CALL(client_session_, GetAlpnsToOffer())
524 .WillOnce(Return(std::vector<std::string>({
525 long_alpn + "1",
526 long_alpn + "2",
527 long_alpn + "3",
528 long_alpn + "4",
529 long_alpn + "5",
530 long_alpn + "6",
531 long_alpn + "7",
532 long_alpn + "8",
533 })));
534 EXPECT_QUIC_BUG(client_stream_->CryptoConnect(), "Failed to set ALPN");
dschinazi91453642019-08-01 11:12:15 -0700535}
536
vasilvvad7424f2019-08-30 00:27:14 -0700537TEST_F(TlsHandshakerTest, ServerRequiresCustomALPN) {
dschinazi423adc72019-10-23 09:58:55 -0700538 const std::string kTestAlpn = "An ALPN That Client Did Not Offer";
vasilvvad7424f2019-08-30 00:27:14 -0700539 EXPECT_CALL(server_session_, SelectAlpn(_))
dschinazi423adc72019-10-23 09:58:55 -0700540 .WillOnce([kTestAlpn](const std::vector<QuicStringPiece>& alpns) {
vasilvvad7424f2019-08-30 00:27:14 -0700541 return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
542 });
543 EXPECT_CALL(*client_conn_, CloseConnection(QUIC_HANDSHAKE_FAILED,
544 "Server did not select ALPN", _));
545 EXPECT_CALL(*server_conn_,
546 CloseConnection(QUIC_HANDSHAKE_FAILED,
547 "Server did not receive a known ALPN", _));
548 client_stream_->CryptoConnect();
549 ExchangeHandshakeMessages(client_stream_, server_stream_);
550
551 EXPECT_FALSE(client_stream_->handshake_confirmed());
552 EXPECT_FALSE(client_stream_->encryption_established());
553 EXPECT_FALSE(server_stream_->handshake_confirmed());
554 EXPECT_FALSE(server_stream_->encryption_established());
555}
556
557TEST_F(TlsHandshakerTest, CustomALPNNegotiation) {
558 EXPECT_CALL(*client_conn_, CloseConnection(_, _, _)).Times(0);
559 EXPECT_CALL(*server_conn_, CloseConnection(_, _, _)).Times(0);
vasilvvad7424f2019-08-30 00:27:14 -0700560
dschinazi423adc72019-10-23 09:58:55 -0700561 const std::string kTestAlpn = "A Custom ALPN Value";
562 const std::vector<std::string> kTestAlpns(
vasilvvad7424f2019-08-30 00:27:14 -0700563 {"foo", "bar", kTestAlpn, "something else"});
564 EXPECT_CALL(client_session_, GetAlpnsToOffer())
565 .WillRepeatedly(Return(kTestAlpns));
566 EXPECT_CALL(server_session_, SelectAlpn(_))
dschinazi423adc72019-10-23 09:58:55 -0700567 .WillOnce(
568 [kTestAlpn, kTestAlpns](const std::vector<QuicStringPiece>& alpns) {
569 EXPECT_THAT(alpns, ElementsAreArray(kTestAlpns));
570 return std::find(alpns.cbegin(), alpns.cend(), kTestAlpn);
571 });
vasilvvad7424f2019-08-30 00:27:14 -0700572 EXPECT_CALL(client_session_, OnAlpnSelected(QuicStringPiece(kTestAlpn)));
573 EXPECT_CALL(server_session_, OnAlpnSelected(QuicStringPiece(kTestAlpn)));
574 client_stream_->CryptoConnect();
575 ExchangeHandshakeMessages(client_stream_, server_stream_);
576
nharper8f759922019-10-09 11:08:36 -0700577 ExpectHandshakeSuccessful();
vasilvvad7424f2019-08-30 00:27:14 -0700578}
579
QUICHE teama6ef0a62019-03-07 20:34:33 -0500580} // namespace
581} // namespace test
582} // namespace quic