blob: 99333a600f495bdee7585df73160f2383ea87c14 [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"
dmcardlecf0bfcf2019-12-13 08:08:21 -080016#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050017
18namespace quic {
19
20TlsServerHandshaker::SignatureCallback::SignatureCallback(
21 TlsServerHandshaker* handshaker)
22 : handshaker_(handshaker) {}
23
nharper35d60192020-03-26 12:15:47 -070024void TlsServerHandshaker::SignatureCallback::Run(
25 bool ok,
26 std::string signature,
27 std::unique_ptr<ProofSource::Details> details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050028 if (handshaker_ == nullptr) {
29 return;
30 }
31 if (ok) {
32 handshaker_->cert_verify_sig_ = std::move(signature);
nharper35d60192020-03-26 12:15:47 -070033 handshaker_->proof_source_details_ = std::move(details);
QUICHE teama6ef0a62019-03-07 20:34:33 -050034 }
35 State last_state = handshaker_->state_;
36 handshaker_->state_ = STATE_SIGNATURE_COMPLETE;
37 handshaker_->signature_callback_ = nullptr;
38 if (last_state == STATE_SIGNATURE_PENDING) {
39 handshaker_->AdvanceHandshake();
40 }
41}
42
43void TlsServerHandshaker::SignatureCallback::Cancel() {
44 handshaker_ = nullptr;
45}
46
nharperfbaacc02020-04-24 17:30:22 -070047TlsServerHandshaker::DecryptCallback::DecryptCallback(
48 TlsServerHandshaker* handshaker)
49 : handshaker_(handshaker) {}
50
51void TlsServerHandshaker::DecryptCallback::Run(std::vector<uint8_t> plaintext) {
52 if (handshaker_ == nullptr) {
53 // The callback was cancelled before we could run.
54 return;
55 }
56 handshaker_->decrypted_session_ticket_ = std::move(plaintext);
57 // DecryptCallback::Run could be called synchronously. When that happens, we
58 // are currently in the middle of a call to AdvanceHandshake.
59 // (AdvanceHandshake called SSL_do_handshake, which through some layers called
60 // SessionTicketOpen, which called TicketCrypter::Decrypt, which synchronously
61 // called this function.) In that case, the handshake will continue to be
62 // processed when this function returns.
63 //
64 // When this callback is called asynchronously (i.e. the ticket decryption is
65 // pending), TlsServerHandshaker is not actively processing handshake
66 // messages. We need to have it resume processing handshake messages by
67 // calling AdvanceHandshake.
68 if (handshaker_->state_ == STATE_TICKET_DECRYPTION_PENDING) {
69 handshaker_->AdvanceHandshake();
70 }
71 // The TicketDecrypter took ownership of this callback when Decrypt was
72 // called. Once the callback returns, it will be deleted. Remove the
73 // (non-owning) pointer to the callback from the handshaker so the handshaker
74 // doesn't have an invalid pointer hanging around.
75 handshaker_->ticket_decryption_callback_ = nullptr;
76}
77
78void TlsServerHandshaker::DecryptCallback::Cancel() {
79 DCHECK(handshaker_);
80 handshaker_ = nullptr;
81}
82
dschinaziaaaf1a42020-04-16 11:44:31 -070083TlsServerHandshaker::TlsServerHandshaker(
84 QuicSession* session,
85 const QuicCryptoServerConfig& crypto_config)
nharperf579b5e2020-01-21 14:11:18 -080086 : TlsHandshaker(this, session),
87 QuicCryptoServerStreamBase(session),
dschinaziaaaf1a42020-04-16 11:44:31 -070088 proof_source_(crypto_config.proof_source()),
89 pre_shared_key_(crypto_config.pre_shared_key()),
nharper6ebe83b2019-06-13 17:43:52 -070090 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters),
dschinaziaaaf1a42020-04-16 11:44:31 -070091 tls_connection_(crypto_config.ssl_ctx(), this) {
zhongyi546cc452019-04-12 15:27:49 -070092 DCHECK_EQ(PROTOCOL_TLS1_3,
93 session->connection()->version().handshake_protocol);
QUICHE teama6ef0a62019-03-07 20:34:33 -050094
95 // Configure the SSL to be a server.
96 SSL_set_accept_state(ssl());
QUICHE teama6ef0a62019-03-07 20:34:33 -050097}
98
99TlsServerHandshaker::~TlsServerHandshaker() {
100 CancelOutstandingCallbacks();
101}
102
103void TlsServerHandshaker::CancelOutstandingCallbacks() {
104 if (signature_callback_) {
105 signature_callback_->Cancel();
106 signature_callback_ = nullptr;
107 }
nharperfbaacc02020-04-24 17:30:22 -0700108 if (ticket_decryption_callback_) {
109 ticket_decryption_callback_->Cancel();
110 ticket_decryption_callback_ = nullptr;
111 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112}
113
114bool TlsServerHandshaker::GetBase64SHA256ClientChannelID(
dschinazi17d42422019-06-18 16:35:07 -0700115 std::string* /*output*/) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116 // Channel ID is not supported when TLS is used in QUIC.
117 return false;
118}
119
120void TlsServerHandshaker::SendServerConfigUpdate(
dschinazi17d42422019-06-18 16:35:07 -0700121 const CachedNetworkParameters* /*cached_network_params*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 // SCUP messages aren't supported when using the TLS handshake.
123}
124
fayang6098a0a2020-03-13 15:32:10 -0700125bool TlsServerHandshaker::IsZeroRtt() const {
126 // TODO(nharper): Support 0-RTT with TLS 1.3 in QUIC.
127 return false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500128}
129
130int TlsServerHandshaker::NumServerConfigUpdateMessagesSent() const {
131 // SCUP messages aren't supported when using the TLS handshake.
132 return 0;
133}
134
135const CachedNetworkParameters*
136TlsServerHandshaker::PreviousCachedNetworkParams() const {
137 return nullptr;
138}
139
140bool TlsServerHandshaker::ZeroRttAttempted() const {
141 // TODO(nharper): Support 0-RTT with TLS 1.3 in QUIC.
142 return false;
143}
144
145void TlsServerHandshaker::SetPreviousCachedNetworkParams(
dschinazi17d42422019-06-18 16:35:07 -0700146 CachedNetworkParameters /*cached_network_params*/) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147
fayangd58736d2019-11-27 13:35:31 -0800148void TlsServerHandshaker::OnPacketDecrypted(EncryptionLevel level) {
149 if (level == ENCRYPTION_HANDSHAKE &&
150 state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) {
151 state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED;
renjietangbd33b622020-02-12 16:52:30 -0800152 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
153 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
fayangd58736d2019-11-27 13:35:31 -0800154 }
155}
156
fayang01062942020-01-22 07:23:23 -0800157void TlsServerHandshaker::OnHandshakeDoneReceived() {
158 DCHECK(false);
159}
160
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161bool TlsServerHandshaker::ShouldSendExpectCTHeader() const {
162 return false;
163}
164
fayanga6a85a82020-05-04 08:58:53 -0700165void TlsServerHandshaker::OnConnectionClosed(QuicErrorCode /*error*/,
166 ConnectionCloseSource /*source*/) {
167 state_ = STATE_CONNECTION_CLOSED;
168}
169
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170bool TlsServerHandshaker::encryption_established() const {
171 return encryption_established_;
172}
173
fayang685367a2020-01-14 10:40:15 -0800174bool TlsServerHandshaker::one_rtt_keys_available() const {
175 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176}
177
178const QuicCryptoNegotiatedParameters&
179TlsServerHandshaker::crypto_negotiated_params() const {
180 return *crypto_negotiated_params_;
181}
182
183CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
184 return TlsHandshaker::crypto_message_parser();
185}
186
fayang9a863cf2020-01-16 14:12:11 -0800187HandshakeState TlsServerHandshaker::GetHandshakeState() const {
188 if (one_rtt_keys_available_) {
fayang01062942020-01-22 07:23:23 -0800189 return HANDSHAKE_CONFIRMED;
fayang9a863cf2020-01-16 14:12:11 -0800190 }
191 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) {
192 return HANDSHAKE_PROCESSED;
193 }
194 return HANDSHAKE_START;
195}
196
nharper486a8a92019-08-28 16:25:10 -0700197size_t TlsServerHandshaker::BufferSizeLimitForLevel(
198 EncryptionLevel level) const {
199 return TlsHandshaker::BufferSizeLimitForLevel(level);
200}
201
nharper54492982020-03-19 14:32:52 -0700202void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
203
nharper8d4ff5c2020-02-27 11:43:44 -0800204bool TlsServerHandshaker::SetReadSecret(
205 EncryptionLevel level,
206 const SSL_CIPHER* cipher,
207 const std::vector<uint8_t>& read_secret) {
208 if (level != ENCRYPTION_FORWARD_SECURE || one_rtt_keys_available_) {
209 return TlsHandshaker::SetReadSecret(level, cipher, read_secret);
210 }
211 // Delay setting read secret for ENCRYPTION_FORWARD_SECURE until handshake
212 // completes.
213 app_data_read_secret_ = read_secret;
214 return true;
215}
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) {
251 QUIC_LOG(WARNING) << "SSL_do_handshake failed; SSL_get_error returns "
252 << ssl_error << ", state_ = " << state_;
253 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 ||
300 session()->config()->ProcessTransportParameters(
renjietangc31106b2020-05-06 10:44:17 -0700301 client_params, CLIENT, /* is_resumption = */ false, error_details) !=
302 QUIC_NO_ERROR) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500303 return false;
304 }
nharper3ee44722020-03-17 11:13:28 -0700305 ProcessAdditionalTransportParameters(client_params);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500306
QUICHE teama6ef0a62019-03-07 20:34:33 -0500307 return true;
308}
309
310bool TlsServerHandshaker::SetTransportParameters() {
311 TransportParameters server_params;
312 server_params.perspective = Perspective::IS_SERVER;
313 server_params.supported_versions =
314 CreateQuicVersionLabelVector(session()->supported_versions());
315 server_params.version =
316 CreateQuicVersionLabel(session()->connection()->version());
317
318 if (!session()->config()->FillTransportParameters(&server_params)) {
319 return false;
320 }
321
322 // TODO(nharper): Provide an actual value for the stateless reset token.
323 server_params.stateless_reset_token.resize(16);
dschinazi631f1602020-05-19 10:10:22 -0700324
325 // Notify QuicConnectionDebugVisitor.
326 session()->connection()->OnTransportParametersSent(server_params);
327
QUICHE teama6ef0a62019-03-07 20:34:33 -0500328 std::vector<uint8_t> server_params_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700329 if (!SerializeTransportParameters(session()->connection()->version(),
330 server_params, &server_params_bytes) ||
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331 SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
332 server_params_bytes.size()) != 1) {
333 return false;
334 }
335 return true;
336}
337
fayanga45ee8a2020-03-20 08:56:11 -0700338void TlsServerHandshaker::SetWriteSecret(
339 EncryptionLevel level,
340 const SSL_CIPHER* cipher,
341 const std::vector<uint8_t>& write_secret) {
fayanga6a85a82020-05-04 08:58:53 -0700342 if (GetQuicReloadableFlag(quic_notify_handshaker_on_connection_close) &&
343 state_ == STATE_CONNECTION_CLOSED) {
344 return;
345 }
fayangb5e1d5b2020-04-29 11:00:38 -0700346 if (level == ENCRYPTION_FORWARD_SECURE) {
fayanga45ee8a2020-03-20 08:56:11 -0700347 encryption_established_ = true;
348 // Fill crypto_negotiated_params_:
349 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
350 if (cipher) {
351 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
352 }
353 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
354 }
355 TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
356}
357
QUICHE teama6ef0a62019-03-07 20:34:33 -0500358void TlsServerHandshaker::FinishHandshake() {
dschinazi91453642019-08-01 11:12:15 -0700359 if (!valid_alpn_received_) {
360 QUIC_DLOG(ERROR)
361 << "Server: handshake finished without receiving a known ALPN";
362 // TODO(b/130164908) this should send no_application_protocol
363 // instead of QUIC_HANDSHAKE_FAILED.
364 CloseConnection(QUIC_HANDSHAKE_FAILED,
365 "Server did not receive a known ALPN");
366 return;
367 }
368
QUICHE teama6ef0a62019-03-07 20:34:33 -0500369 QUIC_LOG(INFO) << "Server: handshake finished";
370 state_ = STATE_HANDSHAKE_COMPLETE;
fayang685367a2020-01-14 10:40:15 -0800371 one_rtt_keys_available_ = true;
nharper8f759922019-10-09 11:08:36 -0700372
nharper8f759922019-10-09 11:08:36 -0700373 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
rch9001a962019-12-17 10:44:04 -0800374
nharper8d4ff5c2020-02-27 11:43:44 -0800375 if (!app_data_read_secret_.empty()) {
376 if (!SetReadSecret(ENCRYPTION_FORWARD_SECURE, cipher,
377 app_data_read_secret_)) {
378 QUIC_BUG << "Failed to set forward secure read key.";
379 CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to set app data read key");
380 return;
381 }
382 app_data_read_secret_.clear();
383 }
384
fayangd18bfb92020-03-19 17:24:21 -0700385 handshaker_delegate()->OnOneRttKeysAvailable();
renjietangbd33b622020-02-12 16:52:30 -0800386 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
387 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500388}
389
QUICHE teama6ef0a62019-03-07 20:34:33 -0500390ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
391 uint8_t* out,
392 size_t* out_len,
393 size_t max_out,
394 uint16_t sig_alg,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800395 quiche::QuicheStringPiece in) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500396 signature_callback_ = new SignatureCallback(this);
397 proof_source_->ComputeTlsSignature(
danzhd1fc5912020-05-01 15:29:04 -0700398 session()->connection()->self_address(),
399 session()->connection()->peer_address(), hostname_, sig_alg, in,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500400 std::unique_ptr<SignatureCallback>(signature_callback_));
401 if (state_ == STATE_SIGNATURE_COMPLETE) {
402 return PrivateKeyComplete(out, out_len, max_out);
403 }
404 state_ = STATE_SIGNATURE_PENDING;
405 return ssl_private_key_retry;
406}
407
QUICHE teama6ef0a62019-03-07 20:34:33 -0500408ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
409 uint8_t* out,
410 size_t* out_len,
411 size_t max_out) {
412 if (state_ == STATE_SIGNATURE_PENDING) {
413 return ssl_private_key_retry;
414 }
415 if (cert_verify_sig_.size() > max_out || cert_verify_sig_.empty()) {
416 return ssl_private_key_failure;
417 }
418 *out_len = cert_verify_sig_.size();
419 memcpy(out, cert_verify_sig_.data(), *out_len);
420 cert_verify_sig_.clear();
421 cert_verify_sig_.shrink_to_fit();
422 return ssl_private_key_success;
423}
424
nharperfbaacc02020-04-24 17:30:22 -0700425size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
nharper1f8289a2020-04-27 11:57:28 -0700426 DCHECK(proof_source_->GetTicketCrypter());
427 return proof_source_->GetTicketCrypter()->MaxOverhead();
nharperfbaacc02020-04-24 17:30:22 -0700428}
429
430int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
431 size_t* out_len,
432 size_t max_out_len,
433 quiche::QuicheStringPiece in) {
nharper1f8289a2020-04-27 11:57:28 -0700434 DCHECK(proof_source_->GetTicketCrypter());
435 std::vector<uint8_t> ticket = proof_source_->GetTicketCrypter()->Encrypt(in);
nharperfbaacc02020-04-24 17:30:22 -0700436 if (max_out_len < ticket.size()) {
437 QUIC_BUG
nharper1f8289a2020-04-27 11:57:28 -0700438 << "TicketCrypter returned " << ticket.size()
nharperfbaacc02020-04-24 17:30:22 -0700439 << " bytes of ciphertext, which is larger than its max overhead of "
440 << max_out_len;
441 return 0; // failure
442 }
443 *out_len = ticket.size();
444 memcpy(out, ticket.data(), ticket.size());
445 return 1; // success
446}
447
448ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
449 uint8_t* out,
450 size_t* out_len,
451 size_t max_out_len,
452 quiche::QuicheStringPiece in) {
nharper1f8289a2020-04-27 11:57:28 -0700453 DCHECK(proof_source_->GetTicketCrypter());
nharperfbaacc02020-04-24 17:30:22 -0700454
455 if (!ticket_decryption_callback_) {
456 ticket_decryption_callback_ = new DecryptCallback(this);
nharper1f8289a2020-04-27 11:57:28 -0700457 proof_source_->GetTicketCrypter()->Decrypt(
nharperfbaacc02020-04-24 17:30:22 -0700458 in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
459 // Decrypt can run the callback synchronously. In that case, the callback
460 // will clear the ticket_decryption_callback_ pointer, and instead of
461 // returning ssl_ticket_aead_retry, we should continue processing to return
462 // the decrypted ticket.
463 //
464 // If the callback is not run asynchronously, return ssl_ticket_aead_retry
465 // and when the callback is complete this function will be run again to
466 // return the result.
467 if (ticket_decryption_callback_) {
468 state_ = STATE_TICKET_DECRYPTION_PENDING;
469 return ssl_ticket_aead_retry;
470 }
471 }
472 ticket_decryption_callback_ = nullptr;
473 state_ = STATE_LISTENING;
474 if (decrypted_session_ticket_.empty()) {
475 QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
476 // Ticket decryption failed. Ignore the ticket.
477 return ssl_ticket_aead_ignore_ticket;
478 }
479 if (max_out_len < decrypted_session_ticket_.size()) {
480 return ssl_ticket_aead_error;
481 }
482 memcpy(out, decrypted_session_ticket_.data(),
483 decrypted_session_ticket_.size());
484 *out_len = decrypted_session_ticket_.size();
nharper1783bc22020-05-12 17:46:53 -0700485 QUIC_RELOADABLE_FLAG_COUNT(quic_enable_tls_resumption);
nharperfbaacc02020-04-24 17:30:22 -0700486
487 return ssl_ticket_aead_success;
488}
489
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490int TlsServerHandshaker::SelectCertificate(int* out_alert) {
491 const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
492 if (hostname) {
493 hostname_ = hostname;
nharper0f51d2e2019-12-11 17:52:05 -0800494 crypto_negotiated_params_->sni =
495 QuicHostnameUtils::NormalizeHostname(hostname_);
nharpere0f979c2020-05-05 17:31:55 -0700496 if (GetQuicReloadableFlag(quic_tls_enforce_valid_sni)) {
497 QUIC_RELOADABLE_FLAG_COUNT(quic_tls_enforce_valid_sni);
498 if (!QuicHostnameUtils::IsValidSNI(hostname_)) {
499 // TODO(b/151676147): Include this error string in the CONNECTION_CLOSE
500 // frame.
501 QUIC_LOG(ERROR) << "Invalid SNI provided: \"" << hostname_ << "\"";
502 return SSL_TLSEXT_ERR_ALERT_FATAL;
503 }
504 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500505 } else {
506 QUIC_LOG(INFO) << "No hostname indicated in SNI";
507 }
508
509 QuicReferenceCountedPointer<ProofSource::Chain> chain =
510 proof_source_->GetCertChain(session()->connection()->self_address(),
danzhd1fc5912020-05-01 15:29:04 -0700511 session()->connection()->peer_address(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500512 hostname_);
nharper3a364d82020-05-07 13:31:27 -0700513 if (!chain || chain->certs.empty()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500514 QUIC_LOG(ERROR) << "No certs provided for host '" << hostname_ << "'";
515 return SSL_TLSEXT_ERR_ALERT_FATAL;
516 }
517
dschinaziaaaf1a42020-04-16 11:44:31 -0700518 if (!pre_shared_key_.empty()) {
519 // TODO(b/154162689) add PSK support to QUIC+TLS.
520 QUIC_BUG << "QUIC server pre-shared keys not yet supported with TLS";
521 return SSL_TLSEXT_ERR_ALERT_FATAL;
522 }
523
QUICHE teama6ef0a62019-03-07 20:34:33 -0500524 std::vector<CRYPTO_BUFFER*> certs;
525 certs.resize(chain->certs.size());
526 for (size_t i = 0; i < certs.size(); i++) {
527 certs[i] = CRYPTO_BUFFER_new(
528 reinterpret_cast<const uint8_t*>(chain->certs[i].data()),
529 chain->certs[i].length(), nullptr);
530 }
531
nharper6ebe83b2019-06-13 17:43:52 -0700532 tls_connection_.SetCertChain(certs);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533
534 for (size_t i = 0; i < certs.size(); i++) {
535 CRYPTO_BUFFER_free(certs[i]);
536 }
537
vasilvvc48c8712019-03-11 13:38:16 -0700538 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500539 if (!ProcessTransportParameters(&error_details)) {
540 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
541 *out_alert = SSL_AD_INTERNAL_ERROR;
542 return SSL_TLSEXT_ERR_ALERT_FATAL;
543 }
nharper54492982020-03-19 14:32:52 -0700544 OverrideQuicConfigDefaults(session()->config());
fayang07573532020-04-06 13:20:17 -0700545 session()->OnConfigNegotiated();
546
nharper54492982020-03-19 14:32:52 -0700547 if (!SetTransportParameters()) {
548 QUIC_LOG(ERROR) << "Failed to set transport parameters";
549 return SSL_TLSEXT_ERR_ALERT_FATAL;
550 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500551
nharper35d60192020-03-26 12:15:47 -0700552 QUIC_LOG(INFO) << "Set " << chain->certs.size() << " certs for server "
553 << "with hostname " << hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500554 return SSL_TLSEXT_ERR_OK;
555}
556
dschinazi35e749e2019-04-09 09:36:04 -0700557int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
558 uint8_t* out_len,
559 const uint8_t* in,
560 unsigned in_len) {
561 // |in| contains a sequence of 1-byte-length-prefixed values.
dschinazi91453642019-08-01 11:12:15 -0700562 *out_len = 0;
563 *out = nullptr;
dschinazi35e749e2019-04-09 09:36:04 -0700564 if (in_len == 0) {
dschinazi91453642019-08-01 11:12:15 -0700565 QUIC_DLOG(ERROR) << "No ALPN provided by client";
566 return SSL_TLSEXT_ERR_NOACK;
dschinazi35e749e2019-04-09 09:36:04 -0700567 }
dschinazi91453642019-08-01 11:12:15 -0700568
dschinazi91453642019-08-01 11:12:15 -0700569 CBS all_alpns;
570 CBS_init(&all_alpns, in, in_len);
571
dmcardlecf0bfcf2019-12-13 08:08:21 -0800572 std::vector<quiche::QuicheStringPiece> alpns;
dschinazi91453642019-08-01 11:12:15 -0700573 while (CBS_len(&all_alpns) > 0) {
574 CBS alpn;
575 if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
576 QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
577 return SSL_TLSEXT_ERR_NOACK;
578 }
vasilvvad7424f2019-08-30 00:27:14 -0700579
dschinazi91453642019-08-01 11:12:15 -0700580 const size_t alpn_length = CBS_len(&alpn);
dschinazi91453642019-08-01 11:12:15 -0700581 if (alpn_length == 0) {
582 QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
583 return SSL_TLSEXT_ERR_NOACK;
584 }
vasilvvad7424f2019-08-30 00:27:14 -0700585
586 alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
587 alpn_length);
dschinazi35e749e2019-04-09 09:36:04 -0700588 }
dschinazi91453642019-08-01 11:12:15 -0700589
vasilvvad7424f2019-08-30 00:27:14 -0700590 auto selected_alpn = session()->SelectAlpn(alpns);
591 if (selected_alpn == alpns.end()) {
592 QUIC_DLOG(ERROR) << "No known ALPN provided by client";
593 return SSL_TLSEXT_ERR_NOACK;
594 }
595
596 session()->OnAlpnSelected(*selected_alpn);
597 valid_alpn_received_ = true;
598 *out_len = selected_alpn->size();
599 *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
600 return SSL_TLSEXT_ERR_OK;
dschinazi35e749e2019-04-09 09:36:04 -0700601}
602
QUICHE teama6ef0a62019-03-07 20:34:33 -0500603} // namespace quic