blob: 98bac6e8d496524602c0b8aef90afeba7a8ffaac [file] [log] [blame]
David Benjamin33d10492025-02-03 17:00:03 -05001// Copyright 2016 The BoringSSL Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Steven Valdez143e8b32016-07-11 13:19:03 -040014
15#include <openssl/ssl.h>
16
17#include <assert.h>
18#include <string.h>
19
David Benjamin91a3f262024-02-10 11:08:08 -050020#include <algorithm>
Adam Langley4bfab5d2019-01-23 13:52:17 -080021#include <tuple>
22
David Benjaminabbbee12016-10-31 19:20:42 -040023#include <openssl/aead.h>
Steven Valdez143e8b32016-07-11 13:19:03 -040024#include <openssl/bytestring.h>
25#include <openssl/digest.h>
26#include <openssl/err.h>
David Benjamin070a6c32021-05-05 15:39:27 -040027#include <openssl/hpke.h>
Steven Valdez143e8b32016-07-11 13:19:03 -040028#include <openssl/mem.h>
29#include <openssl/rand.h>
30#include <openssl/stack.h>
31
David Benjamin17cf2cb2016-12-13 01:07:13 -050032#include "../crypto/internal.h"
Steven Valdez143e8b32016-07-11 13:19:03 -040033#include "internal.h"
34
35
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070036BSSL_NAMESPACE_BEGIN
David Benjamin86e95b82017-07-18 16:34:25 -040037
Steven Valdez5440fe02016-07-18 12:40:30 -040038static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
39
David Benjamin6433a912019-05-04 14:17:08 -050040// Allow a minute of ticket age skew in either direction. This covers
41// transmission delays in ClientHello and NewSessionTicket, as well as
42// drift between client and server clock rate since the ticket was issued.
43// See RFC 8446, section 8.3.
44static const int32_t kMaxTicketAgeSkewSeconds = 60;
45
Chris Wood2b19cd32024-10-23 10:41:55 -040046static bool resolve_pake_secret(SSL_HANDSHAKE *hs) {
47 uint8_t verifier_share[spake2plus::kShareSize];
48 uint8_t verifier_confirm[spake2plus::kConfirmSize];
49 uint8_t shared_secret[spake2plus::kSecretSize];
50 if (!hs->pake_verifier->ProcessProverShare(verifier_share, verifier_confirm,
51 shared_secret,
52 hs->pake_share->pake_message)) {
53 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
54 ssl_send_alert(hs->ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
55 return false;
56 }
57
58 bssl::ScopedCBB cbb;
59 if (!CBB_init(cbb.get(), sizeof(verifier_share) + sizeof(verifier_confirm)) ||
60 !CBB_add_bytes(cbb.get(), verifier_share, sizeof(verifier_share)) ||
61 !CBB_add_bytes(cbb.get(), verifier_confirm, sizeof(verifier_confirm)) ||
62 !CBBFinishArray(cbb.get(), &hs->pake_share_bytes)) {
63 return false;
64 }
65
66 return tls13_advance_key_schedule(
67 hs, MakeConstSpan(shared_secret, sizeof(shared_secret)));
68}
69
David Benjamin3b8c5ec2021-04-12 17:43:23 -040070static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs,
71 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090072 SSL *const ssl = hs->ssl;
David Benjamin3b8c5ec2021-04-12 17:43:23 -040073 const uint16_t group_id = hs->new_session->group_id;
Steven Valdez5440fe02016-07-18 12:40:30 -040074
David Benjamin74795b32017-08-31 15:13:12 -040075 bool found_key_share;
David Benjamin3b8c5ec2021-04-12 17:43:23 -040076 Span<const uint8_t> peer_key;
David Benjamin7e1f9842016-09-20 19:24:40 -040077 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin3b8c5ec2021-04-12 17:43:23 -040078 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &peer_key,
79 &alert, client_hello)) {
David Benjamind1e3ce12017-10-06 18:31:15 -040080 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin3b8c5ec2021-04-12 17:43:23 -040081 return false;
Steven Valdez5440fe02016-07-18 12:40:30 -040082 }
83
84 if (!found_key_share) {
David Benjamin3b8c5ec2021-04-12 17:43:23 -040085 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
86 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
87 return false;
Steven Valdez5440fe02016-07-18 12:40:30 -040088 }
89
David Benjamin3b8c5ec2021-04-12 17:43:23 -040090 Array<uint8_t> secret;
David Benjaminb571e772021-03-25 19:42:16 -040091 SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
92 if (hints && !hs->hints_requested && hints->key_share_group_id == group_id &&
93 !hints->key_share_secret.empty()) {
David Benjamin08b1f382023-02-28 17:22:23 -050094 // Copy the key_share secret from hints.
95 if (!hs->key_share_ciphertext.CopyFrom(hints->key_share_ciphertext) ||
David Benjaminb571e772021-03-25 19:42:16 -040096 !secret.CopyFrom(hints->key_share_secret)) {
97 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
98 return false;
99 }
100 } else {
David Benjamin08b1f382023-02-28 17:22:23 -0500101 ScopedCBB ciphertext;
David Benjaminb571e772021-03-25 19:42:16 -0400102 UniquePtr<SSLKeyShare> key_share = SSLKeyShare::Create(group_id);
103 if (!key_share || //
David Benjamin08b1f382023-02-28 17:22:23 -0500104 !CBB_init(ciphertext.get(), 32) ||
105 !key_share->Encap(ciphertext.get(), &secret, &alert, peer_key) ||
106 !CBBFinishArray(ciphertext.get(), &hs->key_share_ciphertext)) {
David Benjaminb571e772021-03-25 19:42:16 -0400107 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
108 return false;
109 }
110 if (hints && hs->hints_requested) {
111 hints->key_share_group_id = group_id;
David Benjamin08b1f382023-02-28 17:22:23 -0500112 if (!hints->key_share_ciphertext.CopyFrom(hs->key_share_ciphertext) ||
David Benjaminb571e772021-03-25 19:42:16 -0400113 !hints->key_share_secret.CopyFrom(secret)) {
114 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
115 return false;
116 }
117 }
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400118 }
119
120 return tls13_advance_key_schedule(hs, secret);
Steven Valdez5440fe02016-07-18 12:40:30 -0400121}
122
Steven Valdez038da9b2017-07-10 12:57:25 -0400123static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs,
124 CBB *out) {
125 CBB contents;
Bob Beck61725ea2024-11-13 17:50:07 +0000126 if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || //
127 !CBB_add_u16_length_prefixed(out, &contents) || //
128 !CBB_add_u16(&contents, hs->ssl->s3->version) || //
Steven Valdez038da9b2017-07-10 12:57:25 -0400129 !CBB_flush(out)) {
130 return 0;
131 }
132
133 return 1;
134}
135
David Benjamin34202b92016-11-16 19:07:53 +0900136static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin860db9e2024-03-02 22:53:13 -0500137 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900138 CBS cipher_suites;
139 CBS_init(&cipher_suites, client_hello->cipher_suites,
140 client_hello->cipher_suites_len);
141
David Benjamind1e3ce12017-10-06 18:31:15 -0400142 const uint16_t version = ssl_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900143
David Benjamin860db9e2024-03-02 22:53:13 -0500144 return ssl_choose_tls13_cipher(cipher_suites,
145 ssl->config->aes_hw_override
146 ? ssl->config->aes_hw_override_value
147 : EVP_has_aes_hardware(),
Adam Langleyca3146c2024-12-17 17:31:33 -0800148 version, ssl->config->compliance_policy);
David Benjamin34202b92016-11-16 19:07:53 +0900149}
150
David Benjamin0cbb1af2018-07-17 21:26:05 -0400151static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) {
David Benjamin794cc592017-03-25 22:24:23 -0500152 SSL *const ssl = hs->ssl;
Bob Beck61725ea2024-11-13 17:50:07 +0000153 if ( // If the client doesn't accept resumption with PSK_DHE_KE, don't send a
154 // session ticket.
David Benjamin0cbb1af2018-07-17 21:26:05 -0400155 !hs->accept_psk_mode ||
156 // We only implement stateless resumption in TLS 1.3, so skip sending
157 // tickets if disabled.
Chris Wood2b19cd32024-10-23 10:41:55 -0400158 (SSL_get_options(ssl) & SSL_OP_NO_TICKET) ||
159 // Don't send tickets for PAKE connections. We don't support resumption
160 // with PAKEs.
161 hs->pake_verifier != nullptr) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400162 *out_sent_tickets = false;
163 return true;
164 }
165
David Benjaminc11ea9422017-08-29 16:33:21 -0400166 // Rebase the session timestamp so that it is measured from ticket
167 // issuance.
David Benjamin31b0c9b2017-07-20 14:49:15 -0400168 ssl_session_rebase_time(ssl, hs->new_session.get());
David Benjamin794cc592017-03-25 22:24:23 -0500169
David Benjamin3f180b82022-05-09 17:45:18 -0400170 assert(ssl->session_ctx->num_tickets <= kMaxTickets);
David Benjaminc59bf8b2024-11-12 12:02:09 -0500171 bool sent_tickets = false;
David Benjamin3f180b82022-05-09 17:45:18 -0400172 for (size_t i = 0; i < ssl->session_ctx->num_tickets; i++) {
Steven Valdezcd8470f2017-10-11 12:29:36 -0400173 UniquePtr<SSL_SESSION> session(
174 SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH));
175 if (!session) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400176 return false;
David Benjamin794cc592017-03-25 22:24:23 -0500177 }
David Benjamin794cc592017-03-25 22:24:23 -0500178
Steven Valdezcd8470f2017-10-11 12:29:36 -0400179 if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400180 return false;
Steven Valdezcd8470f2017-10-11 12:29:36 -0400181 }
David Benjamina3a71e92018-06-29 13:24:45 -0400182 session->ticket_age_add_valid = true;
David Benjamin873ff5c2024-11-27 00:38:03 -0500183 // TODO(crbug.com/381113363): Remove the SSL_is_dtls check once we support
Nick Harper2dc95ee2024-10-29 23:42:56 +0000184 // 0-RTT for DTLS 1.3.
Nick Harper85194322020-05-20 16:59:29 -0700185 bool enable_early_data =
186 ssl->enable_early_data &&
David Benjamin7ad65542024-11-20 15:01:01 -0500187 (!SSL_is_quic(ssl) || !ssl->config->quic_early_data_context.empty()) &&
Nick Harper2dc95ee2024-10-29 23:42:56 +0000188 !SSL_is_dtls(ssl);
Nick Harper85194322020-05-20 16:59:29 -0700189 if (enable_early_data) {
David Benjamind6343572019-08-15 17:29:02 -0400190 // QUIC does not use the max_early_data_size parameter and always sets it
David Benjamina1d3bfb2021-06-01 12:12:44 -0400191 // to a fixed value. See RFC 9001, section 4.6.1.
David Benjamind6343572019-08-15 17:29:02 -0400192 session->ticket_max_early_data =
David Benjamin7ad65542024-11-20 15:01:01 -0500193 SSL_is_quic(ssl) ? 0xffffffff : kMaxEarlyDataAccepted;
Steven Valdezbe165a22017-10-10 11:45:01 -0400194 }
David Benjamin899b5572025-03-04 11:08:40 -0500195 session->is_resumable_across_names = ssl->resumption_across_names_enabled;
Steven Valdezbe165a22017-10-10 11:45:01 -0400196
David Benjamin3f180b82022-05-09 17:45:18 -0400197 static_assert(kMaxTickets < 256, "Too many tickets");
198 assert(i < 256);
Steven Valdezcd8470f2017-10-11 12:29:36 -0400199 uint8_t nonce[] = {static_cast<uint8_t>(i)};
200
David Benjamin1386aad2017-07-19 23:57:40 -0400201 ScopedCBB cbb;
Steven Valdezcd8470f2017-10-11 12:29:36 -0400202 CBB body, nonce_cbb, ticket, extensions;
David Benjamin1386aad2017-07-19 23:57:40 -0400203 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin794cc592017-03-25 22:24:23 -0500204 SSL3_MT_NEW_SESSION_TICKET) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -0400205 !CBB_add_u32(&body, session->timeout) ||
206 !CBB_add_u32(&body, session->ticket_age_add) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -0500207 !CBB_add_u8_length_prefixed(&body, &nonce_cbb) ||
208 !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) ||
Nick Harperf9e0c6c2024-08-02 23:19:44 +0000209 !tls13_derive_session_psk(session.get(), nonce, SSL_is_dtls(ssl)) ||
David Benjaminc59bf8b2024-11-12 12:02:09 -0500210 !CBB_add_u16_length_prefixed(&body, &ticket) ||
211 !ssl_encrypt_ticket(hs, &ticket, session.get())) {
212 return false;
213 }
214
215 if (CBB_len(&ticket) == 0) {
216 // The caller decided not to encrypt a ticket. Skip the message.
217 continue;
218 }
219
220 if (!CBB_add_u16_length_prefixed(&body, &extensions)) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400221 return false;
David Benjamin794cc592017-03-25 22:24:23 -0500222 }
223
Nick Harper85194322020-05-20 16:59:29 -0700224 if (enable_early_data) {
David Benjamina93beba2019-10-15 16:58:21 -0400225 CBB early_data;
Steven Valdez7e5dd252018-01-22 15:20:31 -0500226 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) ||
David Benjamina93beba2019-10-15 16:58:21 -0400227 !CBB_add_u16_length_prefixed(&extensions, &early_data) ||
228 !CBB_add_u32(&early_data, session->ticket_max_early_data) ||
David Benjamin794cc592017-03-25 22:24:23 -0500229 !CBB_flush(&extensions)) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400230 return false;
David Benjamin794cc592017-03-25 22:24:23 -0500231 }
232 }
233
David Benjamin899b5572025-03-04 11:08:40 -0500234 SSLFlags flags = 0;
235 if (session->is_resumable_across_names) {
236 flags |= kSSLFlagResumptionAcrossNames;
237 }
238 if (!ssl_add_flags_extension(&extensions, flags)) {
239 return false;
240 }
241
David Benjamin3675eb32021-05-18 14:01:07 -0400242 // Add a fake extension. See RFC 8701.
David Benjamin794cc592017-03-25 22:24:23 -0500243 if (!CBB_add_u16(&extensions,
David Benjamina7bc9442018-01-18 10:08:53 -0500244 ssl_get_grease_value(hs, ssl_grease_ticket_extension)) ||
David Benjamin794cc592017-03-25 22:24:23 -0500245 !CBB_add_u16(&extensions, 0 /* empty */)) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400246 return false;
David Benjamin794cc592017-03-25 22:24:23 -0500247 }
248
David Benjamin1386aad2017-07-19 23:57:40 -0400249 if (!ssl_add_message_cbb(ssl, cbb.get())) {
David Benjamin0cbb1af2018-07-17 21:26:05 -0400250 return false;
David Benjamin794cc592017-03-25 22:24:23 -0500251 }
David Benjaminc59bf8b2024-11-12 12:02:09 -0500252 sent_tickets = true;
David Benjamin794cc592017-03-25 22:24:23 -0500253 }
254
David Benjaminc59bf8b2024-11-12 12:02:09 -0500255 *out_sent_tickets = sent_tickets;
David Benjamin0cbb1af2018-07-17 21:26:05 -0400256 return true;
David Benjamin794cc592017-03-25 22:24:23 -0500257}
258
Chris Wood2b19cd32024-10-23 10:41:55 -0400259static bool check_signature_credential(SSL_HANDSHAKE *hs,
260 const SSL_CREDENTIAL *cred,
261 uint16_t *out_sigalg) {
David Benjamin91a3f262024-02-10 11:08:08 -0500262 switch (cred->type) {
263 case SSLCredentialType::kX509:
264 break;
265 case SSLCredentialType::kDelegated:
266 // Check that the peer supports the signature over the delegated
267 // credential.
268 if (std::find(hs->peer_sigalgs.begin(), hs->peer_sigalgs.end(),
269 cred->dc_algorithm) == hs->peer_sigalgs.end()) {
270 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
271 return false;
272 }
273 break;
Chris Wood2b19cd32024-10-23 10:41:55 -0400274 default:
275 OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
276 return false;
David Benjamin91a3f262024-02-10 11:08:08 -0500277 }
278
Chris Wood2b19cd32024-10-23 10:41:55 -0400279 // If we reach here then the credential requires a signature. If |cred| is a
David Benjamin91a3f262024-02-10 11:08:08 -0500280 // delegated credential, this also checks that the peer supports delegated
281 // credentials and matched |dc_cert_verify_algorithm|.
Bob Beckc8fafe82024-09-24 21:54:25 +0000282 if (!tls1_choose_signature_algorithm(hs, cred, out_sigalg)) {
283 return false;
284 }
285 // Use this credential if it either matches a requested issuer,
286 // or does not require issuer matching.
287 return ssl_credential_matches_requested_issuers(hs, cred);
David Benjamin91a3f262024-02-10 11:08:08 -0500288}
289
Chris Wood2b19cd32024-10-23 10:41:55 -0400290static bool check_pake_credential(SSL_HANDSHAKE *hs,
291 const SSL_CREDENTIAL *cred) {
292 assert(cred->type == SSLCredentialType::kSPAKE2PlusV1Server);
293 // Look for a client PAKE share that matches |cred|.
294 if (hs->pake_share == nullptr ||
295 hs->pake_share->named_pake != SSL_PAKE_SPAKE2PLUSV1 ||
296 hs->pake_share->client_identity != Span(cred->client_identity) ||
297 hs->pake_share->server_identity != Span(cred->server_identity)) {
298 OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_PAKE_MISMATCH);
299 return false;
300 }
301
302 return true;
303}
304
David Benjaminc3c88822016-11-14 10:32:04 +0900305static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400306 // At this point, most ClientHello extensions have already been processed by
307 // the common handshake logic. Resolve the remaining non-PSK parameters.
David Benjaminc3c88822016-11-14 10:32:04 +0900308 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400309 SSLMessage msg;
David Benjamin731058e2016-12-03 23:15:13 -0500310 SSL_CLIENT_HELLO client_hello;
Daniel McArdle00e434d2021-02-18 11:47:18 -0500311 if (!hs->GetClientHello(&msg, &client_hello)) {
David Benjamin34202b92016-11-16 19:07:53 +0900312 return ssl_hs_error;
313 }
314
David Benjamin7ad65542024-11-20 15:01:01 -0500315 if (SSL_is_quic(ssl) && client_hello.session_id_len > 0) {
Nick Harpercac93922020-05-07 13:53:23 -0700316 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_COMPATIBILITY_MODE);
317 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
318 return ssl_hs_error;
319 }
Nick Harpercee4fe22024-07-29 20:01:29 +0000320 // DTLS 1.3 disables compatibility mode, and even if the client advertised a
321 // session ID (for resumption in DTLS 1.2), the server "MUST NOT echo the
322 // 'legacy_session_id' value from the client" (RFC 9147, section 5) as it
323 // would in a TLS 1.3 handshake.
324 if (!SSL_is_dtls(ssl)) {
David Benjamin87d0c172024-09-20 16:45:42 -0400325 hs->session_id.CopyFrom(
David Benjaminf6099502025-01-11 00:38:56 -0500326 Span(client_hello.session_id, client_hello.session_id_len));
Nick Harpercee4fe22024-07-29 20:01:29 +0000327 }
Steven Valdez520e1222017-06-13 12:45:25 -0400328
David Benjamin91a3f262024-02-10 11:08:08 -0500329 Array<SSL_CREDENTIAL *> creds;
David Benjamina3de8ea2025-02-17 18:27:07 -0500330 if (!ssl_get_full_credential_list(hs, &creds)) {
David Benjamin91a3f262024-02-10 11:08:08 -0500331 return ssl_hs_error;
332 }
333 if (creds.empty()) {
334 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
335 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
336 return ssl_hs_error;
337 }
338
339 // Select the credential to use.
David Benjamin91a3f262024-02-10 11:08:08 -0500340 for (SSL_CREDENTIAL *cred : creds) {
341 ERR_clear_error();
Chris Wood2b19cd32024-10-23 10:41:55 -0400342 if (cred->type == SSLCredentialType::kSPAKE2PlusV1Server) {
343 if (check_pake_credential(hs, cred)) {
344 hs->credential = UpRef(cred);
345 hs->pake_verifier = MakeUnique<spake2plus::Verifier>();
346 if (hs->pake_verifier == nullptr ||
347 !hs->pake_verifier->Init(cred->pake_context, cred->client_identity,
348 cred->server_identity,
349 cred->password_verifier_w0,
350 cred->registration_record)) {
351 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
352 return ssl_hs_error;
353 }
354 break;
355 }
356 } else {
357 uint16_t sigalg;
358 if (check_signature_credential(hs, cred, &sigalg)) {
359 hs->credential = UpRef(cred);
360 hs->signature_algorithm = sigalg;
361 break;
362 }
David Benjamin91a3f262024-02-10 11:08:08 -0500363 }
364 }
365 if (hs->credential == nullptr) {
366 // The error from the last attempt is in the error queue.
David Benjaminf44677c2025-01-27 16:11:49 -0500367 assert(ERR_peek_error() != 0);
David Benjamin91a3f262024-02-10 11:08:08 -0500368 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
369 return ssl_hs_error;
370 }
371
David Benjaminc11ea9422017-08-29 16:33:21 -0400372 // Negotiate the cipher suite.
David Benjamin860db9e2024-03-02 22:53:13 -0500373 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
David Benjamin45738dd2017-02-09 20:01:26 -0500374 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900375 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
David Benjamind1e3ce12017-10-06 18:31:15 -0400376 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
David Benjaminf01f42a2016-11-16 19:05:33 +0900377 return ssl_hs_error;
378 }
379
David Benjaminc11ea9422017-08-29 16:33:21 -0400380 // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
381 // deferred. Complete it now.
David Benjamin707af292017-03-10 17:47:18 -0500382 uint8_t alert = SSL_AD_DECODE_ERROR;
383 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400384 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500385 return ssl_hs_error;
386 }
387
David Benjamind55f4502021-08-11 13:19:19 -0400388 // The PRF hash is now known.
Steven Valdezcd8470f2017-10-11 12:29:36 -0400389 if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) {
390 return ssl_hs_error;
391 }
392
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -0800393 hs->tls13_state = state13_select_session;
David Benjamin707af292017-03-10 17:47:18 -0500394 return ssl_hs_ok;
395}
Steven Valdez908ac192017-01-12 13:17:07 -0500396
David Benjamin707af292017-03-10 17:47:18 -0500397static enum ssl_ticket_aead_result_t select_session(
David Benjamin37af90f2017-07-29 01:42:16 -0400398 SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
David Benjamin64770122019-05-04 11:00:04 -0500399 int32_t *out_ticket_age_skew, bool *out_offered_ticket,
400 const SSLMessage &msg, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin707af292017-03-10 17:47:18 -0500401 SSL *const ssl = hs->ssl;
David Benjamin64770122019-05-04 11:00:04 -0500402 *out_session = nullptr;
David Benjamin707af292017-03-10 17:47:18 -0500403
David Benjamin707af292017-03-10 17:47:18 -0500404 CBS pre_shared_key;
David Benjamin64770122019-05-04 11:00:04 -0500405 *out_offered_ticket = ssl_client_hello_get_extension(
406 client_hello, &pre_shared_key, TLSEXT_TYPE_pre_shared_key);
407 if (!*out_offered_ticket) {
David Benjamin707af292017-03-10 17:47:18 -0500408 return ssl_ticket_aead_ignore_ticket;
409 }
410
David Benjamin8648c532021-08-19 18:02:37 -0400411 // Per RFC 8446, section 4.2.9, servers MUST abort the handshake if the client
David Benjamin3af62262021-03-30 13:37:53 -0400412 // sends pre_shared_key without psk_key_exchange_modes.
413 CBS unused;
414 if (!ssl_client_hello_get_extension(client_hello, &unused,
415 TLSEXT_TYPE_psk_key_exchange_modes)) {
416 *out_alert = SSL_AD_MISSING_EXTENSION;
417 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
418 return ssl_ticket_aead_error;
419 }
420
David Benjamin707af292017-03-10 17:47:18 -0500421 CBS ticket, binders;
422 uint32_t client_ticket_age;
David Benjamin9806ae02019-08-16 15:32:03 -0400423 if (!ssl_ext_pre_shared_key_parse_clienthello(
424 hs, &ticket, &binders, &client_ticket_age, out_alert, client_hello,
425 &pre_shared_key)) {
David Benjamin707af292017-03-10 17:47:18 -0500426 return ssl_ticket_aead_error;
427 }
428
David Benjamin64770122019-05-04 11:00:04 -0500429 // If the peer did not offer psk_dhe, ignore the resumption.
430 if (!hs->accept_psk_mode) {
431 return ssl_ticket_aead_ignore_ticket;
432 }
433
Chris Wood2b19cd32024-10-23 10:41:55 -0400434 // We do not currently support resumption with PAKEs.
435 if (hs->credential != nullptr &&
436 hs->credential->type == SSLCredentialType::kSPAKE2PlusV1Server) {
437 return ssl_ticket_aead_ignore_ticket;
438 }
439
David Benjaminc11ea9422017-08-29 16:33:21 -0400440 // TLS 1.3 session tickets are renewed separately as part of the
441 // NewSessionTicket.
David Benjaminfd45ee72017-08-31 14:49:09 -0400442 bool unused_renew;
David Benjamin37af90f2017-07-29 01:42:16 -0400443 UniquePtr<SSL_SESSION> session;
David Benjamin707af292017-03-10 17:47:18 -0500444 enum ssl_ticket_aead_result_t ret =
David Benjamin28655672018-07-18 23:23:25 -0400445 ssl_process_ticket(hs, &session, &unused_renew, ticket, {});
David Benjamin707af292017-03-10 17:47:18 -0500446 switch (ret) {
447 case ssl_ticket_aead_success:
448 break;
449 case ssl_ticket_aead_error:
450 *out_alert = SSL_AD_INTERNAL_ERROR;
451 return ret;
452 default:
453 return ret;
454 }
455
David Benjamin37af90f2017-07-29 01:42:16 -0400456 if (!ssl_session_is_resumable(hs, session.get()) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400457 // Historically, some TLS 1.3 tickets were missing ticket_age_add.
David Benjamin707af292017-03-10 17:47:18 -0500458 !session->ticket_age_add_valid) {
David Benjamin707af292017-03-10 17:47:18 -0500459 return ssl_ticket_aead_ignore_ticket;
460 }
461
David Benjaminc11ea9422017-08-29 16:33:21 -0400462 // Recover the client ticket age and convert to seconds.
David Benjamin707af292017-03-10 17:47:18 -0500463 client_ticket_age -= session->ticket_age_add;
464 client_ticket_age /= 1000;
465
David Benjamina5d14be2024-11-03 14:31:16 +0000466 OPENSSL_timeval now = ssl_ctx_get_current_time(ssl->ctx.get());
David Benjamin707af292017-03-10 17:47:18 -0500467
David Benjaminc11ea9422017-08-29 16:33:21 -0400468 // Compute the server ticket age in seconds.
David Benjamin707af292017-03-10 17:47:18 -0500469 assert(now.tv_sec >= session->time);
470 uint64_t server_ticket_age = now.tv_sec - session->time;
471
David Benjaminc11ea9422017-08-29 16:33:21 -0400472 // To avoid overflowing |hs->ticket_age_skew|, we will not resume
473 // 68-year-old sessions.
David Benjamin707af292017-03-10 17:47:18 -0500474 if (server_ticket_age > INT32_MAX) {
David Benjamin707af292017-03-10 17:47:18 -0500475 return ssl_ticket_aead_ignore_ticket;
476 }
477
David Benjamin8c98bac2019-08-15 20:40:01 -0400478 *out_ticket_age_skew = static_cast<int32_t>(client_ticket_age) -
479 static_cast<int32_t>(server_ticket_age);
David Benjamin707af292017-03-10 17:47:18 -0500480
David Benjaminc11ea9422017-08-29 16:33:21 -0400481 // Check the PSK binder.
David Benjamin7934f082017-08-01 16:32:25 -0400482 if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) {
David Benjamin707af292017-03-10 17:47:18 -0500483 *out_alert = SSL_AD_DECRYPT_ERROR;
484 return ssl_ticket_aead_error;
485 }
486
David Benjamin37af90f2017-07-29 01:42:16 -0400487 *out_session = std::move(session);
David Benjamin707af292017-03-10 17:47:18 -0500488 return ssl_ticket_aead_success;
489}
490
Nick Harper7c522992020-04-30 14:15:49 -0700491static bool quic_ticket_compatible(const SSL_SESSION *session,
492 const SSL_CONFIG *config) {
493 if (!session->is_quic) {
494 return true;
495 }
Nick Harper85194322020-05-20 16:59:29 -0700496
497 if (session->quic_early_data_context.empty() ||
498 config->quic_early_data_context.size() !=
499 session->quic_early_data_context.size() ||
500 CRYPTO_memcmp(config->quic_early_data_context.data(),
501 session->quic_early_data_context.data(),
502 session->quic_early_data_context.size()) != 0) {
Nick Harper7c522992020-04-30 14:15:49 -0700503 return false;
504 }
505 return true;
506}
507
David Benjamin707af292017-03-10 17:47:18 -0500508static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
509 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400510 SSLMessage msg;
David Benjamin707af292017-03-10 17:47:18 -0500511 SSL_CLIENT_HELLO client_hello;
Daniel McArdle00e434d2021-02-18 11:47:18 -0500512 if (!hs->GetClientHello(&msg, &client_hello)) {
David Benjamin707af292017-03-10 17:47:18 -0500513 return ssl_hs_error;
514 }
515
David Benjamin4eb95cc2016-11-16 17:08:23 +0900516 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin37af90f2017-07-29 01:42:16 -0400517 UniquePtr<SSL_SESSION> session;
David Benjamin64770122019-05-04 11:00:04 -0500518 bool offered_ticket = false;
519 switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew,
520 &offered_ticket, msg, &client_hello)) {
David Benjamin707af292017-03-10 17:47:18 -0500521 case ssl_ticket_aead_ignore_ticket:
David Benjamin37af90f2017-07-29 01:42:16 -0400522 assert(!session);
David Benjamin962b3752021-05-10 15:17:18 -0400523 if (!ssl_get_new_session(hs)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400524 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjaminf01f42a2016-11-16 19:05:33 +0900525 return ssl_hs_error;
526 }
David Benjamin707af292017-03-10 17:47:18 -0500527 break;
Steven Valdeza833c352016-11-01 13:39:36 -0400528
David Benjamin707af292017-03-10 17:47:18 -0500529 case ssl_ticket_aead_success:
David Benjaminc11ea9422017-08-29 16:33:21 -0400530 // Carry over authentication information from the previous handshake into
531 // a fresh session.
David Benjamin37af90f2017-07-29 01:42:16 -0400532 hs->new_session =
533 SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
David Benjamin6433a912019-05-04 14:17:08 -0500534 if (hs->new_session == nullptr) {
535 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
536 return ssl_hs_error;
537 }
Steven Valdez2d850622017-01-11 11:34:52 -0500538
David Benjamin046bc1f2017-08-31 15:06:42 -0400539 ssl->s3->session_reused = true;
David Benjamin9b2cdb72021-04-01 23:21:53 -0400540 hs->can_release_private_key = true;
David Benjamin707af292017-03-10 17:47:18 -0500541
David Benjaminc11ea9422017-08-29 16:33:21 -0400542 // Resumption incorporates fresh key material, so refresh the timeout.
David Benjamin98472cb2018-05-02 16:05:36 -0400543 ssl_session_renew_timeout(ssl, hs->new_session.get(),
544 ssl->session_ctx->session_psk_dhe_timeout);
David Benjamin707af292017-03-10 17:47:18 -0500545 break;
546
547 case ssl_ticket_aead_error:
David Benjamind1e3ce12017-10-06 18:31:15 -0400548 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500549 return ssl_hs_error;
550
551 case ssl_ticket_aead_retry:
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -0800552 hs->tls13_state = state13_select_session;
David Benjamin707af292017-03-10 17:47:18 -0500553 return ssl_hs_pending_ticket;
554 }
555
Steven Valdez51607f12020-08-05 10:46:05 -0400556 // Negotiate ALPS now, after ALPN is negotiated and |hs->new_session| is
557 // initialized.
558 if (!ssl_negotiate_alps(hs, &alert, &client_hello)) {
559 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
560 return ssl_hs_error;
561 }
562
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400563 // Record connection properties in the new session.
564 hs->new_session->cipher = hs->new_cipher;
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400565
Chris Wood2b19cd32024-10-23 10:41:55 -0400566 // If using key shares, resolve the supported group and determine if we need
567 // HelloRetryRequest.
568 bool need_hrr = false;
569 if (hs->pake_verifier == nullptr) {
570 if (!tls1_get_shared_group(hs, &hs->new_session->group_id)) {
571 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP);
572 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
573 return ssl_hs_error;
574 }
575 bool found_key_share;
576 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share,
577 /*out_key_share=*/nullptr, &alert,
578 &client_hello)) {
579 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
580 return ssl_hs_error;
581 }
582 need_hrr = !found_key_share;
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400583 }
584
Steven Valdez51607f12020-08-05 10:46:05 -0400585 // Determine if we're negotiating 0-RTT.
586 if (!ssl->enable_early_data) {
587 ssl->s3->early_data_reason = ssl_early_data_disabled;
588 } else if (!offered_ticket) {
589 ssl->s3->early_data_reason = ssl_early_data_no_session_offered;
590 } else if (!session) {
591 ssl->s3->early_data_reason = ssl_early_data_session_not_resumed;
592 } else if (session->ticket_max_early_data == 0) {
593 ssl->s3->early_data_reason = ssl_early_data_unsupported_for_session;
594 } else if (!hs->early_data_offered) {
595 ssl->s3->early_data_reason = ssl_early_data_peer_declined;
David Benjamin8acec002021-05-19 13:03:34 -0400596 } else if (hs->channel_id_negotiated) {
Steven Valdez51607f12020-08-05 10:46:05 -0400597 // Channel ID is incompatible with 0-RTT.
598 ssl->s3->early_data_reason = ssl_early_data_channel_id;
David Benjaminf6099502025-01-11 00:38:56 -0500599 } else if (Span(ssl->s3->alpn_selected) != session->early_alpn) {
Steven Valdez51607f12020-08-05 10:46:05 -0400600 // The negotiated ALPN must match the one in the ticket.
601 ssl->s3->early_data_reason = ssl_early_data_alpn_mismatch;
602 } else if (hs->new_session->has_application_settings !=
603 session->has_application_settings ||
David Benjaminf6099502025-01-11 00:38:56 -0500604 Span(hs->new_session->local_application_settings) !=
Steven Valdez51607f12020-08-05 10:46:05 -0400605 session->local_application_settings) {
606 ssl->s3->early_data_reason = ssl_early_data_alps_mismatch;
607 } else if (ssl->s3->ticket_age_skew < -kMaxTicketAgeSkewSeconds ||
608 kMaxTicketAgeSkewSeconds < ssl->s3->ticket_age_skew) {
609 ssl->s3->early_data_reason = ssl_early_data_ticket_age_skew;
610 } else if (!quic_ticket_compatible(session.get(), hs->config)) {
611 ssl->s3->early_data_reason = ssl_early_data_quic_parameter_mismatch;
Chris Wood2b19cd32024-10-23 10:41:55 -0400612 } else if (need_hrr) {
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400613 ssl->s3->early_data_reason = ssl_early_data_hello_retry_request;
Steven Valdez51607f12020-08-05 10:46:05 -0400614 } else {
615 // |ssl_session_is_resumable| forbids cross-cipher resumptions even if the
616 // PRF hashes match.
617 assert(hs->new_cipher == session->cipher);
618
619 ssl->s3->early_data_reason = ssl_early_data_accepted;
620 ssl->s3->early_data_accepted = true;
621 }
622
Steven Valdez51607f12020-08-05 10:46:05 -0400623 // Store the ALPN and ALPS values in the session for 0-RTT. Note the peer
624 // applications settings are not generally known until client
625 // EncryptedExtensions.
David Benjaminbfdd1a92018-06-29 16:26:38 -0400626 if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) {
627 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
628 return ssl_hs_error;
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500629 }
630
Steven Valdez51607f12020-08-05 10:46:05 -0400631 // The peer applications settings are usually received later, in
632 // EncryptedExtensions. But, in 0-RTT handshakes, we carry over the
633 // values from |session|. Do this now, before |session| is discarded.
634 if (ssl->s3->early_data_accepted &&
635 hs->new_session->has_application_settings &&
636 !hs->new_session->peer_application_settings.CopyFrom(
637 session->peer_application_settings)) {
638 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
639 return ssl_hs_error;
640 }
641
Nick Harper5e086952020-09-30 13:59:14 -0700642 // Copy the QUIC early data context to the session.
David Benjamin7ad65542024-11-20 15:01:01 -0500643 if (ssl->enable_early_data && SSL_is_quic(ssl)) {
Nick Harper5e086952020-09-30 13:59:14 -0700644 if (!hs->new_session->quic_early_data_context.CopyFrom(
645 hs->config->quic_early_data_context)) {
646 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
647 return ssl_hs_error;
648 }
649 }
650
David Benjamin707af292017-03-10 17:47:18 -0500651 if (ssl->ctx->dos_protection_cb != NULL &&
652 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400653 // Connection rejected for DOS reasons.
David Benjamin707af292017-03-10 17:47:18 -0500654 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400655 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500656 return ssl_hs_error;
657 }
658
Steven Valdezcd8470f2017-10-11 12:29:36 -0400659 size_t hash_len = EVP_MD_size(
660 ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher));
661
662 // Set up the key schedule and incorporate the PSK into the running secret.
David Benjamin87d0c172024-09-20 16:45:42 -0400663 if (!tls13_init_key_schedule(hs, ssl->s3->session_reused
David Benjaminf6099502025-01-11 00:38:56 -0500664 ? Span(hs->new_session->secret)
665 : Span(kZeroes, hash_len)) ||
David Benjamin83a49932021-05-20 15:57:09 -0400666 !ssl_hash_message(hs, msg)) {
David Benjamin9806ae02019-08-16 15:32:03 -0400667 return ssl_hs_error;
668 }
669
David Benjamin02e62562017-12-18 18:04:01 -0500670 if (ssl->s3->early_data_accepted) {
David Benjamind6343572019-08-15 17:29:02 -0400671 if (!tls13_derive_early_secret(hs)) {
Steven Valdez2d850622017-01-11 11:34:52 -0500672 return ssl_hs_error;
673 }
674 } else if (hs->early_data_offered) {
David Benjamin046bc1f2017-08-31 15:06:42 -0400675 ssl->s3->skip_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500676 }
677
Chris Wood2b19cd32024-10-23 10:41:55 -0400678 if (need_hrr) {
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400679 ssl->method->next_message(ssl);
680 if (!hs->transcript.UpdateForHelloRetryRequest()) {
681 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400682 }
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400683 hs->tls13_state = state13_send_hello_retry_request;
684 return ssl_hs_ok;
685 }
686
Chris Wood2b19cd32024-10-23 10:41:55 -0400687 if (hs->pake_verifier) {
688 assert(!ssl->s3->session_reused);
689 // Revealing the PAKE share (notably confirmV) allows the client to confirm
690 // one PAKE guess, so we must deduct from the brute force limit.
691 if (!hs->credential->ClaimPAKEAttempt()) {
692 OPENSSL_PUT_ERROR(SSL, SSL_R_PAKE_EXHAUSTED);
693 ssl_send_alert(hs->ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
694 return ssl_hs_error;
695 }
696 if (!resolve_pake_secret(hs)) {
697 return ssl_hs_error;
698 }
699 } else {
700 if (!resolve_ecdhe_secret(hs, &client_hello)) {
701 return ssl_hs_error;
702 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400703 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400704
David Benjamin8f94c312017-08-01 17:35:55 -0400705 ssl->method->next_message(ssl);
Daniel McArdle00e434d2021-02-18 11:47:18 -0500706 hs->ech_client_hello_buf.Reset();
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -0800707 hs->tls13_state = state13_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400708 return ssl_hs_ok;
709}
Steven Valdez143e8b32016-07-11 13:19:03 -0400710
David Benjaminc3c88822016-11-14 10:32:04 +0900711static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
712 SSL *const ssl = hs->ssl;
David Benjaminb571e772021-03-25 19:42:16 -0400713 if (hs->hints_requested) {
714 return ssl_hs_hints_ready;
715 }
Steven Valdez964b2372017-11-07 17:09:52 -0500716
Chris Wood2b19cd32024-10-23 10:41:55 -0400717 // Although a server could HelloRetryRequest with PAKEs to request a cookie,
718 // we never do so.
719 assert(hs->pake_verifier == nullptr);
Steven Valdez7e5dd252018-01-22 15:20:31 -0500720 ScopedCBB cbb;
721 CBB body, session_id, extensions;
Steven Valdez7e5dd252018-01-22 15:20:31 -0500722 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
David Benjamin294ab972025-02-19 17:04:07 -0500723 !CBB_add_u16(&body,
724 SSL_is_dtls(ssl) ? DTLS1_2_VERSION : TLS1_2_VERSION) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -0500725 !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) ||
726 !CBB_add_u8_length_prefixed(&body, &session_id) ||
David Benjamin87d0c172024-09-20 16:45:42 -0400727 !CBB_add_bytes(&session_id, hs->session_id.data(),
728 hs->session_id.size()) ||
David Benjamin3743aaf2020-09-21 13:55:16 -0400729 !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -0500730 !CBB_add_u8(&body, 0 /* no compression */) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -0500731 !CBB_add_u16_length_prefixed(&body, &extensions) ||
732 !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) ||
733 !CBB_add_u16(&extensions, 2 /* length */) ||
David Benjamin83824d22024-09-22 13:35:09 -0400734 !CBB_add_u16(&extensions, ssl->s3->version) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -0500735 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
736 !CBB_add_u16(&extensions, 2 /* length */) ||
David Benjamin860db9e2024-03-02 22:53:13 -0500737 !CBB_add_u16(&extensions, hs->new_session->group_id)) {
Steven Valdez7e5dd252018-01-22 15:20:31 -0500738 return ssl_hs_error;
739 }
David Benjamin18b68362021-06-18 23:13:46 -0400740 if (hs->ech_is_inner) {
741 // Fill a placeholder for the ECH confirmation value.
742 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_encrypted_client_hello) ||
743 !CBB_add_u16(&extensions, ECH_CONFIRMATION_SIGNAL_LEN) ||
744 !CBB_add_zeros(&extensions, ECH_CONFIRMATION_SIGNAL_LEN)) {
745 return ssl_hs_error;
746 }
747 }
748 Array<uint8_t> hrr;
749 if (!ssl->method->finish_message(ssl, cbb.get(), &hrr)) {
750 return ssl_hs_error;
751 }
752 if (hs->ech_is_inner) {
753 // Now that the message is encoded, fill in the whole value.
754 size_t offset = hrr.size() - ECH_CONFIRMATION_SIGNAL_LEN;
755 if (!ssl_ech_accept_confirmation(
David Benjaminf6099502025-01-11 00:38:56 -0500756 hs, Span(hrr).last(ECH_CONFIRMATION_SIGNAL_LEN),
David Benjamin18b68362021-06-18 23:13:46 -0400757 ssl->s3->client_random, hs->transcript, /*is_hrr=*/true, hrr,
758 offset)) {
759 return ssl_hs_error;
760 }
761 }
Steven Valdez964b2372017-11-07 17:09:52 -0500762
David Benjamin18b68362021-06-18 23:13:46 -0400763 if (!ssl->method->add_message(ssl, std::move(hrr)) ||
764 !ssl->method->add_change_cipher_spec(ssl)) {
Steven Valdez7e5dd252018-01-22 15:20:31 -0500765 return ssl_hs_error;
Steven Valdez5440fe02016-07-18 12:40:30 -0400766 }
767
Kris Kwiatkowskib11902a2019-08-24 11:01:04 +0100768 ssl->s3->used_hello_retry_request = true;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -0800769 hs->tls13_state = state13_read_second_client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400770 return ssl_hs_flush;
Steven Valdez5440fe02016-07-18 12:40:30 -0400771}
772
David Benjamin7934f082017-08-01 16:32:25 -0400773static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900774 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400775 SSLMessage msg;
776 if (!ssl->method->get_message(ssl, &msg)) {
777 return ssl_hs_read_message;
778 }
779 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400780 return ssl_hs_error;
781 }
David Benjamin731058e2016-12-03 23:15:13 -0500782 SSL_CLIENT_HELLO client_hello;
David Benjamin94398702025-02-11 13:47:02 -0500783 if (!SSL_parse_client_hello(ssl, &client_hello, CBS_data(&msg.body),
784 CBS_len(&msg.body))) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400785 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
Steven Valdez5440fe02016-07-18 12:40:30 -0400786 return ssl_hs_error;
787 }
788
David Benjaminba423c92021-06-15 16:26:58 -0400789 if (ssl->s3->ech_status == ssl_ech_accepted) {
David Benjamin18b68362021-06-18 23:13:46 -0400790 // If we previously accepted the ClientHelloInner, the second ClientHello
791 // must contain an outer encrypted_client_hello extension.
Daniel McArdle00e434d2021-02-18 11:47:18 -0500792 CBS ech_body;
793 if (!ssl_client_hello_get_extension(&client_hello, &ech_body,
794 TLSEXT_TYPE_encrypted_client_hello)) {
795 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
796 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
797 return ssl_hs_error;
798 }
Daniel McArdle00e434d2021-02-18 11:47:18 -0500799 uint16_t kdf_id, aead_id;
David Benjamin18b68362021-06-18 23:13:46 -0400800 uint8_t type, config_id;
Steven Valdez94a63a52021-04-29 10:52:42 -0400801 CBS enc, payload;
David Benjamin18b68362021-06-18 23:13:46 -0400802 if (!CBS_get_u8(&ech_body, &type) || //
803 type != ECH_CLIENT_OUTER || //
804 !CBS_get_u16(&ech_body, &kdf_id) || //
Daniel McArdle00e434d2021-02-18 11:47:18 -0500805 !CBS_get_u16(&ech_body, &aead_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -0400806 !CBS_get_u8(&ech_body, &config_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -0500807 !CBS_get_u16_length_prefixed(&ech_body, &enc) ||
808 !CBS_get_u16_length_prefixed(&ech_body, &payload) ||
809 CBS_len(&ech_body) != 0) {
810 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
811 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
812 return ssl_hs_error;
813 }
814
David Benjaminf39c81d2021-05-03 18:39:46 -0400815 if (kdf_id != EVP_HPKE_KDF_id(EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get())) ||
816 aead_id !=
817 EVP_HPKE_AEAD_id(EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get())) ||
818 config_id != hs->ech_config_id || CBS_len(&enc) > 0) {
Daniel McArdle00e434d2021-02-18 11:47:18 -0500819 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
820 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
821 return ssl_hs_error;
822 }
823
824 // Decrypt the payload with the HPKE context from the first ClientHello.
David Benjamin44425dd2022-01-27 12:22:42 -0500825 uint8_t alert = SSL_AD_DECODE_ERROR;
Daniel McArdle00e434d2021-02-18 11:47:18 -0500826 bool unused;
David Benjamin44425dd2022-01-27 12:22:42 -0500827 if (!ssl_client_hello_decrypt(hs, &alert, &unused,
828 &hs->ech_client_hello_buf, &client_hello,
829 payload)) {
Daniel McArdle00e434d2021-02-18 11:47:18 -0500830 // Decryption failure is fatal in the second ClientHello.
831 OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
Daniel McArdle00e434d2021-02-18 11:47:18 -0500832 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
833 return ssl_hs_error;
834 }
Daniel McArdle00e434d2021-02-18 11:47:18 -0500835
836 // Reparse |client_hello| from the buffer owned by |hs|.
837 if (!hs->GetClientHello(&msg, &client_hello)) {
838 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
839 return ssl_hs_error;
840 }
841 }
842
David Benjamin9806ae02019-08-16 15:32:03 -0400843 // We perform all our negotiation based on the first ClientHello (for
844 // consistency with what |select_certificate_cb| observed), which is in the
845 // transcript, so we can ignore most of this second one.
846 //
847 // We do, however, check the second PSK binder. This covers the client key
848 // share, in case we ever send half-RTT data (we currently do not). It is also
849 // a tricky computation, so we enforce the peer handled it correctly.
850 if (ssl->s3->session_reused) {
851 CBS pre_shared_key;
852 if (!ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
853 TLSEXT_TYPE_pre_shared_key)) {
854 OPENSSL_PUT_ERROR(SSL, SSL_R_INCONSISTENT_CLIENT_HELLO);
855 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
856 return ssl_hs_error;
857 }
858
859 CBS ticket, binders;
860 uint32_t client_ticket_age;
861 uint8_t alert = SSL_AD_DECODE_ERROR;
862 if (!ssl_ext_pre_shared_key_parse_clienthello(
863 hs, &ticket, &binders, &client_ticket_age, &alert, &client_hello,
864 &pre_shared_key)) {
865 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
866 return ssl_hs_error;
867 }
868
869 // Note it is important that we do not obtain a new |SSL_SESSION| from
870 // |ticket|. We have already selected parameters based on the first
871 // ClientHello (in the transcript) and must not switch partway through.
872 if (!tls13_verify_psk_binder(hs, hs->new_session.get(), msg, &binders)) {
873 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
874 return ssl_hs_error;
875 }
876 }
877
Chris Wood2b19cd32024-10-23 10:41:55 -0400878 // Although a server could HelloRetryRequest with PAKEs to request a cookie,
879 // we never do so.
880 assert(hs->pake_verifier == nullptr);
David Benjamin3b8c5ec2021-04-12 17:43:23 -0400881 if (!resolve_ecdhe_secret(hs, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400882 return ssl_hs_error;
883 }
884
David Benjamin7934f082017-08-01 16:32:25 -0400885 if (!ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400886 return ssl_hs_error;
887 }
888
David Benjaminf9cc26f2020-02-09 16:49:31 -0500889 // ClientHello should be the end of the flight.
890 if (ssl->method->has_unprocessed_handshake_data(ssl)) {
891 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
892 OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA);
893 return ssl_hs_error;
894 }
895
David Benjamin8f94c312017-08-01 17:35:55 -0400896 ssl->method->next_message(ssl);
Daniel McArdle00e434d2021-02-18 11:47:18 -0500897 hs->ech_client_hello_buf.Reset();
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -0800898 hs->tls13_state = state13_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400899 return ssl_hs_ok;
900}
901
David Benjaminc3c88822016-11-14 10:32:04 +0900902static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
903 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500904
Dan McArdlec2959352020-10-29 14:31:31 -0400905 Span<uint8_t> random(ssl->s3->server_random);
David Benjaminb571e772021-03-25 19:42:16 -0400906
907 SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
908 if (hints && !hs->hints_requested &&
David Benjamin4a6c8fd2022-07-21 14:05:41 -0700909 hints->server_random_tls13.size() == random.size()) {
910 OPENSSL_memcpy(random.data(), hints->server_random_tls13.data(),
911 random.size());
David Benjaminb571e772021-03-25 19:42:16 -0400912 } else {
913 RAND_bytes(random.data(), random.size());
914 if (hints && hs->hints_requested &&
David Benjamin4a6c8fd2022-07-21 14:05:41 -0700915 !hints->server_random_tls13.CopyFrom(random)) {
David Benjaminb571e772021-03-25 19:42:16 -0400916 return ssl_hs_error;
917 }
918 }
Dan McArdlec2959352020-10-29 14:31:31 -0400919
David Benjamin83a49932021-05-20 15:57:09 -0400920 Array<uint8_t> server_hello;
921 ScopedCBB cbb;
922 CBB body, extensions, session_id;
923 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
David Benjamin294ab972025-02-19 17:04:07 -0500924 !CBB_add_u16(&body,
925 SSL_is_dtls(ssl) ? DTLS1_2_VERSION : TLS1_2_VERSION) ||
David Benjamin83a49932021-05-20 15:57:09 -0400926 !CBB_add_bytes(&body, ssl->s3->server_random,
927 sizeof(ssl->s3->server_random)) ||
928 !CBB_add_u8_length_prefixed(&body, &session_id) ||
David Benjamin87d0c172024-09-20 16:45:42 -0400929 !CBB_add_bytes(&session_id, hs->session_id.data(),
930 hs->session_id.size()) ||
David Benjamin83a49932021-05-20 15:57:09 -0400931 !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) ||
932 !CBB_add_u8(&body, 0) ||
933 !CBB_add_u16_length_prefixed(&body, &extensions) ||
934 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Chris Wood2b19cd32024-10-23 10:41:55 -0400935 !ssl_ext_pake_add_serverhello(hs, &extensions) ||
David Benjamin83a49932021-05-20 15:57:09 -0400936 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
937 !ssl_ext_supported_versions_add_serverhello(hs, &extensions) ||
938 !ssl->method->finish_message(ssl, cbb.get(), &server_hello)) {
939 return ssl_hs_error;
Dan McArdlec2959352020-10-29 14:31:31 -0400940 }
941
David Benjamin18b68362021-06-18 23:13:46 -0400942 assert(ssl->s3->ech_status != ssl_ech_accepted || hs->ech_is_inner);
943 if (hs->ech_is_inner) {
David Benjamin83a49932021-05-20 15:57:09 -0400944 // Fill in the ECH confirmation signal.
David Benjamin18b68362021-06-18 23:13:46 -0400945 const size_t offset = ssl_ech_confirmation_signal_hello_offset(ssl);
David Benjamin006f20a2021-06-22 23:00:49 -0400946 Span<uint8_t> random_suffix = random.last(ECH_CONFIRMATION_SIGNAL_LEN);
David Benjamin18b68362021-06-18 23:13:46 -0400947 if (!ssl_ech_accept_confirmation(hs, random_suffix, ssl->s3->client_random,
948 hs->transcript,
949 /*is_hrr=*/false, server_hello, offset)) {
David Benjamin83a49932021-05-20 15:57:09 -0400950 return ssl_hs_error;
951 }
952
953 // Update |server_hello|.
David Benjamin83a49932021-05-20 15:57:09 -0400954 Span<uint8_t> server_hello_out =
David Benjaminf6099502025-01-11 00:38:56 -0500955 Span(server_hello).subspan(offset, ECH_CONFIRMATION_SIGNAL_LEN);
David Benjamin83a49932021-05-20 15:57:09 -0400956 OPENSSL_memcpy(server_hello_out.data(), random_suffix.data(),
957 ECH_CONFIRMATION_SIGNAL_LEN);
958 }
959
960 if (!ssl->method->add_message(ssl, std::move(server_hello))) {
David Benjamin1386aad2017-07-19 23:57:40 -0400961 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400962 }
963
David Benjamin08b1f382023-02-28 17:22:23 -0500964 hs->key_share_ciphertext.Reset(); // No longer needed.
Kris Kwiatkowskib11902a2019-08-24 11:01:04 +0100965 if (!ssl->s3->used_hello_retry_request &&
David Benjamin666d16e2017-10-06 18:45:16 -0400966 !ssl->method->add_change_cipher_spec(ssl)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400967 return ssl_hs_error;
Steven Valdez520e1222017-06-13 12:45:25 -0400968 }
969
David Benjaminc11ea9422017-08-29 16:33:21 -0400970 // Derive and enable the handshake traffic secrets.
Steven Valdez4cb84942016-12-16 11:29:28 -0500971 if (!tls13_derive_handshake_secrets(hs) ||
David Benjamine530ea32019-08-16 19:28:00 -0400972 !tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal,
David Benjamin754d4c92020-02-11 16:27:21 -0500973 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -0400974 hs->server_handshake_secret)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400975 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400976 }
977
David Benjaminc11ea9422017-08-29 16:33:21 -0400978 // Send EncryptedExtensions.
David Benjamin1386aad2017-07-19 23:57:40 -0400979 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez143e8b32016-07-11 13:19:03 -0400980 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500981 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400982 !ssl_add_message_cbb(ssl, cbb.get())) {
983 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400984 }
985
Chris Wood2b19cd32024-10-23 10:41:55 -0400986 if (!ssl->s3->session_reused && !hs->pake_verifier) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400987 // Determine whether to request a client certificate.
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -0700988 hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER);
Steven Valdez143e8b32016-07-11 13:19:03 -0400989 }
990
David Benjaminc11ea9422017-08-29 16:33:21 -0400991 // Send a CertificateRequest, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500992 if (hs->cert_request) {
Steven Valdez7e5dd252018-01-22 15:20:31 -0500993 CBB cert_request_extensions, sigalg_contents, sigalgs_cbb;
994 if (!ssl->method->init_message(ssl, cbb.get(), &body,
995 SSL3_MT_CERTIFICATE_REQUEST) ||
996 !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
997 !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) ||
998 !CBB_add_u16(&cert_request_extensions,
999 TLSEXT_TYPE_signature_algorithms) ||
1000 !CBB_add_u16_length_prefixed(&cert_request_extensions,
1001 &sigalg_contents) ||
1002 !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) ||
David Benjaminebad5082020-02-03 19:32:19 -05001003 !tls12_add_verify_sigalgs(hs, &sigalgs_cbb)) {
Steven Valdez7e5dd252018-01-22 15:20:31 -05001004 return ssl_hs_error;
1005 }
1006
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001007 if (ssl_has_client_CAs(hs->config)) {
Steven Valdez7e5dd252018-01-22 15:20:31 -05001008 CBB ca_contents;
1009 if (!CBB_add_u16(&cert_request_extensions,
1010 TLSEXT_TYPE_certificate_authorities) ||
Steven Valdezcd8470f2017-10-11 12:29:36 -04001011 !CBB_add_u16_length_prefixed(&cert_request_extensions,
Steven Valdez7e5dd252018-01-22 15:20:31 -05001012 &ca_contents) ||
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001013 !ssl_add_client_CA_list(hs, &ca_contents) ||
Steven Valdez7e5dd252018-01-22 15:20:31 -05001014 !CBB_flush(&cert_request_extensions)) {
Steven Valdezcd8470f2017-10-11 12:29:36 -04001015 return ssl_hs_error;
1016 }
Steven Valdez7e5dd252018-01-22 15:20:31 -05001017 }
Steven Valdezcd8470f2017-10-11 12:29:36 -04001018
Steven Valdez7e5dd252018-01-22 15:20:31 -05001019 if (!ssl_add_message_cbb(ssl, cbb.get())) {
1020 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -04001021 }
1022 }
1023
David Benjaminc11ea9422017-08-29 16:33:21 -04001024 // Send the server Certificate message, if necessary.
Chris Wood2b19cd32024-10-23 10:41:55 -04001025 if (!ssl->s3->session_reused && !hs->pake_verifier) {
David Benjamin0f24bed2017-01-12 19:46:50 -05001026 if (!tls13_add_certificate(hs)) {
David Benjamin1386aad2017-07-19 23:57:40 -04001027 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -05001028 }
1029
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001030 hs->tls13_state = state13_send_server_certificate_verify;
David Benjamin81b7bc32017-01-12 19:44:57 -05001031 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001032 }
1033
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001034 hs->tls13_state = state13_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -05001035 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001036}
1037
David Benjamin44148742017-06-17 13:20:59 -04001038static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
1039 switch (tls13_add_certificate_verify(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04001040 case ssl_private_key_success:
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001041 hs->tls13_state = state13_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -05001042 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001043
1044 case ssl_private_key_retry:
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001045 hs->tls13_state = state13_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -04001046 return ssl_hs_private_key_operation;
1047
1048 case ssl_private_key_failure:
1049 return ssl_hs_error;
1050 }
1051
1052 assert(0);
1053 return ssl_hs_error;
1054}
1055
David Benjaminc3c88822016-11-14 10:32:04 +09001056static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +09001057 SSL *const ssl = hs->ssl;
David Benjaminb571e772021-03-25 19:42:16 -04001058 if (hs->hints_requested) {
1059 return ssl_hs_hints_ready;
1060 }
1061
David Benjamin9b2cdb72021-04-01 23:21:53 -04001062 hs->can_release_private_key = true;
David Benjamin0f24bed2017-01-12 19:46:50 -05001063 if (!tls13_add_finished(hs) ||
David Benjaminc11ea9422017-08-29 16:33:21 -04001064 // Update the secret to the master secret and derive traffic keys.
David Benjaminf6099502025-01-11 00:38:56 -05001065 !tls13_advance_key_schedule(hs,
1066 Span(kZeroes, hs->transcript.DigestLen())) ||
David Benjamin6e4fc332016-11-17 16:43:08 +09001067 !tls13_derive_application_secrets(hs) ||
David Benjamine530ea32019-08-16 19:28:00 -04001068 !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal,
David Benjamin754d4c92020-02-11 16:27:21 -05001069 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -04001070 hs->server_traffic_secret_0)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04001071 return ssl_hs_error;
1072 }
1073
Matthew Braithwaite093a8232020-01-28 14:06:55 -08001074 hs->tls13_state = state13_send_half_rtt_ticket;
David Benjamin0c306492020-02-09 16:28:52 -05001075 return hs->handback ? ssl_hs_handback : ssl_hs_ok;
Matthew Braithwaite093a8232020-01-28 14:06:55 -08001076}
1077
1078static enum ssl_hs_wait_t do_send_half_rtt_ticket(SSL_HANDSHAKE *hs) {
1079 SSL *const ssl = hs->ssl;
1080
David Benjamin02e62562017-12-18 18:04:01 -05001081 if (ssl->s3->early_data_accepted) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001082 // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
1083 // the wire sooner and also avoids triggering a write on |SSL_read| when
1084 // processing the client Finished. This requires computing the client
David Benjamina130ce02018-08-14 22:26:39 -05001085 // Finished early. See RFC 8446, section 4.6.1.
Bob Beck61725ea2024-11-13 17:50:07 +00001086 static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, 0,
1087 0};
David Benjamin7ad65542024-11-20 15:01:01 -05001088 if (!SSL_is_quic(ssl) && !hs->transcript.Update(kEndOfEarlyData)) {
Steven Valdez7e5dd252018-01-22 15:20:31 -05001089 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1090 return ssl_hs_error;
Steven Valdezcd8470f2017-10-11 12:29:36 -04001091 }
1092
David Benjamin794cc592017-03-25 22:24:23 -05001093 size_t finished_len;
David Benjamin0f55aa82024-10-08 22:09:51 -04001094 hs->expected_client_finished.Resize(hs->transcript.DigestLen());
1095 if (!tls13_finished_mac(hs, hs->expected_client_finished.data(),
David Benjamine530ea32019-08-16 19:28:00 -04001096 &finished_len, false /* client */)) {
David Benjamin794cc592017-03-25 22:24:23 -05001097 return ssl_hs_error;
1098 }
1099
David Benjamin0f55aa82024-10-08 22:09:51 -04001100 if (finished_len != hs->expected_client_finished.size()) {
David Benjamin794cc592017-03-25 22:24:23 -05001101 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1102 return ssl_hs_error;
1103 }
1104
David Benjaminc11ea9422017-08-29 16:33:21 -04001105 // Feed the predicted Finished into the transcript. This allows us to derive
1106 // the resumption secret early and send half-RTT tickets.
David Benjamind2529062024-10-22 17:53:35 -04001107 //
David Benjamin873ff5c2024-11-27 00:38:03 -05001108 // TODO(crbug.com/381113363): Don't use half-RTT tickets with DTLS 1.3.
1109 // TODO(crbug.com/376939532): Perhaps don't use half-RTT tickets at all.
David Benjamin794cc592017-03-25 22:24:23 -05001110 assert(!SSL_is_dtls(hs->ssl));
David Benjamin0f55aa82024-10-08 22:09:51 -04001111 assert(hs->expected_client_finished.size() <= 0xff);
David Benjamine530ea32019-08-16 19:28:00 -04001112 uint8_t header[4] = {
1113 SSL3_MT_FINISHED, 0, 0,
David Benjamin0f55aa82024-10-08 22:09:51 -04001114 static_cast<uint8_t>(hs->expected_client_finished.size())};
David Benjamin0cbb1af2018-07-17 21:26:05 -04001115 bool unused_sent_tickets;
David Benjamin75a1f232017-10-11 17:19:19 -04001116 if (!hs->transcript.Update(header) ||
David Benjamin0f55aa82024-10-08 22:09:51 -04001117 !hs->transcript.Update(hs->expected_client_finished) ||
David Benjamin8f94c312017-08-01 17:35:55 -04001118 !tls13_derive_resumption_secret(hs) ||
David Benjamin0cbb1af2018-07-17 21:26:05 -04001119 !add_new_session_tickets(hs, &unused_sent_tickets)) {
David Benjamin794cc592017-03-25 22:24:23 -05001120 return ssl_hs_error;
1121 }
1122 }
1123
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001124 hs->tls13_state = state13_read_second_client_flight;
Steven Valdez2d850622017-01-11 11:34:52 -05001125 return ssl_hs_flush;
1126}
1127
David Benjamin82374692024-09-05 17:04:04 -04001128static bool uses_end_of_early_data(const SSL *ssl) {
1129 // DTLS and QUIC omit the EndOfEarlyData message. See RFC 9001, section 8.3,
1130 // and RFC 9147, section 5.6.
David Benjamin7ad65542024-11-20 15:01:01 -05001131 return !SSL_is_quic(ssl) && !SSL_is_dtls(ssl);
David Benjamin82374692024-09-05 17:04:04 -04001132}
1133
Steven Valdez2d850622017-01-11 11:34:52 -05001134static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
1135 SSL *const ssl = hs->ssl;
David Benjamin02e62562017-12-18 18:04:01 -05001136 if (ssl->s3->early_data_accepted) {
David Benjamin1e859052020-02-09 16:04:58 -05001137 if (!tls13_set_traffic_key(ssl, ssl_encryption_early_data, evp_aead_open,
David Benjamin754d4c92020-02-11 16:27:21 -05001138 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -04001139 hs->early_traffic_secret)) {
Steven Valdez2d850622017-01-11 11:34:52 -05001140 return ssl_hs_error;
1141 }
David Benjaminfd45ee72017-08-31 14:49:09 -04001142 hs->can_early_write = true;
1143 hs->can_early_read = true;
1144 hs->in_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -05001145 }
David Benjamind6343572019-08-15 17:29:02 -04001146
David Benjamin82374692024-09-05 17:04:04 -04001147 // If the EndOfEarlyData message is not used, switch to
1148 // client_handshake_secret before the early return.
1149 if (!uses_end_of_early_data(ssl)) {
David Benjamind6343572019-08-15 17:29:02 -04001150 if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
David Benjamin754d4c92020-02-11 16:27:21 -05001151 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -04001152 hs->client_handshake_secret)) {
David Benjamind6343572019-08-15 17:29:02 -04001153 return ssl_hs_error;
1154 }
David Benjamin71ed9d72021-01-12 18:18:46 -05001155 hs->tls13_state = state13_process_end_of_early_data;
David Benjamind6343572019-08-15 17:29:02 -04001156 return ssl->s3->early_data_accepted ? ssl_hs_early_return : ssl_hs_ok;
1157 }
1158
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001159 hs->tls13_state = state13_process_end_of_early_data;
David Benjamin02e62562017-12-18 18:04:01 -05001160 return ssl->s3->early_data_accepted ? ssl_hs_read_end_of_early_data
1161 : ssl_hs_ok;
Steven Valdez2d850622017-01-11 11:34:52 -05001162}
1163
1164static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
Steven Valdezcd8470f2017-10-11 12:29:36 -04001165 SSL *const ssl = hs->ssl;
David Benjamin71ed9d72021-01-12 18:18:46 -05001166 // In protocols that use EndOfEarlyData, we must consume the extra message and
1167 // switch to client_handshake_secret after the early return.
David Benjamin82374692024-09-05 17:04:04 -04001168 if (uses_end_of_early_data(ssl)) {
David Benjamin71ed9d72021-01-12 18:18:46 -05001169 // If early data was not accepted, the EndOfEarlyData will be in the
1170 // discarded early data.
1171 if (hs->ssl->s3->early_data_accepted) {
1172 SSLMessage msg;
1173 if (!ssl->method->get_message(ssl, &msg)) {
1174 return ssl_hs_read_message;
1175 }
1176 if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
1177 return ssl_hs_error;
1178 }
1179 if (CBS_len(&msg.body) != 0) {
1180 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1181 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1182 return ssl_hs_error;
1183 }
1184 ssl->method->next_message(ssl);
Steven Valdezcd8470f2017-10-11 12:29:36 -04001185 }
David Benjamin71ed9d72021-01-12 18:18:46 -05001186 if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
1187 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -04001188 hs->client_handshake_secret)) {
David Benjaminf3503512019-08-20 15:55:24 -04001189 return ssl_hs_error;
1190 }
Steven Valdez2d850622017-01-11 11:34:52 -05001191 }
Steven Valdez51607f12020-08-05 10:46:05 -04001192 hs->tls13_state = state13_read_client_encrypted_extensions;
1193 return ssl_hs_ok;
1194}
1195
1196static enum ssl_hs_wait_t do_read_client_encrypted_extensions(
1197 SSL_HANDSHAKE *hs) {
1198 SSL *const ssl = hs->ssl;
1199 // For now, only one extension uses client EncryptedExtensions. This function
1200 // may be generalized if others use it in the future.
1201 if (hs->new_session->has_application_settings &&
1202 !ssl->s3->early_data_accepted) {
1203 SSLMessage msg;
1204 if (!ssl->method->get_message(ssl, &msg)) {
1205 return ssl_hs_read_message;
1206 }
1207 if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
1208 return ssl_hs_error;
1209 }
1210
1211 CBS body = msg.body, extensions;
1212 if (!CBS_get_u16_length_prefixed(&body, &extensions) ||
1213 CBS_len(&body) != 0) {
1214 OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1215 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1216 return ssl_hs_error;
1217 }
1218
Victor Tan558960d2023-06-23 15:04:33 +00001219 uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
1220 if (hs->config->alps_use_new_codepoint) {
1221 extension_type = TLSEXT_TYPE_application_settings;
1222 }
1223 SSLExtension application_settings(extension_type);
Steven Valdez51607f12020-08-05 10:46:05 -04001224 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamina75027b2021-07-20 15:07:22 -04001225 if (!ssl_parse_extensions(&extensions, &alert, {&application_settings},
Steven Valdez51607f12020-08-05 10:46:05 -04001226 /*ignore_unknown=*/false)) {
1227 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
1228 return ssl_hs_error;
1229 }
1230
David Benjamina75027b2021-07-20 15:07:22 -04001231 if (!application_settings.present) {
Steven Valdez51607f12020-08-05 10:46:05 -04001232 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
1233 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
1234 return ssl_hs_error;
1235 }
1236
1237 // Note that, if 0-RTT was accepted, these values will already have been
1238 // initialized earlier.
1239 if (!hs->new_session->peer_application_settings.CopyFrom(
David Benjamina75027b2021-07-20 15:07:22 -04001240 application_settings.data) ||
Steven Valdez51607f12020-08-05 10:46:05 -04001241 !ssl_hash_message(hs, msg)) {
1242 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
1243 return ssl_hs_error;
1244 }
1245
1246 ssl->method->next_message(ssl);
1247 }
1248
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001249 hs->tls13_state = state13_read_client_certificate;
David Benjamin7934f082017-08-01 16:32:25 -04001250 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001251}
1252
David Benjamin7934f082017-08-01 16:32:25 -04001253static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +09001254 SSL *const ssl = hs->ssl;
1255 if (!hs->cert_request) {
David Benjaminf3503512019-08-20 15:55:24 -04001256 if (!ssl->s3->session_reused) {
1257 // OpenSSL returns X509_V_OK when no certificates are requested. This is
1258 // classed by them as a bug, but it's assumed by at least NGINX. (Only do
1259 // this in full handshakes as resumptions should carry over the previous
1260 // |verify_result|, though this is a no-op because servers do not
1261 // implement the client's odd soft-fail mode.)
1262 hs->new_session->verify_result = X509_V_OK;
1263 }
Adam Langley37646832016-08-01 16:16:46 -07001264
David Benjaminc11ea9422017-08-29 16:33:21 -04001265 // Skip this state.
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001266 hs->tls13_state = state13_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -04001267 return ssl_hs_ok;
1268 }
1269
David Benjamin12f58782018-08-28 17:06:31 -05001270 const bool allow_anonymous =
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001271 (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
David Benjamin7934f082017-08-01 16:32:25 -04001272 SSLMessage msg;
1273 if (!ssl->method->get_message(ssl, &msg)) {
1274 return ssl_hs_read_message;
1275 }
1276 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) ||
1277 !tls13_process_certificate(hs, msg, allow_anonymous) ||
1278 !ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04001279 return ssl_hs_error;
1280 }
1281
David Benjamin8f94c312017-08-01 17:35:55 -04001282 ssl->method->next_message(ssl);
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001283 hs->tls13_state = state13_read_client_certificate_verify;
David Benjamin7934f082017-08-01 16:32:25 -04001284 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001285}
1286
Steven Valdez51607f12020-08-05 10:46:05 -04001287static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +09001288 SSL *const ssl = hs->ssl;
David Benjaminbfdd1a92018-06-29 16:26:38 -04001289 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001290 // Skip this state.
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001291 hs->tls13_state = state13_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -04001292 return ssl_hs_ok;
1293 }
1294
David Benjamin7934f082017-08-01 16:32:25 -04001295 SSLMessage msg;
1296 if (!ssl->method->get_message(ssl, &msg)) {
1297 return ssl_hs_read_message;
1298 }
1299
David Benjamin3a1dd462017-07-11 16:13:10 -04001300 switch (ssl_verify_peer_cert(hs)) {
1301 case ssl_verify_ok:
1302 break;
1303 case ssl_verify_invalid:
1304 return ssl_hs_error;
1305 case ssl_verify_retry:
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001306 hs->tls13_state = state13_read_client_certificate_verify;
David Benjamin3a1dd462017-07-11 16:13:10 -04001307 return ssl_hs_certificate_verify;
1308 }
1309
David Benjamin7934f082017-08-01 16:32:25 -04001310 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
1311 !tls13_process_certificate_verify(hs, msg) ||
1312 !ssl_hash_message(hs, msg)) {
David Benjamin6929f272016-11-16 19:10:08 +09001313 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -04001314 }
1315
David Benjamin8f94c312017-08-01 17:35:55 -04001316 ssl->method->next_message(ssl);
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001317 hs->tls13_state = state13_read_channel_id;
David Benjamin7934f082017-08-01 16:32:25 -04001318 return ssl_hs_ok;
Nick Harper60a85cb2016-09-23 16:25:11 -07001319}
1320
David Benjamin7934f082017-08-01 16:32:25 -04001321static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
David Benjamin8f94c312017-08-01 17:35:55 -04001322 SSL *const ssl = hs->ssl;
David Benjamin8acec002021-05-19 13:03:34 -04001323 if (!hs->channel_id_negotiated) {
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001324 hs->tls13_state = state13_read_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -07001325 return ssl_hs_ok;
1326 }
1327
David Benjamin7934f082017-08-01 16:32:25 -04001328 SSLMessage msg;
1329 if (!ssl->method->get_message(ssl, &msg)) {
1330 return ssl_hs_read_message;
1331 }
Bob Beck61725ea2024-11-13 17:50:07 +00001332 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || //
1333 !tls1_verify_channel_id(hs, msg) || //
David Benjamin7934f082017-08-01 16:32:25 -04001334 !ssl_hash_message(hs, msg)) {
Nick Harper60a85cb2016-09-23 16:25:11 -07001335 return ssl_hs_error;
1336 }
1337
David Benjamin8f94c312017-08-01 17:35:55 -04001338 ssl->method->next_message(ssl);
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001339 hs->tls13_state = state13_read_client_finished;
David Benjamin7934f082017-08-01 16:32:25 -04001340 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001341}
1342
David Benjamin7934f082017-08-01 16:32:25 -04001343static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +09001344 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -04001345 SSLMessage msg;
1346 if (!ssl->method->get_message(ssl, &msg)) {
1347 return ssl_hs_read_message;
1348 }
1349 if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
David Benjaminc11ea9422017-08-29 16:33:21 -04001350 // If early data was accepted, we've already computed the client Finished
1351 // and derived the resumption secret.
David Benjamin02e62562017-12-18 18:04:01 -05001352 !tls13_process_finished(hs, msg, ssl->s3->early_data_accepted) ||
David Benjaminc11ea9422017-08-29 16:33:21 -04001353 // evp_aead_seal keys have already been switched.
David Benjamine530ea32019-08-16 19:28:00 -04001354 !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_open,
David Benjamin754d4c92020-02-11 16:27:21 -05001355 hs->new_session.get(),
David Benjamin0f55aa82024-10-08 22:09:51 -04001356 hs->client_traffic_secret_0)) {
Steven Valdez143e8b32016-07-11 13:19:03 -04001357 return ssl_hs_error;
1358 }
1359
David Benjamin02e62562017-12-18 18:04:01 -05001360 if (!ssl->s3->early_data_accepted) {
Bob Beck61725ea2024-11-13 17:50:07 +00001361 if (!ssl_hash_message(hs, msg) || //
David Benjamin794cc592017-03-25 22:24:23 -05001362 !tls13_derive_resumption_secret(hs)) {
1363 return ssl_hs_error;
1364 }
1365
David Benjaminc11ea9422017-08-29 16:33:21 -04001366 // We send post-handshake tickets as part of the handshake in 1-RTT.
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001367 hs->tls13_state = state13_send_new_session_ticket;
David Benjamin8f94c312017-08-01 17:35:55 -04001368 } else {
David Benjaminc11ea9422017-08-29 16:33:21 -04001369 // We already sent half-RTT tickets.
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001370 hs->tls13_state = state13_done;
David Benjamin794cc592017-03-25 22:24:23 -05001371 }
1372
Chris Wood2b19cd32024-10-23 10:41:55 -04001373 if (hs->credential != nullptr &&
1374 hs->credential->type == SSLCredentialType::kSPAKE2PlusV1Server) {
1375 // The client has now confirmed that it does know the correct password, so
1376 // this connection no longer counts towards the brute force limit.
1377 hs->credential->RestorePAKEAttempt();
1378 }
1379
David Benjamin8f94c312017-08-01 17:35:55 -04001380 ssl->method->next_message(ssl);
David Benjamin484c3342024-11-22 00:38:38 -05001381 if (SSL_is_dtls(ssl)) {
1382 ssl->method->schedule_ack(ssl);
1383 return ssl_hs_flush;
1384 }
1385 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -04001386}
1387
David Benjaminc3c88822016-11-14 10:32:04 +09001388static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjamin484c3342024-11-22 00:38:38 -05001389 SSL *const ssl = hs->ssl;
David Benjamin0cbb1af2018-07-17 21:26:05 -04001390 bool sent_tickets;
1391 if (!add_new_session_tickets(hs, &sent_tickets)) {
David Benjamin794cc592017-03-25 22:24:23 -05001392 return ssl_hs_error;
Steven Valdez08b65f42016-12-07 15:29:45 -05001393 }
1394
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001395 hs->tls13_state = state13_done;
David Benjamin484c3342024-11-22 00:38:38 -05001396 // In QUIC and DTLS, we can flush the ticket to the transport immediately. In
1397 // TLS over TCP-like transports, we defer until the server performs a write.
1398 // This prevents a non-reading client from causing the server to hang in the
1399 // case of a small server write buffer. Consumers which don't write data to
1400 // the client will need to do a zero-byte write if they wish to flush the
1401 // tickets.
1402 bool should_flush = sent_tickets && (SSL_is_dtls(ssl) || SSL_is_quic(ssl));
1403 return should_flush ? ssl_hs_flush : ssl_hs_ok;
Steven Valdez1e6f11a2016-07-27 11:10:52 -04001404}
1405
David Benjaminc3c88822016-11-14 10:32:04 +09001406enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001407 while (hs->tls13_state != state13_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -04001408 enum ssl_hs_wait_t ret = ssl_hs_error;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001409 enum tls13_server_hs_state_t state =
1410 static_cast<enum tls13_server_hs_state_t>(hs->tls13_state);
Steven Valdez143e8b32016-07-11 13:19:03 -04001411 switch (state) {
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001412 case state13_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +09001413 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -04001414 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001415 case state13_select_session:
David Benjamin707af292017-03-10 17:47:18 -05001416 ret = do_select_session(hs);
1417 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001418 case state13_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +09001419 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -04001420 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001421 case state13_read_second_client_hello:
David Benjamin7934f082017-08-01 16:32:25 -04001422 ret = do_read_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -04001423 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001424 case state13_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +09001425 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -04001426 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001427 case state13_send_server_certificate_verify:
David Benjamin44148742017-06-17 13:20:59 -04001428 ret = do_send_server_certificate_verify(hs);
Steven Valdez2d850622017-01-11 11:34:52 -05001429 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001430 case state13_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +09001431 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -04001432 break;
Matthew Braithwaite093a8232020-01-28 14:06:55 -08001433 case state13_send_half_rtt_ticket:
1434 ret = do_send_half_rtt_ticket(hs);
1435 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001436 case state13_read_second_client_flight:
Steven Valdez2d850622017-01-11 11:34:52 -05001437 ret = do_read_second_client_flight(hs);
1438 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001439 case state13_process_end_of_early_data:
Steven Valdez2d850622017-01-11 11:34:52 -05001440 ret = do_process_end_of_early_data(hs);
1441 break;
Steven Valdez51607f12020-08-05 10:46:05 -04001442 case state13_read_client_encrypted_extensions:
1443 ret = do_read_client_encrypted_extensions(hs);
1444 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001445 case state13_read_client_certificate:
David Benjamin7934f082017-08-01 16:32:25 -04001446 ret = do_read_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -04001447 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001448 case state13_read_client_certificate_verify:
David Benjamin7934f082017-08-01 16:32:25 -04001449 ret = do_read_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -04001450 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001451 case state13_read_channel_id:
David Benjamin7934f082017-08-01 16:32:25 -04001452 ret = do_read_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -07001453 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001454 case state13_read_client_finished:
David Benjamin7934f082017-08-01 16:32:25 -04001455 ret = do_read_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -04001456 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001457 case state13_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +09001458 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -04001459 break;
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001460 case state13_done:
Steven Valdez143e8b32016-07-11 13:19:03 -04001461 ret = ssl_hs_ok;
1462 break;
1463 }
1464
Steven Valdez4d71a9a2017-08-14 15:08:34 -04001465 if (hs->tls13_state != state) {
David Benjaminf60bcfb2017-08-18 15:23:44 -04001466 ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1);
1467 }
1468
Steven Valdez143e8b32016-07-11 13:19:03 -04001469 if (ret != ssl_hs_ok) {
1470 return ret;
1471 }
1472 }
1473
1474 return ssl_hs_ok;
1475}
David Benjamin86e95b82017-07-18 16:34:25 -04001476
David Benjaminf60bcfb2017-08-18 15:23:44 -04001477const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) {
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001478 enum tls13_server_hs_state_t state =
1479 static_cast<enum tls13_server_hs_state_t>(hs->tls13_state);
David Benjaminf60bcfb2017-08-18 15:23:44 -04001480 switch (state) {
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001481 case state13_select_parameters:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001482 return "TLS 1.3 server select_parameters";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001483 case state13_select_session:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001484 return "TLS 1.3 server select_session";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001485 case state13_send_hello_retry_request:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001486 return "TLS 1.3 server send_hello_retry_request";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001487 case state13_read_second_client_hello:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001488 return "TLS 1.3 server read_second_client_hello";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001489 case state13_send_server_hello:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001490 return "TLS 1.3 server send_server_hello";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001491 case state13_send_server_certificate_verify:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001492 return "TLS 1.3 server send_server_certificate_verify";
Matthew Braithwaite093a8232020-01-28 14:06:55 -08001493 case state13_send_half_rtt_ticket:
1494 return "TLS 1.3 server send_half_rtt_ticket";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001495 case state13_send_server_finished:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001496 return "TLS 1.3 server send_server_finished";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001497 case state13_read_second_client_flight:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001498 return "TLS 1.3 server read_second_client_flight";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001499 case state13_process_end_of_early_data:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001500 return "TLS 1.3 server process_end_of_early_data";
Steven Valdez51607f12020-08-05 10:46:05 -04001501 case state13_read_client_encrypted_extensions:
1502 return "TLS 1.3 server read_client_encrypted_extensions";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001503 case state13_read_client_certificate:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001504 return "TLS 1.3 server read_client_certificate";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001505 case state13_read_client_certificate_verify:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001506 return "TLS 1.3 server read_client_certificate_verify";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001507 case state13_read_channel_id:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001508 return "TLS 1.3 server read_channel_id";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001509 case state13_read_client_finished:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001510 return "TLS 1.3 server read_client_finished";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001511 case state13_send_new_session_ticket:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001512 return "TLS 1.3 server send_new_session_ticket";
Matthew Braithwaite08e1fe02019-11-26 17:49:04 -08001513 case state13_done:
David Benjaminf60bcfb2017-08-18 15:23:44 -04001514 return "TLS 1.3 server done";
1515 }
1516
1517 return "TLS 1.3 server unknown";
1518}
1519
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07001520BSSL_NAMESPACE_END