blob: 46e4b81704f9881b55da98d6805dee31b02d3b93 [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_server_handshaker.h"
6
7#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "third_party/boringssl/src/include/openssl/pool.h"
11#include "third_party/boringssl/src/include/openssl/ssl.h"
12#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
13#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
nharper0f51d2e2019-12-11 17:52:05 -080014#include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
nharpera60a2552020-05-28 15:32:44 -070016#include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080017#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
nharperac52a862020-06-08 12:41:06 -070018#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21
22TlsServerHandshaker::SignatureCallback::SignatureCallback(
23 TlsServerHandshaker* handshaker)
24 : handshaker_(handshaker) {}
25
nharper35d60192020-03-26 12:15:47 -070026void TlsServerHandshaker::SignatureCallback::Run(
27 bool ok,
28 std::string signature,
29 std::unique_ptr<ProofSource::Details> details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050030 if (handshaker_ == nullptr) {
31 return;
32 }
33 if (ok) {
34 handshaker_->cert_verify_sig_ = std::move(signature);
nharper35d60192020-03-26 12:15:47 -070035 handshaker_->proof_source_details_ = std::move(details);
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 }
37 State last_state = handshaker_->state_;
38 handshaker_->state_ = STATE_SIGNATURE_COMPLETE;
39 handshaker_->signature_callback_ = nullptr;
40 if (last_state == STATE_SIGNATURE_PENDING) {
41 handshaker_->AdvanceHandshake();
42 }
43}
44
45void TlsServerHandshaker::SignatureCallback::Cancel() {
46 handshaker_ = nullptr;
47}
48
nharperfbaacc02020-04-24 17:30:22 -070049TlsServerHandshaker::DecryptCallback::DecryptCallback(
50 TlsServerHandshaker* handshaker)
51 : handshaker_(handshaker) {}
52
53void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
54 if (handshaker_ == nullptr) {
55 // The callback was cancelled before we could run.
56 return;
57 }
58 handshaker_->decrypted_session_ticket_ = std::move(plaintext);
59 // DecryptCallback::Run could be called synchronously. When that happens, we
60 // are currently in the middle of a call to AdvanceHandshake.
61 // (AdvanceHandshake called SSL_do_handshake, which through some layers called
62 // SessionTicketOpen, which called TicketCrypter::Decrypt, which synchronously
63 // called this function.) In that case, the handshake will continue to be
64 // processed when this function returns.
65 //
66 // When this callback is called asynchronously (i.e. the ticket decryption is
67 // pending), TlsServerHandshaker is not actively processing handshake
68 // messages. We need to have it resume processing handshake messages by
69 // calling AdvanceHandshake.
70 if (handshaker_->state_ == STATE_TICKET_DECRYPTION_PENDING) {
71 handshaker_->AdvanceHandshake();
72 }
73 // The TicketDecrypter took ownership of this callback when Decrypt was
74 // called. Once the callback returns, it will be deleted. Remove the
75 // (non-owning) pointer to the callback from the handshaker so the handshaker
76 // doesn't have an invalid pointer hanging around.
77 handshaker_->ticket_decryption_callback_ = nullptr;
78}
79
80void TlsServerHandshaker::DecryptCallback::Cancel() {
81 DCHECK(handshaker_);
82 handshaker_ = nullptr;
83}
84
dschinaziaaaf1a42020-04-16 11:44:31 -070085TlsServerHandshaker::TlsServerHandshaker(
86 QuicSession* session,
87 const QuicCryptoServerConfig& crypto_config)
nharperf579b5e2020-01-21 14:11:18 -080088 : TlsHandshaker(this, session),
89 QuicCryptoServerStreamBase(session),
dschinaziaaaf1a42020-04-16 11:44:31 -070090 proof_source_(crypto_config.proof_source()),
91 pre_shared_key_(crypto_config.pre_shared_key()),
nharper6ebe83b2019-06-13 17:43:52 -070092 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
dschinaziaaaf1a42020-04-16 11:44:31 -070093 tls_connection_(crypto_config.ssl_ctx(), this) {
zhongyi546cc452019-04-12 15:27:49 -070094 DCHECK_EQ(PROTOCOL_TLS1_3,
95 session->connection()->version().handshake_protocol);
QUICHE teama6ef0a62019-03-07 20:34:33 -050096
97 // Configure the SSL to be a server.
98 SSL_set_accept_state(ssl());
QUICHE teama6ef0a62019-03-07 20:34:33 -050099}
100
101TlsServerHandshaker::~TlsServerHandshaker() {
102 CancelOutstandingCallbacks();
103}
104
105void TlsServerHandshaker::CancelOutstandingCallbacks() {
106 if (signature_callback_) {
107 signature_callback_->Cancel();
108 signature_callback_ = nullptr;
109 }
nharperfbaacc02020-04-24 17:30:22 -0700110 if (ticket_decryption_callback_) {
111 ticket_decryption_callback_->Cancel();
112 ticket_decryption_callback_ = nullptr;
113 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114}
115
116bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
dschinazi17d42422019-06-18 16:35:07 -0700117 std::string* /*output*/) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500118 // Channel ID is not supported when TLS is used in QUIC.
119 return false;
120}
121
122void TlsServerHandshaker::SendServerConfigUpdate(
dschinazi17d42422019-06-18 16:35:07 -0700123 const CachedNetworkParameters* /*cached_network_params*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500124 // SCUP messages aren't supported when using the TLS handshake.
125}
126
fayang6098a0a2020-03-13 15:32:10 -0700127bool TlsServerHandshaker::IsZeroRtt() const {
nharperac52a862020-06-08 12:41:06 -0700128 return SSL_early_data_accepted(ssl());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129}
130
nharperfd0e2632020-06-02 11:19:05 -0700131bool TlsServerHandshaker::IsResumption() const {
132 return SSL_session_reused(ssl());
133}
134
135bool TlsServerHandshaker::ResumptionAttempted() const {
136 return ticket_received_;
137}
138
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
140 // SCUP messages aren't supported when using the TLS handshake.
141 return 0;
142}
143
144const CachedNetworkParameters*
145TlsServerHandshaker::PreviousCachedNetworkParams() const {
146 return nullptr;
147}
148
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149void TlsServerHandshaker::SetPreviousCachedNetworkParams(
dschinazi17d42422019-06-18 16:35:07 -0700150 CachedNetworkParameters /*cached_network_params*/) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500151
fayangd58736d2019-11-27 13:35:31 -0800152void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
153 if (level == ENCRYPTION_HANDSHAKE &&
154 state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) {
155 state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED;
renjietangbd33b622020-02-12 16:52:30 -0800156 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
157 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
fayangd58736d2019-11-27 13:35:31 -0800158 }
159}
160
fayang01062942020-01-22 07:23:23 -0800161void TlsServerHandshaker::OnHandshakeDoneReceived() {
162 DCHECK(false);
163}
164
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
166 return false;
167}
168
nharper9b0a1af2020-08-07 17:11:29 -0700169const ProofSource::Details* TlsServerHandshaker::ProofSourceDetails() const {
170 return proof_source_details_.get();
171}
172
fayanga6a85a82020-05-04 08:58:53 -0700173void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
174 ConnectionCloseSource /*source*/) {
175 state_ = STATE_CONNECTION_CLOSED;
176}
177
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178bool TlsServerHandshaker::encryption_established() const {
179 return encryption_established_;
180}
181
fayang685367a2020-01-14 10:40:15 -0800182bool TlsServerHandshaker::one_rtt_keys_available() const {
183 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184}
185
186const QuicCryptoNegotiatedParameters&
187TlsServerHandshaker::crypto_negotiated_params() const {
188 return *crypto_negotiated_params_;
189}
190
191CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
192 return TlsHandshaker::crypto_message_parser();
193}
194
fayang9a863cf2020-01-16 14:12:11 -0800195HandshakeState TlsServerHandshaker::GetHandshakeState() const {
196 if (one_rtt_keys_available_) {
fayang01062942020-01-22 07:23:23 -0800197 return HANDSHAKE_CONFIRMED;
fayang9a863cf2020-01-16 14:12:11 -0800198 }
199 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) {
200 return HANDSHAKE_PROCESSED;
201 }
202 return HANDSHAKE_START;
203}
204
nharperac52a862020-06-08 12:41:06 -0700205void TlsServerHandshaker::SetServerApplicationStateForResumption(
206 std::unique_ptr<ApplicationState> state) {
207 application_state_ = std::move(state);
208}
209
nharper486a8a92019-08-28 16:25:10 -0700210size_t TlsServerHandshaker::BufferSizeLimitForLevel(
211 EncryptionLevel level) const {
212 return TlsHandshaker::BufferSizeLimitForLevel(level);
213}
214
nharper54492982020-03-19 14:32:52 -0700215void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
216
QUICHE teama6ef0a62019-03-07 20:34:33 -0500217void TlsServerHandshaker::AdvanceHandshake() {
218 if (state_ == STATE_CONNECTION_CLOSED) {
219 QUIC_LOG(INFO) << "TlsServerHandshaker received handshake message after "
220 "connection was closed";
221 return;
222 }
223 if (state_ == STATE_HANDSHAKE_COMPLETE) {
224 // TODO(nharper): Handle post-handshake messages.
225 return;
226 }
227
228 int rv = SSL_do_handshake(ssl());
229 if (rv == 1) {
230 FinishHandshake();
231 return;
232 }
233
234 int ssl_error = SSL_get_error(ssl(), rv);
235 bool should_close = true;
236 switch (state_) {
237 case STATE_LISTENING:
238 case STATE_SIGNATURE_COMPLETE:
239 should_close = ssl_error != SSL_ERROR_WANT_READ;
240 break;
241 case STATE_SIGNATURE_PENDING:
242 should_close = ssl_error != SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
243 break;
nharperfbaacc02020-04-24 17:30:22 -0700244 case STATE_TICKET_DECRYPTION_PENDING:
245 should_close = ssl_error != SSL_ERROR_PENDING_TICKET;
246 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500247 default:
248 should_close = true;
249 }
250 if (should_close && state_ != STATE_CONNECTION_CLOSED) {
QUICHE team600f5212020-06-17 15:49:33 -0700251 QUIC_VLOG(1) << "SSL_do_handshake failed; SSL_get_error returns "
252 << ssl_error << ", state_ = " << state_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 ERR_print_errors_fp(stderr);
dschinazi91453642019-08-01 11:12:15 -0700254 CloseConnection(QUIC_HANDSHAKE_FAILED,
255 "Server observed TLS handshake failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500256 }
257}
258
259void TlsServerHandshaker::CloseConnection(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700260 const std::string& reason_phrase) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261 state_ = STATE_CONNECTION_CLOSED;
renjietang87df0d02020-02-13 11:53:52 -0800262 stream()->OnUnrecoverableError(error, reason_phrase);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500263}
264
265bool TlsServerHandshaker::ProcessTransportParameters(
vasilvvc48c8712019-03-11 13:38:16 -0700266 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 TransportParameters client_params;
268 const uint8_t* client_params_bytes;
269 size_t params_bytes_len;
270 SSL_get_peer_quic_transport_params(ssl(), &client_params_bytes,
271 &params_bytes_len);
dschinazi7b8f0c72020-03-02 13:17:57 -0800272 if (params_bytes_len == 0) {
273 *error_details = "Client's transport parameters are missing";
274 return false;
275 }
276 std::string parse_error_details;
277 if (!ParseTransportParameters(session()->connection()->version(),
dschinazi6c84c142019-07-31 09:11:49 -0700278 Perspective::IS_CLIENT, client_params_bytes,
dschinazi7b8f0c72020-03-02 13:17:57 -0800279 params_bytes_len, &client_params,
280 &parse_error_details)) {
281 DCHECK(!parse_error_details.empty());
282 *error_details =
283 "Unable to parse client's transport parameters: " + parse_error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 return false;
285 }
dschinazi6cf4d2a2019-04-30 16:20:23 -0700286
dschinazi631f1602020-05-19 10:10:22 -0700287 // Notify QuicConnectionDebugVisitor.
288 session()->connection()->OnTransportParametersReceived(client_params);
289
dschinazi6cf4d2a2019-04-30 16:20:23 -0700290 // When interoperating with non-Google implementations that do not send
291 // the version extension, set it to what we expect.
292 if (client_params.version == 0) {
293 client_params.version =
294 CreateQuicVersionLabel(session()->connection()->version());
295 }
296
QUICHE teama6ef0a62019-03-07 20:34:33 -0500297 if (CryptoUtils::ValidateClientHelloVersion(
298 client_params.version, session()->connection()->version(),
299 session()->supported_versions(), error_details) != QUIC_NO_ERROR ||
dschinazi2c4d8332020-05-27 17:23:32 -0700300 handshaker_delegate()->ProcessTransportParameters(
301 client_params, /* is_resumption = */ false, error_details) !=
renjietangc31106b2020-05-06 10:44:17 -0700302 QUIC_NO_ERROR) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500303 return false;
304 }
nharper3ee44722020-03-17 11:13:28 -0700305 ProcessAdditionalTransportParameters(client_params);
dschinazi52c8f332020-08-17 13:30:01 -0700306 if (!session()->user_agent_id().has_value() &&
307 client_params.user_agent_id.has_value()) {
308 session()->SetUserAgentId(client_params.user_agent_id.value());
wubbe634b72020-06-16 08:41:26 -0700309 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310
QUICHE teama6ef0a62019-03-07 20:34:33 -0500311 return true;
312}
313
314bool TlsServerHandshaker::SetTransportParameters() {
315 TransportParameters server_params;
316 server_params.perspective = Perspective::IS_SERVER;
317 server_params.supported_versions =
318 CreateQuicVersionLabelVector(session()->supported_versions());
319 server_params.version =
320 CreateQuicVersionLabel(session()->connection()->version());
321
dschinazi2c4d8332020-05-27 17:23:32 -0700322 if (!handshaker_delegate()->FillTransportParameters(&server_params)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500323 return false;
324 }
325
dschinazi631f1602020-05-19 10:10:22 -0700326 // Notify QuicConnectionDebugVisitor.
327 session()->connection()->OnTransportParametersSent(server_params);
328
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 std::vector<uint8_t> server_params_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700330 if (!SerializeTransportParameters(session()->connection()->version(),
331 server_params, &server_params_bytes) ||
QUICHE teama6ef0a62019-03-07 20:34:33 -0500332 SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
333 server_params_bytes.size()) != 1) {
334 return false;
335 }
nharperac52a862020-06-08 12:41:06 -0700336 if (application_state_) {
337 std::vector<uint8_t> early_data_context;
338 if (!SerializeTransportParametersForTicket(
339 server_params, *application_state_, &early_data_context)) {
340 QUIC_BUG << "Failed to serialize Transport Parameters for ticket.";
341 return false;
342 }
343 SSL_set_quic_early_data_context(ssl(), early_data_context.data(),
344 early_data_context.size());
345 application_state_.reset(nullptr);
346 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500347 return true;
348}
349
fayanga45ee8a2020-03-20 08:56:11 -0700350void TlsServerHandshaker::SetWriteSecret(
351 EncryptionLevel level,
352 const SSL_CIPHER* cipher,
353 const std::vector<uint8_t>& write_secret) {
fayang6cccce42020-06-08 08:37:31 -0700354 if (state_ == STATE_CONNECTION_CLOSED) {
fayanga6a85a82020-05-04 08:58:53 -0700355 return;
356 }
fayangb5e1d5b2020-04-29 11:00:38 -0700357 if (level == ENCRYPTION_FORWARD_SECURE) {
fayanga45ee8a2020-03-20 08:56:11 -0700358 encryption_established_ = true;
359 // Fill crypto_negotiated_params_:
360 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
361 if (cipher) {
362 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
363 }
364 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
365 }
366 TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
367}
368
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369void TlsServerHandshaker::FinishHandshake() {
nharperd25cd652020-05-20 13:10:26 -0700370 if (SSL_in_early_data(ssl())) {
371 // If the server accepts early data, SSL_do_handshake returns success twice:
372 // once after processing the ClientHello and sending the server's first
373 // flight, and then again after the handshake is complete. This results in
374 // FinishHandshake getting called twice. On the first call to
375 // FinishHandshake, we don't have any confirmation that the client is live,
376 // so all end of handshake processing is deferred until the handshake is
377 // actually complete.
renjietangeccd8cc2020-07-29 14:31:17 -0700378 QUIC_RESTART_FLAG_COUNT(quic_enable_zero_rtt_for_tls_v2);
nharperd25cd652020-05-20 13:10:26 -0700379 return;
380 }
dschinazi91453642019-08-01 11:12:15 -0700381 if (!valid_alpn_received_) {
382 QUIC_DLOG(ERROR)
383 << "Server: handshake finished without receiving a known ALPN";
384 // TODO(b/130164908) this should send no_application_protocol
385 // instead of QUIC_HANDSHAKE_FAILED.
386 CloseConnection(QUIC_HANDSHAKE_FAILED,
387 "Server did not receive a known ALPN");
388 return;
389 }
390
QUICHE teamdc339762020-08-04 16:01:05 -0700391 QUIC_DLOG(INFO) << "Server: handshake finished";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500392 state_ = STATE_HANDSHAKE_COMPLETE;
fayang685367a2020-01-14 10:40:15 -0800393 one_rtt_keys_available_ = true;
nharper8f759922019-10-09 11:08:36 -0700394
renjietangc50cc4a2020-08-17 18:33:30 -0700395 handshaker_delegate()->OnTlsHandshakeComplete();
renjietangbd33b622020-02-12 16:52:30 -0800396 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
397 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
nharper0b8f0ca2020-06-05 12:34:18 -0700398 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_ZERO_RTT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500399}
400
QUICHE teama6ef0a62019-03-07 20:34:33 -0500401ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
402 uint8_t* out,
403 size_t* out_len,
404 size_t max_out,
405 uint16_t sig_alg,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800406 quiche::QuicheStringPiece in) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500407 signature_callback_ = new SignatureCallback(this);
408 proof_source_->ComputeTlsSignature(
danzhd1fc5912020-05-01 15:29:04 -0700409 session()->connection()->self_address(),
410 session()->connection()->peer_address(), hostname_, sig_alg, in,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 std::unique_ptr<SignatureCallback>(signature_callback_));
412 if (state_ == STATE_SIGNATURE_COMPLETE) {
413 return PrivateKeyComplete(out, out_len, max_out);
414 }
415 state_ = STATE_SIGNATURE_PENDING;
416 return ssl_private_key_retry;
417}
418
QUICHE teama6ef0a62019-03-07 20:34:33 -0500419ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
420 uint8_t* out,
421 size_t* out_len,
422 size_t max_out) {
423 if (state_ == STATE_SIGNATURE_PENDING) {
424 return ssl_private_key_retry;
425 }
426 if (cert_verify_sig_.size() > max_out || cert_verify_sig_.empty()) {
427 return ssl_private_key_failure;
428 }
429 *out_len = cert_verify_sig_.size();
430 memcpy(out, cert_verify_sig_.data(), *out_len);
431 cert_verify_sig_.clear();
432 cert_verify_sig_.shrink_to_fit();
433 return ssl_private_key_success;
434}
435
nharperfbaacc02020-04-24 17:30:22 -0700436size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
nharper1f8289a2020-04-27 11:57:28 -0700437 DCHECK(proof_source_->GetTicketCrypter());
438 return proof_source_->GetTicketCrypter()->MaxOverhead();
nharperfbaacc02020-04-24 17:30:22 -0700439}
440
441int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
442 size_t* out_len,
443 size_t max_out_len,
444 quiche::QuicheStringPiece in) {
nharpereede82b2020-07-23 17:21:24 -0700445 QUIC_CODE_COUNT(quic_tls_ticket_seal);
nharper1f8289a2020-04-27 11:57:28 -0700446 DCHECK(proof_source_->GetTicketCrypter());
447 std::vector<uint8_t> ticket = proof_source_->GetTicketCrypter()->Encrypt(in);
nharperfbaacc02020-04-24 17:30:22 -0700448 if (max_out_len < ticket.size()) {
449 QUIC_BUG
nharper1f8289a2020-04-27 11:57:28 -0700450 << "TicketCrypter returned " << ticket.size()
nharperfbaacc02020-04-24 17:30:22 -0700451 << " bytes of ciphertext, which is larger than its max overhead of "
452 << max_out_len;
453 return 0; // failure
454 }
455 *out_len = ticket.size();
456 memcpy(out, ticket.data(), ticket.size());
457 return 1; // success
458}
459
460ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
461 uint8_t* out,
462 size_t* out_len,
463 size_t max_out_len,
464 quiche::QuicheStringPiece in) {
nharpereede82b2020-07-23 17:21:24 -0700465 QUIC_CODE_COUNT(quic_tls_ticket_open);
nharper1f8289a2020-04-27 11:57:28 -0700466 DCHECK(proof_source_->GetTicketCrypter());
nharperfbaacc02020-04-24 17:30:22 -0700467
468 if (!ticket_decryption_callback_) {
nharperfd0e2632020-06-02 11:19:05 -0700469 ticket_received_ = true;
nharperfbaacc02020-04-24 17:30:22 -0700470 ticket_decryption_callback_ = new DecryptCallback(this);
nharper1f8289a2020-04-27 11:57:28 -0700471 proof_source_->GetTicketCrypter()->Decrypt(
nharperfbaacc02020-04-24 17:30:22 -0700472 in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
473 // Decrypt can run the callback synchronously. In that case, the callback
474 // will clear the ticket_decryption_callback_ pointer, and instead of
475 // returning ssl_ticket_aead_retry, we should continue processing to return
476 // the decrypted ticket.
477 //
478 // If the callback is not run asynchronously, return ssl_ticket_aead_retry
479 // and when the callback is complete this function will be run again to
480 // return the result.
481 if (ticket_decryption_callback_) {
482 state_ = STATE_TICKET_DECRYPTION_PENDING;
483 return ssl_ticket_aead_retry;
484 }
485 }
486 ticket_decryption_callback_ = nullptr;
487 state_ = STATE_LISTENING;
488 if (decrypted_session_ticket_.empty()) {
489 QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
490 // Ticket decryption failed. Ignore the ticket.
491 return ssl_ticket_aead_ignore_ticket;
492 }
493 if (max_out_len < decrypted_session_ticket_.size()) {
494 return ssl_ticket_aead_error;
495 }
496 memcpy(out, decrypted_session_ticket_.data(),
497 decrypted_session_ticket_.size());
498 *out_len = decrypted_session_ticket_.size();
nharperf238f602020-08-04 18:49:13 -0700499 QUIC_RESTART_FLAG_COUNT(quic_enable_tls_resumption_v4);
nharperfbaacc02020-04-24 17:30:22 -0700500
501 return ssl_ticket_aead_success;
502}
503
QUICHE teama6ef0a62019-03-07 20:34:33 -0500504int TlsServerHandshaker::SelectCertificate(int* out_alert) {
505 const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
506 if (hostname) {
507 hostname_ = hostname;
nharper0f51d2e2019-12-11 17:52:05 -0800508 crypto_negotiated_params_->sni =
509 QuicHostnameUtils::NormalizeHostname(hostname_);
nharper6043dd62020-06-29 13:36:53 -0700510 if (!QuicHostnameUtils::IsValidSNI(hostname_)) {
511 // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
512 // frame.
513 QUIC_LOG(ERROR) << "Invalid SNI provided: \"" << hostname_ << "\"";
514 return SSL_TLSEXT_ERR_ALERT_FATAL;
nharpere0f979c2020-05-05 17:31:55 -0700515 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500516 } else {
517 QUIC_LOG(INFO) << "No hostname indicated in SNI";
518 }
519
520 QuicReferenceCountedPointer<ProofSource::Chain> chain =
521 proof_source_->GetCertChain(session()->connection()->self_address(),
danzhd1fc5912020-05-01 15:29:04 -0700522 session()->connection()->peer_address(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500523 hostname_);
nharper3a364d82020-05-07 13:31:27 -0700524 if (!chain || chain->certs.empty()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500525 QUIC_LOG(ERROR) << "No certs provided for host '" << hostname_ << "'";
526 return SSL_TLSEXT_ERR_ALERT_FATAL;
527 }
528
dschinaziaaaf1a42020-04-16 11:44:31 -0700529 if (!pre_shared_key_.empty()) {
530 // TODO(b/154162689) add PSK support to QUIC+TLS.
531 QUIC_BUG << "QUIC server pre-shared keys not yet supported with TLS";
532 return SSL_TLSEXT_ERR_ALERT_FATAL;
533 }
534
QUICHE teama6ef0a62019-03-07 20:34:33 -0500535 std::vector<CRYPTO_BUFFER*> certs;
536 certs.resize(chain->certs.size());
537 for (size_t i = 0; i < certs.size(); i++) {
538 certs[i] = CRYPTO_BUFFER_new(
539 reinterpret_cast<const uint8_t*>(chain->certs[i].data()),
540 chain->certs[i].length(), nullptr);
541 }
542
nharper6ebe83b2019-06-13 17:43:52 -0700543 tls_connection_.SetCertChain(certs);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500544
545 for (size_t i = 0; i < certs.size(); i++) {
546 CRYPTO_BUFFER_free(certs[i]);
547 }
548
vasilvvc48c8712019-03-11 13:38:16 -0700549 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500550 if (!ProcessTransportParameters(&error_details)) {
551 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
552 *out_alert = SSL_AD_INTERNAL_ERROR;
553 return SSL_TLSEXT_ERR_ALERT_FATAL;
554 }
nharper54492982020-03-19 14:32:52 -0700555 OverrideQuicConfigDefaults(session()->config());
fayang07573532020-04-06 13:20:17 -0700556 session()->OnConfigNegotiated();
557
nharper54492982020-03-19 14:32:52 -0700558 if (!SetTransportParameters()) {
559 QUIC_LOG(ERROR) << "Failed to set transport parameters";
560 return SSL_TLSEXT_ERR_ALERT_FATAL;
561 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500562
QUICHE teamdc339762020-08-04 16:01:05 -0700563 QUIC_DLOG(INFO) << "Set " << chain->certs.size() << " certs for server "
564 << "with hostname " << hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500565 return SSL_TLSEXT_ERR_OK;
566}
567
dschinazi35e749e2019-04-09 09:36:04 -0700568int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
569 uint8_t* out_len,
570 const uint8_t* in,
571 unsigned in_len) {
572 // |in| contains a sequence of 1-byte-length-prefixed values.
dschinazi91453642019-08-01 11:12:15 -0700573 *out_len = 0;
574 *out = nullptr;
dschinazi35e749e2019-04-09 09:36:04 -0700575 if (in_len == 0) {
dschinazi91453642019-08-01 11:12:15 -0700576 QUIC_DLOG(ERROR) << "No ALPN provided by client";
577 return SSL_TLSEXT_ERR_NOACK;
dschinazi35e749e2019-04-09 09:36:04 -0700578 }
dschinazi91453642019-08-01 11:12:15 -0700579
dschinazi91453642019-08-01 11:12:15 -0700580 CBS all_alpns;
581 CBS_init(&all_alpns, in, in_len);
582
dmcardlecf0bfcf2019-12-13 08:08:21 -0800583 std::vector<quiche::QuicheStringPiece> alpns;
dschinazi91453642019-08-01 11:12:15 -0700584 while (CBS_len(&all_alpns) > 0) {
585 CBS alpn;
586 if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
587 QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
588 return SSL_TLSEXT_ERR_NOACK;
589 }
vasilvvad7424f2019-08-30 00:27:14 -0700590
dschinazi91453642019-08-01 11:12:15 -0700591 const size_t alpn_length = CBS_len(&alpn);
dschinazi91453642019-08-01 11:12:15 -0700592 if (alpn_length == 0) {
593 QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
594 return SSL_TLSEXT_ERR_NOACK;
595 }
vasilvvad7424f2019-08-30 00:27:14 -0700596
597 alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
598 alpn_length);
dschinazi35e749e2019-04-09 09:36:04 -0700599 }
dschinazi91453642019-08-01 11:12:15 -0700600
vasilvvad7424f2019-08-30 00:27:14 -0700601 auto selected_alpn = session()->SelectAlpn(alpns);
602 if (selected_alpn == alpns.end()) {
603 QUIC_DLOG(ERROR) << "No known ALPN provided by client";
604 return SSL_TLSEXT_ERR_NOACK;
605 }
606
607 session()->OnAlpnSelected(*selected_alpn);
608 valid_alpn_received_ = true;
609 *out_len = selected_alpn->size();
610 *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
611 return SSL_TLSEXT_ERR_OK;
dschinazi35e749e2019-04-09 09:36:04 -0700612}
613
QUICHE teama6ef0a62019-03-07 20:34:33 -0500614} // namespace quic