blob: 108bc5a4f07e924203eb96d401f634897350ffdc [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
165bool TlsServerHandshaker::encryption_established() const {
166 return encryption_established_;
167}
168
fayang685367a2020-01-14 10:40:15 -0800169bool TlsServerHandshaker::one_rtt_keys_available() const {
170 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171}
172
173const QuicCryptoNegotiatedParameters&
174TlsServerHandshaker::crypto_negotiated_params() const {
175 return *crypto_negotiated_params_;
176}
177
178CryptoMessageParser* TlsServerHandshaker::crypto_message_parser() {
179 return TlsHandshaker::crypto_message_parser();
180}
181
fayang9a863cf2020-01-16 14:12:11 -0800182HandshakeState TlsServerHandshaker::GetHandshakeState() const {
183 if (one_rtt_keys_available_) {
fayang01062942020-01-22 07:23:23 -0800184 return HANDSHAKE_CONFIRMED;
fayang9a863cf2020-01-16 14:12:11 -0800185 }
186 if (state_ >= STATE_ENCRYPTION_HANDSHAKE_DATA_PROCESSED) {
187 return HANDSHAKE_PROCESSED;
188 }
189 return HANDSHAKE_START;
190}
191
nharper486a8a92019-08-28 16:25:10 -0700192size_t TlsServerHandshaker::BufferSizeLimitForLevel(
193 EncryptionLevel level) const {
194 return TlsHandshaker::BufferSizeLimitForLevel(level);
195}
196
nharper54492982020-03-19 14:32:52 -0700197void TlsServerHandshaker::OverrideQuicConfigDefaults(QuicConfig* /*config*/) {}
198
nharper8d4ff5c2020-02-27 11:43:44 -0800199bool TlsServerHandshaker::SetReadSecret(
200 EncryptionLevel level,
201 const SSL_CIPHER* cipher,
202 const std::vector<uint8_t>& read_secret) {
203 if (level != ENCRYPTION_FORWARD_SECURE || one_rtt_keys_available_) {
204 return TlsHandshaker::SetReadSecret(level, cipher, read_secret);
205 }
206 // Delay setting read secret for ENCRYPTION_FORWARD_SECURE until handshake
207 // completes.
208 app_data_read_secret_ = read_secret;
209 return true;
210}
211
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212void TlsServerHandshaker::AdvanceHandshake() {
213 if (state_ == STATE_CONNECTION_CLOSED) {
214 QUIC_LOG(INFO) << "TlsServerHandshaker received handshake message after "
215 "connection was closed";
216 return;
217 }
218 if (state_ == STATE_HANDSHAKE_COMPLETE) {
219 // TODO(nharper): Handle post-handshake messages.
220 return;
221 }
222
223 int rv = SSL_do_handshake(ssl());
224 if (rv == 1) {
225 FinishHandshake();
226 return;
227 }
228
229 int ssl_error = SSL_get_error(ssl(), rv);
230 bool should_close = true;
231 switch (state_) {
232 case STATE_LISTENING:
233 case STATE_SIGNATURE_COMPLETE:
234 should_close = ssl_error != SSL_ERROR_WANT_READ;
235 break;
236 case STATE_SIGNATURE_PENDING:
237 should_close = ssl_error != SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
238 break;
nharperfbaacc02020-04-24 17:30:22 -0700239 case STATE_TICKET_DECRYPTION_PENDING:
240 should_close = ssl_error != SSL_ERROR_PENDING_TICKET;
241 break;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500242 default:
243 should_close = true;
244 }
245 if (should_close && state_ != STATE_CONNECTION_CLOSED) {
246 QUIC_LOG(WARNING) << "SSL_do_handshake failed; SSL_get_error returns "
247 << ssl_error << ", state_ = " << state_;
248 ERR_print_errors_fp(stderr);
dschinazi91453642019-08-01 11:12:15 -0700249 CloseConnection(QUIC_HANDSHAKE_FAILED,
250 "Server observed TLS handshake failure");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 }
252}
253
254void TlsServerHandshaker::CloseConnection(QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700255 const std::string& reason_phrase) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500256 state_ = STATE_CONNECTION_CLOSED;
renjietang87df0d02020-02-13 11:53:52 -0800257 stream()->OnUnrecoverableError(error, reason_phrase);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258}
259
260bool TlsServerHandshaker::ProcessTransportParameters(
vasilvvc48c8712019-03-11 13:38:16 -0700261 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262 TransportParameters client_params;
263 const uint8_t* client_params_bytes;
264 size_t params_bytes_len;
265 SSL_get_peer_quic_transport_params(ssl(), &client_params_bytes,
266 &params_bytes_len);
dschinazi7b8f0c72020-03-02 13:17:57 -0800267 if (params_bytes_len == 0) {
268 *error_details = "Client's transport parameters are missing";
269 return false;
270 }
271 std::string parse_error_details;
272 if (!ParseTransportParameters(session()->connection()->version(),
dschinazi6c84c142019-07-31 09:11:49 -0700273 Perspective::IS_CLIENT, client_params_bytes,
dschinazi7b8f0c72020-03-02 13:17:57 -0800274 params_bytes_len, &client_params,
275 &parse_error_details)) {
276 DCHECK(!parse_error_details.empty());
277 *error_details =
278 "Unable to parse client's transport parameters: " + parse_error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500279 return false;
280 }
dschinazi6cf4d2a2019-04-30 16:20:23 -0700281
282 // When interoperating with non-Google implementations that do not send
283 // the version extension, set it to what we expect.
284 if (client_params.version == 0) {
285 client_params.version =
286 CreateQuicVersionLabel(session()->connection()->version());
287 }
288
QUICHE teama6ef0a62019-03-07 20:34:33 -0500289 if (CryptoUtils::ValidateClientHelloVersion(
290 client_params.version, session()->connection()->version(),
291 session()->supported_versions(), error_details) != QUIC_NO_ERROR ||
292 session()->config()->ProcessTransportParameters(
293 client_params, CLIENT, error_details) != QUIC_NO_ERROR) {
294 return false;
295 }
nharper3ee44722020-03-17 11:13:28 -0700296 ProcessAdditionalTransportParameters(client_params);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500297
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298 return true;
299}
300
301bool TlsServerHandshaker::SetTransportParameters() {
302 TransportParameters server_params;
303 server_params.perspective = Perspective::IS_SERVER;
304 server_params.supported_versions =
305 CreateQuicVersionLabelVector(session()->supported_versions());
306 server_params.version =
307 CreateQuicVersionLabel(session()->connection()->version());
308
309 if (!session()->config()->FillTransportParameters(&server_params)) {
310 return false;
311 }
312
313 // TODO(nharper): Provide an actual value for the stateless reset token.
314 server_params.stateless_reset_token.resize(16);
315 std::vector<uint8_t> server_params_bytes;
dschinazi6c84c142019-07-31 09:11:49 -0700316 if (!SerializeTransportParameters(session()->connection()->version(),
317 server_params, &server_params_bytes) ||
QUICHE teama6ef0a62019-03-07 20:34:33 -0500318 SSL_set_quic_transport_params(ssl(), server_params_bytes.data(),
319 server_params_bytes.size()) != 1) {
320 return false;
321 }
322 return true;
323}
324
fayanga45ee8a2020-03-20 08:56:11 -0700325void TlsServerHandshaker::SetWriteSecret(
326 EncryptionLevel level,
327 const SSL_CIPHER* cipher,
328 const std::vector<uint8_t>& write_secret) {
329 if (GetQuicRestartFlag(quic_send_settings_on_write_key_available) &&
330 level == ENCRYPTION_FORWARD_SECURE) {
331 encryption_established_ = true;
332 // Fill crypto_negotiated_params_:
333 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
334 if (cipher) {
335 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
336 }
337 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
338 }
339 TlsHandshaker::SetWriteSecret(level, cipher, write_secret);
340}
341
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342void TlsServerHandshaker::FinishHandshake() {
dschinazi91453642019-08-01 11:12:15 -0700343 if (!valid_alpn_received_) {
344 QUIC_DLOG(ERROR)
345 << "Server: handshake finished without receiving a known ALPN";
346 // TODO(b/130164908) this should send no_application_protocol
347 // instead of QUIC_HANDSHAKE_FAILED.
348 CloseConnection(QUIC_HANDSHAKE_FAILED,
349 "Server did not receive a known ALPN");
350 return;
351 }
352
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 QUIC_LOG(INFO) << "Server: handshake finished";
354 state_ = STATE_HANDSHAKE_COMPLETE;
355
fayanga45ee8a2020-03-20 08:56:11 -0700356 if (!GetQuicRestartFlag(quic_send_settings_on_write_key_available)) {
357 encryption_established_ = true;
358 }
fayang685367a2020-01-14 10:40:15 -0800359 one_rtt_keys_available_ = true;
nharper8f759922019-10-09 11:08:36 -0700360
nharper8f759922019-10-09 11:08:36 -0700361 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl());
fayanga45ee8a2020-03-20 08:56:11 -0700362 if (!GetQuicRestartFlag(quic_send_settings_on_write_key_available)) {
363 // Fill crypto_negotiated_params_:
364 if (cipher) {
365 crypto_negotiated_params_->cipher_suite = SSL_CIPHER_get_value(cipher);
366 }
367 crypto_negotiated_params_->key_exchange_group = SSL_get_curve_id(ssl());
nharper8f759922019-10-09 11:08:36 -0700368 }
rch9001a962019-12-17 10:44:04 -0800369
nharper8d4ff5c2020-02-27 11:43:44 -0800370 if (!app_data_read_secret_.empty()) {
371 if (!SetReadSecret(ENCRYPTION_FORWARD_SECURE, cipher,
372 app_data_read_secret_)) {
373 QUIC_BUG << "Failed to set forward secure read key.";
374 CloseConnection(QUIC_HANDSHAKE_FAILED, "Failed to set app data read key");
375 return;
376 }
377 app_data_read_secret_.clear();
378 }
379
fayangd18bfb92020-03-19 17:24:21 -0700380 handshaker_delegate()->OnOneRttKeysAvailable();
renjietangbd33b622020-02-12 16:52:30 -0800381 handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_HANDSHAKE);
382 handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_HANDSHAKE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383}
384
QUICHE teama6ef0a62019-03-07 20:34:33 -0500385ssl_private_key_result_t TlsServerHandshaker::PrivateKeySign(
386 uint8_t* out,
387 size_t* out_len,
388 size_t max_out,
389 uint16_t sig_alg,
dmcardlecf0bfcf2019-12-13 08:08:21 -0800390 quiche::QuicheStringPiece in) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500391 signature_callback_ = new SignatureCallback(this);
392 proof_source_->ComputeTlsSignature(
393 session()->connection()->self_address(), hostname_, sig_alg, in,
394 std::unique_ptr<SignatureCallback>(signature_callback_));
395 if (state_ == STATE_SIGNATURE_COMPLETE) {
396 return PrivateKeyComplete(out, out_len, max_out);
397 }
398 state_ = STATE_SIGNATURE_PENDING;
399 return ssl_private_key_retry;
400}
401
QUICHE teama6ef0a62019-03-07 20:34:33 -0500402ssl_private_key_result_t TlsServerHandshaker::PrivateKeyComplete(
403 uint8_t* out,
404 size_t* out_len,
405 size_t max_out) {
406 if (state_ == STATE_SIGNATURE_PENDING) {
407 return ssl_private_key_retry;
408 }
409 if (cert_verify_sig_.size() > max_out || cert_verify_sig_.empty()) {
410 return ssl_private_key_failure;
411 }
412 *out_len = cert_verify_sig_.size();
413 memcpy(out, cert_verify_sig_.data(), *out_len);
414 cert_verify_sig_.clear();
415 cert_verify_sig_.shrink_to_fit();
416 return ssl_private_key_success;
417}
418
nharperfbaacc02020-04-24 17:30:22 -0700419size_t TlsServerHandshaker::SessionTicketMaxOverhead() {
420 DCHECK(proof_source_->SessionTicketCrypter());
421 return proof_source_->SessionTicketCrypter()->MaxOverhead();
422}
423
424int TlsServerHandshaker::SessionTicketSeal(uint8_t* out,
425 size_t* out_len,
426 size_t max_out_len,
427 quiche::QuicheStringPiece in) {
428 DCHECK(proof_source_->SessionTicketCrypter());
429 std::vector<uint8_t> ticket =
430 proof_source_->SessionTicketCrypter()->Encrypt(in);
431 if (max_out_len < ticket.size()) {
432 QUIC_BUG
433 << "SessionTicketCrypter returned " << ticket.size()
434 << " bytes of ciphertext, which is larger than its max overhead of "
435 << max_out_len;
436 return 0; // failure
437 }
438 *out_len = ticket.size();
439 memcpy(out, ticket.data(), ticket.size());
440 return 1; // success
441}
442
443ssl_ticket_aead_result_t TlsServerHandshaker::SessionTicketOpen(
444 uint8_t* out,
445 size_t* out_len,
446 size_t max_out_len,
447 quiche::QuicheStringPiece in) {
448 DCHECK(proof_source_->SessionTicketCrypter());
449
450 if (!ticket_decryption_callback_) {
451 ticket_decryption_callback_ = new DecryptCallback(this);
452 proof_source_->SessionTicketCrypter()->Decrypt(
453 in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
454 // Decrypt can run the callback synchronously. In that case, the callback
455 // will clear the ticket_decryption_callback_ pointer, and instead of
456 // returning ssl_ticket_aead_retry, we should continue processing to return
457 // the decrypted ticket.
458 //
459 // If the callback is not run asynchronously, return ssl_ticket_aead_retry
460 // and when the callback is complete this function will be run again to
461 // return the result.
462 if (ticket_decryption_callback_) {
463 state_ = STATE_TICKET_DECRYPTION_PENDING;
464 return ssl_ticket_aead_retry;
465 }
466 }
467 ticket_decryption_callback_ = nullptr;
468 state_ = STATE_LISTENING;
469 if (decrypted_session_ticket_.empty()) {
470 QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
471 // Ticket decryption failed. Ignore the ticket.
472 return ssl_ticket_aead_ignore_ticket;
473 }
474 if (max_out_len < decrypted_session_ticket_.size()) {
475 return ssl_ticket_aead_error;
476 }
477 memcpy(out, decrypted_session_ticket_.data(),
478 decrypted_session_ticket_.size());
479 *out_len = decrypted_session_ticket_.size();
480
481 return ssl_ticket_aead_success;
482}
483
QUICHE teama6ef0a62019-03-07 20:34:33 -0500484int TlsServerHandshaker::SelectCertificate(int* out_alert) {
485 const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
486 if (hostname) {
487 hostname_ = hostname;
nharper0f51d2e2019-12-11 17:52:05 -0800488 crypto_negotiated_params_->sni =
489 QuicHostnameUtils::NormalizeHostname(hostname_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 } else {
491 QUIC_LOG(INFO) << "No hostname indicated in SNI";
492 }
493
494 QuicReferenceCountedPointer<ProofSource::Chain> chain =
495 proof_source_->GetCertChain(session()->connection()->self_address(),
496 hostname_);
497 if (chain->certs.empty()) {
498 QUIC_LOG(ERROR) << "No certs provided for host '" << hostname_ << "'";
499 return SSL_TLSEXT_ERR_ALERT_FATAL;
500 }
501
dschinaziaaaf1a42020-04-16 11:44:31 -0700502 if (!pre_shared_key_.empty()) {
503 // TODO(b/154162689) add PSK support to QUIC+TLS.
504 QUIC_BUG << "QUIC server pre-shared keys not yet supported with TLS";
505 return SSL_TLSEXT_ERR_ALERT_FATAL;
506 }
507
QUICHE teama6ef0a62019-03-07 20:34:33 -0500508 std::vector<CRYPTO_BUFFER*> certs;
509 certs.resize(chain->certs.size());
510 for (size_t i = 0; i < certs.size(); i++) {
511 certs[i] = CRYPTO_BUFFER_new(
512 reinterpret_cast<const uint8_t*>(chain->certs[i].data()),
513 chain->certs[i].length(), nullptr);
514 }
515
nharper6ebe83b2019-06-13 17:43:52 -0700516 tls_connection_.SetCertChain(certs);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500517
518 for (size_t i = 0; i < certs.size(); i++) {
519 CRYPTO_BUFFER_free(certs[i]);
520 }
521
vasilvvc48c8712019-03-11 13:38:16 -0700522 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500523 if (!ProcessTransportParameters(&error_details)) {
524 CloseConnection(QUIC_HANDSHAKE_FAILED, error_details);
525 *out_alert = SSL_AD_INTERNAL_ERROR;
526 return SSL_TLSEXT_ERR_ALERT_FATAL;
527 }
nharper54492982020-03-19 14:32:52 -0700528 OverrideQuicConfigDefaults(session()->config());
fayang07573532020-04-06 13:20:17 -0700529 session()->OnConfigNegotiated();
530
nharper54492982020-03-19 14:32:52 -0700531 if (!SetTransportParameters()) {
532 QUIC_LOG(ERROR) << "Failed to set transport parameters";
533 return SSL_TLSEXT_ERR_ALERT_FATAL;
534 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500535
nharper35d60192020-03-26 12:15:47 -0700536 QUIC_LOG(INFO) << "Set " << chain->certs.size() << " certs for server "
537 << "with hostname " << hostname_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500538 return SSL_TLSEXT_ERR_OK;
539}
540
dschinazi35e749e2019-04-09 09:36:04 -0700541int TlsServerHandshaker::SelectAlpn(const uint8_t** out,
542 uint8_t* out_len,
543 const uint8_t* in,
544 unsigned in_len) {
545 // |in| contains a sequence of 1-byte-length-prefixed values.
dschinazi91453642019-08-01 11:12:15 -0700546 *out_len = 0;
547 *out = nullptr;
dschinazi35e749e2019-04-09 09:36:04 -0700548 if (in_len == 0) {
dschinazi91453642019-08-01 11:12:15 -0700549 QUIC_DLOG(ERROR) << "No ALPN provided by client";
550 return SSL_TLSEXT_ERR_NOACK;
dschinazi35e749e2019-04-09 09:36:04 -0700551 }
dschinazi91453642019-08-01 11:12:15 -0700552
dschinazi91453642019-08-01 11:12:15 -0700553 CBS all_alpns;
554 CBS_init(&all_alpns, in, in_len);
555
dmcardlecf0bfcf2019-12-13 08:08:21 -0800556 std::vector<quiche::QuicheStringPiece> alpns;
dschinazi91453642019-08-01 11:12:15 -0700557 while (CBS_len(&all_alpns) > 0) {
558 CBS alpn;
559 if (!CBS_get_u8_length_prefixed(&all_alpns, &alpn)) {
560 QUIC_DLOG(ERROR) << "Failed to parse ALPN length";
561 return SSL_TLSEXT_ERR_NOACK;
562 }
vasilvvad7424f2019-08-30 00:27:14 -0700563
dschinazi91453642019-08-01 11:12:15 -0700564 const size_t alpn_length = CBS_len(&alpn);
dschinazi91453642019-08-01 11:12:15 -0700565 if (alpn_length == 0) {
566 QUIC_DLOG(ERROR) << "Received invalid zero-length ALPN";
567 return SSL_TLSEXT_ERR_NOACK;
568 }
vasilvvad7424f2019-08-30 00:27:14 -0700569
570 alpns.emplace_back(reinterpret_cast<const char*>(CBS_data(&alpn)),
571 alpn_length);
dschinazi35e749e2019-04-09 09:36:04 -0700572 }
dschinazi91453642019-08-01 11:12:15 -0700573
vasilvvad7424f2019-08-30 00:27:14 -0700574 auto selected_alpn = session()->SelectAlpn(alpns);
575 if (selected_alpn == alpns.end()) {
576 QUIC_DLOG(ERROR) << "No known ALPN provided by client";
577 return SSL_TLSEXT_ERR_NOACK;
578 }
579
580 session()->OnAlpnSelected(*selected_alpn);
581 valid_alpn_received_ = true;
582 *out_len = selected_alpn->size();
583 *out = reinterpret_cast<const uint8_t*>(selected_alpn->data());
584 return SSL_TLSEXT_ERR_OK;
dschinazi35e749e2019-04-09 09:36:04 -0700585}
586
QUICHE teama6ef0a62019-03-07 20:34:33 -0500587} // namespace quic