blob: 324c3780ee2c602fb0f50ec0840b89e241f19789 [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
5#include "net/third_party/quiche/src/quic/core/tls_client_handshaker.h"
6
dschinazi35e749e2019-04-09 09:36:04 -07007#include <cstring>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
9
QUICHE teama6ef0a62019-03-07 20:34:33 -050010#include "third_party/boringssl/src/include/openssl/ssl.h"
renjietangf21e3852020-04-13 15:45:39 -070011#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
13#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
14#include "net/third_party/quiche/src/quic/core/quic_session.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080015#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
16#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017
18namespace quic {
19
20TlsClientHandshaker::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
21 TlsClientHandshaker* parent)
22 : parent_(parent) {}
23
24TlsClientHandshaker::ProofVerifierCallbackImpl::~ProofVerifierCallbackImpl() {}
25
26void TlsClientHandshaker::ProofVerifierCallbackImpl::Run(
27 bool ok,
dschinazi17d42422019-06-18 16:35:07 -070028 const std::string& /*error_details*/,
QUICHE teama6ef0a62019-03-07 20:34:33 -050029 std::unique_ptr<ProofVerifyDetails>* details) {
30 if (parent_ == nullptr) {
31 return;
32 }
33
34 parent_->verify_details_ = std::move(*details);
35 parent_->verify_result_ = ok ? ssl_verify_ok : ssl_verify_invalid;
36 parent_->state_ = STATE_HANDSHAKE_RUNNING;
37 parent_->proof_verify_callback_ = nullptr;
nharperbe646e52020-04-16 13:24:18 -070038 if (parent_->verify_details_) {
39 parent_->proof_handler_->OnProofVerifyDetailsAvailable(
40 *parent_->verify_details_);
41 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 parent_->AdvanceHandshake();
43}
44
45void TlsClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
46 parent_ = nullptr;
47}
48
49TlsClientHandshaker::TlsClientHandshaker(
nharperdf7a77b2019-11-11 13:12:45 -080050 const QuicServerId& server_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 QuicCryptoStream* stream,
52 QuicSession* session,
QUICHE teama6ef0a62019-03-07 20:34:33 -050053 std::unique_ptr<ProofVerifyContext> verify_context,
nharperdf7a77b2019-11-11 13:12:45 -080054 QuicCryptoClientConfig* crypto_config,
renjietangbcc066a2020-04-21 18:05:57 -070055 QuicCryptoClientStream::ProofHandler* proof_handler,
56 bool has_application_state)
nharper80d3b172020-01-17 11:43:39 -080057 : TlsHandshaker(stream, session),
nharperf579b5e2020-01-21 14:11:18 -080058 session_(session),
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 server_id_(server_id),
nharperdf7a77b2019-11-11 13:12:45 -080060 proof_verifier_(crypto_config->proof_verifier()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050061 verify_context_(std::move(verify_context)),
nharper40bdf532019-10-03 11:16:22 -070062 proof_handler_(proof_handler),
nharperdf7a77b2019-11-11 13:12:45 -080063 session_cache_(crypto_config->session_cache()),
64 user_agent_id_(crypto_config->user_agent_id()),
dschinaziaaaf1a42020-04-16 11:44:31 -070065 pre_shared_key_(crypto_config->pre_shared_key()),
nharper6ebe83b2019-06-13 17:43:52 -070066 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
renjietangbcc066a2020-04-21 18:05:57 -070067 has_application_state_(has_application_state),
nharperdf7a77b2019-11-11 13:12:45 -080068 tls_connection_(crypto_config->ssl_ctx(), this) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050069
70TlsClientHandshaker::~TlsClientHandshaker() {
71 if (proof_verify_callback_) {
72 proof_verify_callback_->Cancel();
73 }
74}
75
QUICHE teama6ef0a62019-03-07 20:34:33 -050076bool TlsClientHandshaker::CryptoConnect() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 state_ = STATE_HANDSHAKE_RUNNING;
QUICHE teama6ef0a62019-03-07 20:34:33 -050078
dschinaziaaaf1a42020-04-16 11:44:31 -070079 if (!pre_shared_key_.empty()) {
80 // TODO(b/154162689) add PSK support to QUIC+TLS.
81 std::string error_details =
82 "QUIC client pre-shared keys not yet supported with TLS";
83 QUIC_BUG << error_details;
84 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
85 return false;
86 }
87
nharper0f51d2e2019-12-11 17:52:05 -080088 // Set the SNI to send, if any.
QUICHE teama6ef0a62019-03-07 20:34:33 -050089 SSL_set_connect_state(ssl());
nharper0f51d2e2019-12-11 17:52:05 -080090 if (!server_id_.host().empty() &&
91 SSL_set_tlsext_host_name(ssl(), server_id_.host().c_str()) != 1) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 return false;
93 }
94
vasilvv4724c9c2019-08-29 11:52:11 -070095 if (!SetAlpn()) {
96 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client failed to set ALPN");
dschinazi35e749e2019-04-09 09:36:04 -070097 return false;
98 }
dschinazi35e749e2019-04-09 09:36:04 -070099
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 // Set the Transport Parameters to send in the ClientHello
101 if (!SetTransportParameters()) {
102 CloseConnection(QUIC_HANDSHAKE_FAILED,
dschinazi91453642019-08-01 11:12:15 -0700103 "Client failed to set Transport Parameters");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 return false;
105 }
106
nharperdf7a77b2019-11-11 13:12:45 -0800107 // Set a session to resume, if there is one.
108 if (session_cache_) {
109 std::unique_ptr<QuicResumptionState> cached_state =
110 session_cache_->Lookup(server_id_, SSL_get_SSL_CTX(ssl()));
111 if (cached_state) {
112 SSL_set_session(ssl(), cached_state->tls_session.get());
113 }
114 }
115
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116 // Start the handshake.
117 AdvanceHandshake();
118 return session()->connection()->connected();
119}
120
vasilvv4724c9c2019-08-29 11:52:11 -0700121static bool IsValidAlpn(const std::string& alpn_string) {
122 return alpn_string.length() <= std::numeric_limits<uint8_t>::max();
123}
124
125bool TlsClientHandshaker::SetAlpn() {
126 std::vector<std::string> alpns = session()->GetAlpnsToOffer();
127 if (alpns.empty()) {
128 if (allow_empty_alpn_for_tests_) {
129 return true;
130 }
131
132 QUIC_BUG << "ALPN missing";
133 return false;
134 }
135 if (!std::all_of(alpns.begin(), alpns.end(), IsValidAlpn)) {
136 QUIC_BUG << "ALPN too long";
137 return false;
138 }
139
140 // SSL_set_alpn_protos expects a sequence of one-byte-length-prefixed
141 // strings.
142 uint8_t alpn[1024];
143 QuicDataWriter alpn_writer(sizeof(alpn), reinterpret_cast<char*>(alpn));
144 bool success = true;
145 for (const std::string& alpn_string : alpns) {
146 success = success && alpn_writer.WriteUInt8(alpn_string.size()) &&
147 alpn_writer.WriteStringPiece(alpn_string);
148 }
149 success =
150 success && (SSL_set_alpn_protos(ssl(), alpn, alpn_writer.length()) == 0);
151 if (!success) {
152 QUIC_BUG << "Failed to set ALPN: "
dmcardlecf0bfcf2019-12-13 08:08:21 -0800153 << quiche::QuicheTextUtils::HexDump(quiche::QuicheStringPiece(
154 alpn_writer.data(), alpn_writer.length()));
vasilvv4724c9c2019-08-29 11:52:11 -0700155 return false;
156 }
157 QUIC_DLOG(INFO) << "Client using ALPN: '" << alpns[0] << "'";
158 return true;
159}
160
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161bool TlsClientHandshaker::SetTransportParameters() {
162 TransportParameters params;
163 params.perspective = Perspective::IS_CLIENT;
164 params.version =
165 CreateQuicVersionLabel(session()->supported_versions().front());
166
167 if (!session()->config()->FillTransportParameters(&params)) {
168 return false;
169 }
170 params.google_quic_params->SetStringPiece(kUAID, user_agent_id_);
171
172 std::vector<uint8_t> param_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700173 return SerializeTransportParameters(session()->connection()->version(),
174 params, &param_bytes) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500175 SSL_set_quic_transport_params(ssl(), param_bytes.data(),
176 param_bytes.size()) == 1;
177}
178
179bool TlsClientHandshaker::ProcessTransportParameters(
vasilvvc48c8712019-03-11 13:38:16 -0700180 std::string* error_details) {
renjietangcc12f432020-04-09 16:44:22 -0700181 received_transport_params_ = std::make_unique<TransportParameters>();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 const uint8_t* param_bytes;
183 size_t param_bytes_len;
184 SSL_get_peer_quic_transport_params(ssl(), &param_bytes, &param_bytes_len);
dschinazi7b8f0c72020-03-02 13:17:57 -0800185 if (param_bytes_len == 0) {
186 *error_details = "Server's transport parameters are missing";
187 return false;
188 }
189 std::string parse_error_details;
190 if (!ParseTransportParameters(
191 session()->connection()->version(), Perspective::IS_SERVER,
renjietangcc12f432020-04-09 16:44:22 -0700192 param_bytes, param_bytes_len, received_transport_params_.get(),
193 &parse_error_details)) {
dschinazi7b8f0c72020-03-02 13:17:57 -0800194 DCHECK(!parse_error_details.empty());
195 *error_details =
196 "Unable to parse server's transport parameters: " + parse_error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197 return false;
198 }
199
dschinazi6cf4d2a2019-04-30 16:20:23 -0700200 // When interoperating with non-Google implementations that do not send
201 // the version extension, set it to what we expect.
renjietangcc12f432020-04-09 16:44:22 -0700202 if (received_transport_params_->version == 0) {
203 received_transport_params_->version =
204 CreateQuicVersionLabel(session()->connection()->version());
dschinazi6cf4d2a2019-04-30 16:20:23 -0700205 }
renjietangcc12f432020-04-09 16:44:22 -0700206 if (received_transport_params_->supported_versions.empty()) {
207 received_transport_params_->supported_versions.push_back(
208 received_transport_params_->version);
dschinazi6cf4d2a2019-04-30 16:20:23 -0700209 }
210
renjietangcc12f432020-04-09 16:44:22 -0700211 if (received_transport_params_->version !=
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212 CreateQuicVersionLabel(session()->connection()->version())) {
213 *error_details = "Version mismatch detected";
214 return false;
215 }
216 if (CryptoUtils::ValidateServerHelloVersions(
renjietangcc12f432020-04-09 16:44:22 -0700217 received_transport_params_->supported_versions,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218 session()->connection()->server_supported_versions(),
219 error_details) != QUIC_NO_ERROR ||
220 session()->config()->ProcessTransportParameters(
renjietangcc12f432020-04-09 16:44:22 -0700221 *received_transport_params_, SERVER, error_details) !=
222 QUIC_NO_ERROR) {
dschinazid1967a22019-04-03 16:11:32 -0700223 DCHECK(!error_details->empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500224 return false;
225 }
226
227 session()->OnConfigNegotiated();
228 return true;
229}
230
231int TlsClientHandshaker::num_sent_client_hellos() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500232 return 0;
233}
234
nharper02703962019-11-07 12:23:13 -0800235bool TlsClientHandshaker::IsResumption() const {
fayang685367a2020-01-14 10:40:15 -0800236 QUIC_BUG_IF(!one_rtt_keys_available_);
nharperdf7a77b2019-11-11 13:12:45 -0800237 return SSL_session_reused(ssl()) == 1;
nharper02703962019-11-07 12:23:13 -0800238}
239
nharper4084fc92020-02-10 14:43:35 -0800240bool TlsClientHandshaker::EarlyDataAccepted() const {
241 QUIC_BUG_IF(!one_rtt_keys_available_);
242 return SSL_early_data_accepted(ssl()) == 1;
243}
244
245bool TlsClientHandshaker::ReceivedInchoateReject() const {
246 QUIC_BUG_IF(!one_rtt_keys_available_);
247 // REJ messages are a QUIC crypto feature, so TLS always returns false.
248 return false;
249}
250
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251int TlsClientHandshaker::num_scup_messages_received() const {
252 // SCUP messages aren't sent or received when using the TLS handshake.
253 return 0;
254}
255
vasilvvc48c8712019-03-11 13:38:16 -0700256std::string TlsClientHandshaker::chlo_hash() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500257 return "";
258}
259
260bool TlsClientHandshaker::encryption_established() const {
261 return encryption_established_;
262}
263
fayang685367a2020-01-14 10:40:15 -0800264bool TlsClientHandshaker::one_rtt_keys_available() const {
265 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500266}
267
268const QuicCryptoNegotiatedParameters&
269TlsClientHandshaker::crypto_negotiated_params() const {
270 return *crypto_negotiated_params_;
271}
272
273CryptoMessageParser* TlsClientHandshaker::crypto_message_parser() {
274 return TlsHandshaker::crypto_message_parser();
275}
276
fayang9a863cf2020-01-16 14:12:11 -0800277HandshakeState TlsClientHandshaker::GetHandshakeState() const {
fayang01062942020-01-22 07:23:23 -0800278 if (handshake_confirmed_) {
279 return HANDSHAKE_CONFIRMED;
280 }
fayang9a863cf2020-01-16 14:12:11 -0800281 if (one_rtt_keys_available_) {
282 return HANDSHAKE_COMPLETE;
283 }
284 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
285 return HANDSHAKE_PROCESSED;
286 }
287 return HANDSHAKE_START;
288}
289
nharper486a8a92019-08-28 16:25:10 -0700290size_t TlsClientHandshaker::BufferSizeLimitForLevel(
291 EncryptionLevel level) const {
292 return TlsHandshaker::BufferSizeLimitForLevel(level);
293}
294
fayang2f2915d2020-01-24 06:47:15 -0800295void TlsClientHandshaker::OnOneRttPacketAcknowledged() {
296 OnHandshakeConfirmed();
297}
298
fayang44ae4e92020-04-28 13:09:42 -0700299void TlsClientHandshaker::OnHandshakePacketSent() {
300 if (initial_keys_dropped_) {
301 return;
302 }
303 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
304 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
305 initial_keys_dropped_ = true;
306}
307
fayanga6a85a82020-05-04 08:58:53 -0700308void TlsClientHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
309 ConnectionCloseSource /*source*/) {
310 state_ = STATE_CONNECTION_CLOSED;
311}
312
fayang01062942020-01-22 07:23:23 -0800313void TlsClientHandshaker::OnHandshakeDoneReceived() {
314 if (!one_rtt_keys_available_) {
315 CloseConnection(QUIC_HANDSHAKE_FAILED,
316 "Unexpected handshake done received");
317 return;
318 }
fayang2f2915d2020-01-24 06:47:15 -0800319 OnHandshakeConfirmed();
320}
321
fayanga45ee8a2020-03-20 08:56:11 -0700322void TlsClientHandshaker::SetWriteSecret(
323 EncryptionLevel level,
324 const SSL_CIPHER* cipher,
325 const std::vector<uint8_t>& write_secret) {
fayanga6a85a82020-05-04 08:58:53 -0700326 if (state_ == STATE_CONNECTION_CLOSED) {
327 return;
328 }
fayangb5e1d5b2020-04-29 11:00:38 -0700329 if (level == ENCRYPTION_FORWARD_SECURE) {
fayanga45ee8a2020-03-20 08:56:11 -0700330 encryption_established_ = true;
331 }
332 TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
333}
334
fayang2f2915d2020-01-24 06:47:15 -0800335void TlsClientHandshaker::OnHandshakeConfirmed() {
336 DCHECK(one_rtt_keys_available_);
fayang01062942020-01-22 07:23:23 -0800337 if (handshake_confirmed_) {
338 return;
339 }
340 handshake_confirmed_ = true;
renjietangbd33b622020-02-12 16:52:30 -0800341 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
342 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
fayang01062942020-01-22 07:23:23 -0800343}
344
QUICHE teama6ef0a62019-03-07 20:34:33 -0500345void TlsClientHandshaker::AdvanceHandshake() {
346 if (state_ == STATE_CONNECTION_CLOSED) {
347 QUIC_LOG(INFO)
348 << "TlsClientHandshaker received message after connection closed";
349 return;
350 }
351 if (state_ == STATE_IDLE) {
dschinazi91453642019-08-01 11:12:15 -0700352 CloseConnection(QUIC_HANDSHAKE_FAILED,
353 "Client observed TLS handshake idle failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500354 return;
355 }
356 if (state_ == STATE_HANDSHAKE_COMPLETE) {
nharperdf7a77b2019-11-11 13:12:45 -0800357 int rv = SSL_process_quic_post_handshake(ssl());
358 if (rv != 1) {
359 CloseConnection(QUIC_HANDSHAKE_FAILED, "Unexpected post-handshake data");
360 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500361 return;
362 }
363
364 QUIC_LOG(INFO) << "TlsClientHandshaker: continuing handshake";
365 int rv = SSL_do_handshake(ssl());
366 if (rv == 1) {
367 FinishHandshake();
368 return;
369 }
370 int ssl_error = SSL_get_error(ssl(), rv);
371 bool should_close = true;
372 switch (state_) {
373 case STATE_HANDSHAKE_RUNNING:
374 should_close = ssl_error != SSL_ERROR_WANT_READ;
375 break;
376 case STATE_CERT_VERIFY_PENDING:
377 should_close = ssl_error != SSL_ERROR_WANT_CERTIFICATE_VERIFY;
378 break;
379 default:
380 should_close = true;
381 }
382 if (should_close && state_ != STATE_CONNECTION_CLOSED) {
383 // TODO(nharper): Surface error details from the error queue when ssl_error
384 // is SSL_ERROR_SSL.
385 QUIC_LOG(WARNING) << "SSL_do_handshake failed; closing connection";
dschinazi91453642019-08-01 11:12:15 -0700386 CloseConnection(QUIC_HANDSHAKE_FAILED,
387 "Client observed TLS handshake failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388 }
389}
390
391void TlsClientHandshaker::CloseConnection(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700392 const std::string& reason_phrase) {
dschinazid1967a22019-04-03 16:11:32 -0700393 DCHECK(!reason_phrase.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 state_ = STATE_CONNECTION_CLOSED;
renjietang87df0d02020-02-13 11:53:52 -0800395 stream()->OnUnrecoverableError(error, reason_phrase);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500396}
397
398void TlsClientHandshaker::FinishHandshake() {
399 QUIC_LOG(INFO) << "Client: handshake finished";
400 state_ = STATE_HANDSHAKE_COMPLETE;
fayangb5e1d5b2020-04-29 11:00:38 -0700401 // Fill crypto_negotiated_params_:
402 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
403 if (cipher) {
404 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
fayanga45ee8a2020-03-20 08:56:11 -0700405 }
fayangb5e1d5b2020-04-29 11:00:38 -0700406 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
407 crypto_negotiated_params_->peer_signature_algorithm =
408 SSL_get_peer_signature_algorithm(ssl());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409
vasilvvc48c8712019-03-11 13:38:16 -0700410 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 if (!ProcessTransportParameters(&error_details)) {
dschinazid1967a22019-04-03 16:11:32 -0700412 DCHECK(!error_details.empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500413 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
414 return;
415 }
416
dschinazi35e749e2019-04-09 09:36:04 -0700417 const uint8_t* alpn_data = nullptr;
418 unsigned alpn_length = 0;
419 SSL_get0_alpn_selected(ssl(), &alpn_data, &alpn_length);
dschinazi91453642019-08-01 11:12:15 -0700420
421 if (alpn_length == 0) {
422 QUIC_DLOG(ERROR) << "Client: server did not select ALPN";
423 // TODO(b/130164908) this should send no_application_protocol
424 // instead of QUIC_HANDSHAKE_FAILED.
425 CloseConnection(QUIC_HANDSHAKE_FAILED, "Server did not select ALPN");
426 return;
dschinazi35e749e2019-04-09 09:36:04 -0700427 }
428
dschinazi91453642019-08-01 11:12:15 -0700429 std::string received_alpn_string(reinterpret_cast<const char*>(alpn_data),
430 alpn_length);
vasilvvad7424f2019-08-30 00:27:14 -0700431 std::vector<std::string> offered_alpns = session()->GetAlpnsToOffer();
432 if (std::find(offered_alpns.begin(), offered_alpns.end(),
433 received_alpn_string) == offered_alpns.end()) {
dschinazi91453642019-08-01 11:12:15 -0700434 QUIC_LOG(ERROR) << "Client: received mismatched ALPN '"
vasilvvad7424f2019-08-30 00:27:14 -0700435 << received_alpn_string;
dschinazi91453642019-08-01 11:12:15 -0700436 // TODO(b/130164908) this should send no_application_protocol
437 // instead of QUIC_HANDSHAKE_FAILED.
438 CloseConnection(QUIC_HANDSHAKE_FAILED, "Client received mismatched ALPN");
439 return;
440 }
vasilvvad7424f2019-08-30 00:27:14 -0700441 session()->OnAlpnSelected(received_alpn_string);
dschinazi91453642019-08-01 11:12:15 -0700442 QUIC_DLOG(INFO) << "Client: server selected ALPN: '" << received_alpn_string
443 << "'";
fayang685367a2020-01-14 10:40:15 -0800444 one_rtt_keys_available_ = true;
fayangd18bfb92020-03-19 17:24:21 -0700445 handshaker_delegate()->OnOneRttKeysAvailable();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446}
447
QUICHE teama6ef0a62019-03-07 20:34:33 -0500448enum ssl_verify_result_t TlsClientHandshaker::VerifyCert(uint8_t* out_alert) {
449 if (verify_result_ != ssl_verify_retry ||
450 state_ == STATE_CERT_VERIFY_PENDING) {
451 enum ssl_verify_result_t result = verify_result_;
452 verify_result_ = ssl_verify_retry;
453 return result;
454 }
455 const STACK_OF(CRYPTO_BUFFER)* cert_chain = SSL_get0_peer_certificates(ssl());
456 if (cert_chain == nullptr) {
457 *out_alert = SSL_AD_INTERNAL_ERROR;
458 return ssl_verify_invalid;
459 }
460 // TODO(nharper): Pass the CRYPTO_BUFFERs into the QUIC stack to avoid copies.
vasilvvc48c8712019-03-11 13:38:16 -0700461 std::vector<std::string> certs;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500462 for (CRYPTO_BUFFER* cert : cert_chain) {
463 certs.push_back(
vasilvvc48c8712019-03-11 13:38:16 -0700464 std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert)),
465 CRYPTO_BUFFER_len(cert)));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 }
QUICHE team38c190b2019-05-08 09:12:01 -0700467 const uint8_t* ocsp_response_raw;
468 size_t ocsp_response_len;
469 SSL_get0_ocsp_response(ssl(), &ocsp_response_raw, &ocsp_response_len);
470 std::string ocsp_response(reinterpret_cast<const char*>(ocsp_response_raw),
471 ocsp_response_len);
472 const uint8_t* sct_list_raw;
473 size_t sct_list_len;
474 SSL_get0_signed_cert_timestamp_list(ssl(), &sct_list_raw, &sct_list_len);
475 std::string sct_list(reinterpret_cast<const char*>(sct_list_raw),
476 sct_list_len);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500477
478 ProofVerifierCallbackImpl* proof_verify_callback =
479 new ProofVerifierCallbackImpl(this);
480
481 QuicAsyncStatus verify_result = proof_verifier_->VerifyCertChain(
QUICHE team38c190b2019-05-08 09:12:01 -0700482 server_id_.host(), certs, ocsp_response, sct_list, verify_context_.get(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500483 &cert_verify_error_details_, &verify_details_,
484 std::unique_ptr<ProofVerifierCallback>(proof_verify_callback));
485 switch (verify_result) {
486 case QUIC_SUCCESS:
nharper9b3cba42020-04-16 08:17:20 -0700487 if (verify_details_) {
488 proof_handler_->OnProofVerifyDetailsAvailable(*verify_details_);
489 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 return ssl_verify_ok;
491 case QUIC_PENDING:
492 proof_verify_callback_ = proof_verify_callback;
493 state_ = STATE_CERT_VERIFY_PENDING;
494 return ssl_verify_retry;
495 case QUIC_FAILURE:
496 default:
497 QUIC_LOG(INFO) << "Cert chain verification failed: "
498 << cert_verify_error_details_;
499 return ssl_verify_invalid;
500 }
501}
502
nharperdf7a77b2019-11-11 13:12:45 -0800503void TlsClientHandshaker::InsertSession(bssl::UniquePtr<SSL_SESSION> session) {
renjietangbcc066a2020-04-21 18:05:57 -0700504 if (!received_transport_params_) {
505 QUIC_BUG << "Transport parameters isn't received";
506 return;
507 }
nharperdf7a77b2019-11-11 13:12:45 -0800508 if (session_cache_ == nullptr) {
509 QUIC_DVLOG(1) << "No session cache, not inserting a session";
510 return;
511 }
renjietangbcc066a2020-04-21 18:05:57 -0700512 if (has_application_state_ && !received_application_state_) {
513 // Application state is not received yet. cache the sessions.
514 if (cached_tls_sessions_[0] != nullptr) {
515 cached_tls_sessions_[1] = std::move(cached_tls_sessions_[0]);
516 }
517 cached_tls_sessions_[0] = std::move(session);
518 return;
519 }
520 session_cache_->Insert(server_id_, std::move(session),
renjietangb5c69352020-04-22 17:56:04 -0700521 *received_transport_params_,
renjietangbcc066a2020-04-21 18:05:57 -0700522 received_application_state_.get());
nharperdf7a77b2019-11-11 13:12:45 -0800523}
524
fayangd58736d2019-11-27 13:35:31 -0800525void TlsClientHandshaker::WriteMessage(EncryptionLevel level,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800526 quiche::QuicheStringPiece data) {
fayangd58736d2019-11-27 13:35:31 -0800527 if (level == ENCRYPTION_HANDSHAKE &&
528 state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
529 state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_SENT;
fayangd58736d2019-11-27 13:35:31 -0800530 }
531 TlsHandshaker::WriteMessage(level, data);
532}
533
renjietangf21e3852020-04-13 15:45:39 -0700534void TlsClientHandshaker::OnApplicationState(
535 std::unique_ptr<ApplicationState> application_state) {
536 received_application_state_ = std::move(application_state);
renjietangbcc066a2020-04-21 18:05:57 -0700537 // At least one tls session is cached before application state is received. So
538 // insert now.
539 if (session_cache_ != nullptr && cached_tls_sessions_[0] != nullptr) {
540 if (cached_tls_sessions_[1] != nullptr) {
541 // Insert the older session first.
542 session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[1]),
renjietangb5c69352020-04-22 17:56:04 -0700543 *received_transport_params_,
renjietangbcc066a2020-04-21 18:05:57 -0700544 received_application_state_.get());
545 }
546 session_cache_->Insert(server_id_, std::move(cached_tls_sessions_[0]),
renjietangb5c69352020-04-22 17:56:04 -0700547 *received_transport_params_,
renjietang28e3a762020-04-16 12:16:17 -0700548 received_application_state_.get());
549 }
renjietangf21e3852020-04-13 15:45:39 -0700550}
551
QUICHE teama6ef0a62019-03-07 20:34:33 -0500552} // namespace quic