xref: /aosp_15_r20/external/boringssl/src/ssl/tls13_server.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (c) 2016, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker  *
3*8fb009dcSAndroid Build Coastguard Worker  * Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker  *
7*8fb009dcSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14*8fb009dcSAndroid Build Coastguard Worker 
15*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
16*8fb009dcSAndroid Build Coastguard Worker 
17*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
18*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
19*8fb009dcSAndroid Build Coastguard Worker 
20*8fb009dcSAndroid Build Coastguard Worker #include <algorithm>
21*8fb009dcSAndroid Build Coastguard Worker #include <tuple>
22*8fb009dcSAndroid Build Coastguard Worker 
23*8fb009dcSAndroid Build Coastguard Worker #include <openssl/aead.h>
24*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
25*8fb009dcSAndroid Build Coastguard Worker #include <openssl/digest.h>
26*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
27*8fb009dcSAndroid Build Coastguard Worker #include <openssl/hpke.h>
28*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
29*8fb009dcSAndroid Build Coastguard Worker #include <openssl/rand.h>
30*8fb009dcSAndroid Build Coastguard Worker #include <openssl/stack.h>
31*8fb009dcSAndroid Build Coastguard Worker 
32*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
33*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
34*8fb009dcSAndroid Build Coastguard Worker 
35*8fb009dcSAndroid Build Coastguard Worker 
36*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
37*8fb009dcSAndroid Build Coastguard Worker 
38*8fb009dcSAndroid Build Coastguard Worker static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
39*8fb009dcSAndroid Build Coastguard Worker 
40*8fb009dcSAndroid Build Coastguard Worker // Allow a minute of ticket age skew in either direction. This covers
41*8fb009dcSAndroid Build Coastguard Worker // transmission delays in ClientHello and NewSessionTicket, as well as
42*8fb009dcSAndroid Build Coastguard Worker // drift between client and server clock rate since the ticket was issued.
43*8fb009dcSAndroid Build Coastguard Worker // See RFC 8446, section 8.3.
44*8fb009dcSAndroid Build Coastguard Worker static const int32_t kMaxTicketAgeSkewSeconds = 60;
45*8fb009dcSAndroid Build Coastguard Worker 
resolve_ecdhe_secret(SSL_HANDSHAKE * hs,const SSL_CLIENT_HELLO * client_hello)46*8fb009dcSAndroid Build Coastguard Worker static bool resolve_ecdhe_secret(SSL_HANDSHAKE *hs,
47*8fb009dcSAndroid Build Coastguard Worker                                  const SSL_CLIENT_HELLO *client_hello) {
48*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
49*8fb009dcSAndroid Build Coastguard Worker   const uint16_t group_id = hs->new_session->group_id;
50*8fb009dcSAndroid Build Coastguard Worker 
51*8fb009dcSAndroid Build Coastguard Worker   bool found_key_share;
52*8fb009dcSAndroid Build Coastguard Worker   Span<const uint8_t> peer_key;
53*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert = SSL_AD_DECODE_ERROR;
54*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &peer_key,
55*8fb009dcSAndroid Build Coastguard Worker                                            &alert, client_hello)) {
56*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
57*8fb009dcSAndroid Build Coastguard Worker     return false;
58*8fb009dcSAndroid Build Coastguard Worker   }
59*8fb009dcSAndroid Build Coastguard Worker 
60*8fb009dcSAndroid Build Coastguard Worker   if (!found_key_share) {
61*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
62*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
63*8fb009dcSAndroid Build Coastguard Worker     return false;
64*8fb009dcSAndroid Build Coastguard Worker   }
65*8fb009dcSAndroid Build Coastguard Worker 
66*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> secret;
67*8fb009dcSAndroid Build Coastguard Worker   SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
68*8fb009dcSAndroid Build Coastguard Worker   if (hints && !hs->hints_requested && hints->key_share_group_id == group_id &&
69*8fb009dcSAndroid Build Coastguard Worker       !hints->key_share_secret.empty()) {
70*8fb009dcSAndroid Build Coastguard Worker     // Copy the key_share secret from hints.
71*8fb009dcSAndroid Build Coastguard Worker     if (!hs->key_share_ciphertext.CopyFrom(hints->key_share_ciphertext) ||
72*8fb009dcSAndroid Build Coastguard Worker         !secret.CopyFrom(hints->key_share_secret)) {
73*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
74*8fb009dcSAndroid Build Coastguard Worker       return false;
75*8fb009dcSAndroid Build Coastguard Worker     }
76*8fb009dcSAndroid Build Coastguard Worker   } else {
77*8fb009dcSAndroid Build Coastguard Worker     ScopedCBB ciphertext;
78*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<SSLKeyShare> key_share = SSLKeyShare::Create(group_id);
79*8fb009dcSAndroid Build Coastguard Worker     if (!key_share ||  //
80*8fb009dcSAndroid Build Coastguard Worker         !CBB_init(ciphertext.get(), 32) ||
81*8fb009dcSAndroid Build Coastguard Worker         !key_share->Encap(ciphertext.get(), &secret, &alert, peer_key) ||
82*8fb009dcSAndroid Build Coastguard Worker         !CBBFinishArray(ciphertext.get(), &hs->key_share_ciphertext)) {
83*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
84*8fb009dcSAndroid Build Coastguard Worker       return false;
85*8fb009dcSAndroid Build Coastguard Worker     }
86*8fb009dcSAndroid Build Coastguard Worker     if (hints && hs->hints_requested) {
87*8fb009dcSAndroid Build Coastguard Worker       hints->key_share_group_id = group_id;
88*8fb009dcSAndroid Build Coastguard Worker       if (!hints->key_share_ciphertext.CopyFrom(hs->key_share_ciphertext) ||
89*8fb009dcSAndroid Build Coastguard Worker           !hints->key_share_secret.CopyFrom(secret)) {
90*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
91*8fb009dcSAndroid Build Coastguard Worker         return false;
92*8fb009dcSAndroid Build Coastguard Worker       }
93*8fb009dcSAndroid Build Coastguard Worker     }
94*8fb009dcSAndroid Build Coastguard Worker   }
95*8fb009dcSAndroid Build Coastguard Worker 
96*8fb009dcSAndroid Build Coastguard Worker   return tls13_advance_key_schedule(hs, secret);
97*8fb009dcSAndroid Build Coastguard Worker }
98*8fb009dcSAndroid Build Coastguard Worker 
ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE * hs,CBB * out)99*8fb009dcSAndroid Build Coastguard Worker static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs,
100*8fb009dcSAndroid Build Coastguard Worker                                                       CBB *out) {
101*8fb009dcSAndroid Build Coastguard Worker   CBB contents;
102*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
103*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(out, &contents) ||
104*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&contents, hs->ssl->version) ||
105*8fb009dcSAndroid Build Coastguard Worker       !CBB_flush(out)) {
106*8fb009dcSAndroid Build Coastguard Worker     return 0;
107*8fb009dcSAndroid Build Coastguard Worker   }
108*8fb009dcSAndroid Build Coastguard Worker 
109*8fb009dcSAndroid Build Coastguard Worker   return 1;
110*8fb009dcSAndroid Build Coastguard Worker }
111*8fb009dcSAndroid Build Coastguard Worker 
choose_tls13_cipher(const SSL * ssl,const SSL_CLIENT_HELLO * client_hello)112*8fb009dcSAndroid Build Coastguard Worker static const SSL_CIPHER *choose_tls13_cipher(
113*8fb009dcSAndroid Build Coastguard Worker     const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
114*8fb009dcSAndroid Build Coastguard Worker   CBS cipher_suites;
115*8fb009dcSAndroid Build Coastguard Worker   CBS_init(&cipher_suites, client_hello->cipher_suites,
116*8fb009dcSAndroid Build Coastguard Worker            client_hello->cipher_suites_len);
117*8fb009dcSAndroid Build Coastguard Worker 
118*8fb009dcSAndroid Build Coastguard Worker   const uint16_t version = ssl_protocol_version(ssl);
119*8fb009dcSAndroid Build Coastguard Worker 
120*8fb009dcSAndroid Build Coastguard Worker   return ssl_choose_tls13_cipher(cipher_suites,
121*8fb009dcSAndroid Build Coastguard Worker                                  ssl->config->aes_hw_override
122*8fb009dcSAndroid Build Coastguard Worker                                      ? ssl->config->aes_hw_override_value
123*8fb009dcSAndroid Build Coastguard Worker                                      : EVP_has_aes_hardware(),
124*8fb009dcSAndroid Build Coastguard Worker                                  version, ssl->config->tls13_cipher_policy);
125*8fb009dcSAndroid Build Coastguard Worker }
126*8fb009dcSAndroid Build Coastguard Worker 
add_new_session_tickets(SSL_HANDSHAKE * hs,bool * out_sent_tickets)127*8fb009dcSAndroid Build Coastguard Worker static bool add_new_session_tickets(SSL_HANDSHAKE *hs, bool *out_sent_tickets) {
128*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
129*8fb009dcSAndroid Build Coastguard Worker   if (// If the client doesn't accept resumption with PSK_DHE_KE, don't send a
130*8fb009dcSAndroid Build Coastguard Worker       // session ticket.
131*8fb009dcSAndroid Build Coastguard Worker       !hs->accept_psk_mode ||
132*8fb009dcSAndroid Build Coastguard Worker       // We only implement stateless resumption in TLS 1.3, so skip sending
133*8fb009dcSAndroid Build Coastguard Worker       // tickets if disabled.
134*8fb009dcSAndroid Build Coastguard Worker       (SSL_get_options(ssl) & SSL_OP_NO_TICKET)) {
135*8fb009dcSAndroid Build Coastguard Worker     *out_sent_tickets = false;
136*8fb009dcSAndroid Build Coastguard Worker     return true;
137*8fb009dcSAndroid Build Coastguard Worker   }
138*8fb009dcSAndroid Build Coastguard Worker 
139*8fb009dcSAndroid Build Coastguard Worker   // Rebase the session timestamp so that it is measured from ticket
140*8fb009dcSAndroid Build Coastguard Worker   // issuance.
141*8fb009dcSAndroid Build Coastguard Worker   ssl_session_rebase_time(ssl, hs->new_session.get());
142*8fb009dcSAndroid Build Coastguard Worker 
143*8fb009dcSAndroid Build Coastguard Worker   assert(ssl->session_ctx->num_tickets <= kMaxTickets);
144*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < ssl->session_ctx->num_tickets; i++) {
145*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<SSL_SESSION> session(
146*8fb009dcSAndroid Build Coastguard Worker         SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH));
147*8fb009dcSAndroid Build Coastguard Worker     if (!session) {
148*8fb009dcSAndroid Build Coastguard Worker       return false;
149*8fb009dcSAndroid Build Coastguard Worker     }
150*8fb009dcSAndroid Build Coastguard Worker 
151*8fb009dcSAndroid Build Coastguard Worker     if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) {
152*8fb009dcSAndroid Build Coastguard Worker       return false;
153*8fb009dcSAndroid Build Coastguard Worker     }
154*8fb009dcSAndroid Build Coastguard Worker     session->ticket_age_add_valid = true;
155*8fb009dcSAndroid Build Coastguard Worker     bool enable_early_data =
156*8fb009dcSAndroid Build Coastguard Worker         ssl->enable_early_data &&
157*8fb009dcSAndroid Build Coastguard Worker         (!ssl->quic_method || !ssl->config->quic_early_data_context.empty());
158*8fb009dcSAndroid Build Coastguard Worker     if (enable_early_data) {
159*8fb009dcSAndroid Build Coastguard Worker       // QUIC does not use the max_early_data_size parameter and always sets it
160*8fb009dcSAndroid Build Coastguard Worker       // to a fixed value. See RFC 9001, section 4.6.1.
161*8fb009dcSAndroid Build Coastguard Worker       session->ticket_max_early_data =
162*8fb009dcSAndroid Build Coastguard Worker           ssl->quic_method != nullptr ? 0xffffffff : kMaxEarlyDataAccepted;
163*8fb009dcSAndroid Build Coastguard Worker     }
164*8fb009dcSAndroid Build Coastguard Worker 
165*8fb009dcSAndroid Build Coastguard Worker     static_assert(kMaxTickets < 256, "Too many tickets");
166*8fb009dcSAndroid Build Coastguard Worker     assert(i < 256);
167*8fb009dcSAndroid Build Coastguard Worker     uint8_t nonce[] = {static_cast<uint8_t>(i)};
168*8fb009dcSAndroid Build Coastguard Worker 
169*8fb009dcSAndroid Build Coastguard Worker     ScopedCBB cbb;
170*8fb009dcSAndroid Build Coastguard Worker     CBB body, nonce_cbb, ticket, extensions;
171*8fb009dcSAndroid Build Coastguard Worker     if (!ssl->method->init_message(ssl, cbb.get(), &body,
172*8fb009dcSAndroid Build Coastguard Worker                                    SSL3_MT_NEW_SESSION_TICKET) ||
173*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u32(&body, session->timeout) ||
174*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u32(&body, session->ticket_age_add) ||
175*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u8_length_prefixed(&body, &nonce_cbb) ||
176*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) ||
177*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&body, &ticket) ||
178*8fb009dcSAndroid Build Coastguard Worker         !tls13_derive_session_psk(session.get(), nonce) ||
179*8fb009dcSAndroid Build Coastguard Worker         !ssl_encrypt_ticket(hs, &ticket, session.get()) ||
180*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&body, &extensions)) {
181*8fb009dcSAndroid Build Coastguard Worker       return false;
182*8fb009dcSAndroid Build Coastguard Worker     }
183*8fb009dcSAndroid Build Coastguard Worker 
184*8fb009dcSAndroid Build Coastguard Worker     if (enable_early_data) {
185*8fb009dcSAndroid Build Coastguard Worker       CBB early_data;
186*8fb009dcSAndroid Build Coastguard Worker       if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) ||
187*8fb009dcSAndroid Build Coastguard Worker           !CBB_add_u16_length_prefixed(&extensions, &early_data) ||
188*8fb009dcSAndroid Build Coastguard Worker           !CBB_add_u32(&early_data, session->ticket_max_early_data) ||
189*8fb009dcSAndroid Build Coastguard Worker           !CBB_flush(&extensions)) {
190*8fb009dcSAndroid Build Coastguard Worker         return false;
191*8fb009dcSAndroid Build Coastguard Worker       }
192*8fb009dcSAndroid Build Coastguard Worker     }
193*8fb009dcSAndroid Build Coastguard Worker 
194*8fb009dcSAndroid Build Coastguard Worker     // Add a fake extension. See RFC 8701.
195*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&extensions,
196*8fb009dcSAndroid Build Coastguard Worker                      ssl_get_grease_value(hs, ssl_grease_ticket_extension)) ||
197*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16(&extensions, 0 /* empty */)) {
198*8fb009dcSAndroid Build Coastguard Worker       return false;
199*8fb009dcSAndroid Build Coastguard Worker     }
200*8fb009dcSAndroid Build Coastguard Worker 
201*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_add_message_cbb(ssl, cbb.get())) {
202*8fb009dcSAndroid Build Coastguard Worker       return false;
203*8fb009dcSAndroid Build Coastguard Worker     }
204*8fb009dcSAndroid Build Coastguard Worker   }
205*8fb009dcSAndroid Build Coastguard Worker 
206*8fb009dcSAndroid Build Coastguard Worker   *out_sent_tickets = true;
207*8fb009dcSAndroid Build Coastguard Worker   return true;
208*8fb009dcSAndroid Build Coastguard Worker }
209*8fb009dcSAndroid Build Coastguard Worker 
check_credential(SSL_HANDSHAKE * hs,const SSL_CREDENTIAL * cred,uint16_t * out_sigalg)210*8fb009dcSAndroid Build Coastguard Worker static bool check_credential(SSL_HANDSHAKE *hs, const SSL_CREDENTIAL *cred,
211*8fb009dcSAndroid Build Coastguard Worker                              uint16_t *out_sigalg) {
212*8fb009dcSAndroid Build Coastguard Worker   switch (cred->type) {
213*8fb009dcSAndroid Build Coastguard Worker     case SSLCredentialType::kX509:
214*8fb009dcSAndroid Build Coastguard Worker       break;
215*8fb009dcSAndroid Build Coastguard Worker     case SSLCredentialType::kDelegated:
216*8fb009dcSAndroid Build Coastguard Worker       // Check that the peer supports the signature over the delegated
217*8fb009dcSAndroid Build Coastguard Worker       // credential.
218*8fb009dcSAndroid Build Coastguard Worker       if (std::find(hs->peer_sigalgs.begin(), hs->peer_sigalgs.end(),
219*8fb009dcSAndroid Build Coastguard Worker                     cred->dc_algorithm) == hs->peer_sigalgs.end()) {
220*8fb009dcSAndroid Build Coastguard Worker         OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
221*8fb009dcSAndroid Build Coastguard Worker         return false;
222*8fb009dcSAndroid Build Coastguard Worker       }
223*8fb009dcSAndroid Build Coastguard Worker       break;
224*8fb009dcSAndroid Build Coastguard Worker   }
225*8fb009dcSAndroid Build Coastguard Worker 
226*8fb009dcSAndroid Build Coastguard Worker   // All currently supported credentials require a signature. If |cred| is a
227*8fb009dcSAndroid Build Coastguard Worker   // delegated credential, this also checks that the peer supports delegated
228*8fb009dcSAndroid Build Coastguard Worker   // credentials and matched |dc_cert_verify_algorithm|.
229*8fb009dcSAndroid Build Coastguard Worker   return tls1_choose_signature_algorithm(hs, cred, out_sigalg);
230*8fb009dcSAndroid Build Coastguard Worker }
231*8fb009dcSAndroid Build Coastguard Worker 
do_select_parameters(SSL_HANDSHAKE * hs)232*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
233*8fb009dcSAndroid Build Coastguard Worker   // At this point, most ClientHello extensions have already been processed by
234*8fb009dcSAndroid Build Coastguard Worker   // the common handshake logic. Resolve the remaining non-PSK parameters.
235*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
236*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
237*8fb009dcSAndroid Build Coastguard Worker   SSL_CLIENT_HELLO client_hello;
238*8fb009dcSAndroid Build Coastguard Worker   if (!hs->GetClientHello(&msg, &client_hello)) {
239*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
240*8fb009dcSAndroid Build Coastguard Worker   }
241*8fb009dcSAndroid Build Coastguard Worker 
242*8fb009dcSAndroid Build Coastguard Worker   if (ssl->quic_method != nullptr && client_hello.session_id_len > 0) {
243*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_COMPATIBILITY_MODE);
244*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
245*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
246*8fb009dcSAndroid Build Coastguard Worker   }
247*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memcpy(hs->session_id, client_hello.session_id,
248*8fb009dcSAndroid Build Coastguard Worker                  client_hello.session_id_len);
249*8fb009dcSAndroid Build Coastguard Worker   hs->session_id_len = client_hello.session_id_len;
250*8fb009dcSAndroid Build Coastguard Worker 
251*8fb009dcSAndroid Build Coastguard Worker   Array<SSL_CREDENTIAL *> creds;
252*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_get_credential_list(hs, &creds)) {
253*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
254*8fb009dcSAndroid Build Coastguard Worker   }
255*8fb009dcSAndroid Build Coastguard Worker   if (creds.empty()) {
256*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
257*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
258*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
259*8fb009dcSAndroid Build Coastguard Worker   }
260*8fb009dcSAndroid Build Coastguard Worker 
261*8fb009dcSAndroid Build Coastguard Worker   // Select the credential to use.
262*8fb009dcSAndroid Build Coastguard Worker   for (SSL_CREDENTIAL *cred : creds) {
263*8fb009dcSAndroid Build Coastguard Worker     ERR_clear_error();
264*8fb009dcSAndroid Build Coastguard Worker     uint16_t sigalg;
265*8fb009dcSAndroid Build Coastguard Worker     if (check_credential(hs, cred, &sigalg)) {
266*8fb009dcSAndroid Build Coastguard Worker       hs->credential = UpRef(cred);
267*8fb009dcSAndroid Build Coastguard Worker       hs->signature_algorithm = sigalg;
268*8fb009dcSAndroid Build Coastguard Worker       break;
269*8fb009dcSAndroid Build Coastguard Worker     }
270*8fb009dcSAndroid Build Coastguard Worker   }
271*8fb009dcSAndroid Build Coastguard Worker   if (hs->credential == nullptr) {
272*8fb009dcSAndroid Build Coastguard Worker     // The error from the last attempt is in the error queue.
273*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
274*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
275*8fb009dcSAndroid Build Coastguard Worker   }
276*8fb009dcSAndroid Build Coastguard Worker 
277*8fb009dcSAndroid Build Coastguard Worker   // Negotiate the cipher suite.
278*8fb009dcSAndroid Build Coastguard Worker   hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
279*8fb009dcSAndroid Build Coastguard Worker   if (hs->new_cipher == NULL) {
280*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
281*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
282*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
283*8fb009dcSAndroid Build Coastguard Worker   }
284*8fb009dcSAndroid Build Coastguard Worker 
285*8fb009dcSAndroid Build Coastguard Worker   // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
286*8fb009dcSAndroid Build Coastguard Worker   // deferred. Complete it now.
287*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert = SSL_AD_DECODE_ERROR;
288*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
289*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
290*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
291*8fb009dcSAndroid Build Coastguard Worker   }
292*8fb009dcSAndroid Build Coastguard Worker 
293*8fb009dcSAndroid Build Coastguard Worker   // The PRF hash is now known.
294*8fb009dcSAndroid Build Coastguard Worker   if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) {
295*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
296*8fb009dcSAndroid Build Coastguard Worker   }
297*8fb009dcSAndroid Build Coastguard Worker 
298*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_select_session;
299*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
300*8fb009dcSAndroid Build Coastguard Worker }
301*8fb009dcSAndroid Build Coastguard Worker 
select_session(SSL_HANDSHAKE * hs,uint8_t * out_alert,UniquePtr<SSL_SESSION> * out_session,int32_t * out_ticket_age_skew,bool * out_offered_ticket,const SSLMessage & msg,const SSL_CLIENT_HELLO * client_hello)302*8fb009dcSAndroid Build Coastguard Worker static enum ssl_ticket_aead_result_t select_session(
303*8fb009dcSAndroid Build Coastguard Worker     SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
304*8fb009dcSAndroid Build Coastguard Worker     int32_t *out_ticket_age_skew, bool *out_offered_ticket,
305*8fb009dcSAndroid Build Coastguard Worker     const SSLMessage &msg, const SSL_CLIENT_HELLO *client_hello) {
306*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
307*8fb009dcSAndroid Build Coastguard Worker   *out_session = nullptr;
308*8fb009dcSAndroid Build Coastguard Worker 
309*8fb009dcSAndroid Build Coastguard Worker   CBS pre_shared_key;
310*8fb009dcSAndroid Build Coastguard Worker   *out_offered_ticket = ssl_client_hello_get_extension(
311*8fb009dcSAndroid Build Coastguard Worker       client_hello, &pre_shared_key, TLSEXT_TYPE_pre_shared_key);
312*8fb009dcSAndroid Build Coastguard Worker   if (!*out_offered_ticket) {
313*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_ignore_ticket;
314*8fb009dcSAndroid Build Coastguard Worker   }
315*8fb009dcSAndroid Build Coastguard Worker 
316*8fb009dcSAndroid Build Coastguard Worker   // Per RFC 8446, section 4.2.9, servers MUST abort the handshake if the client
317*8fb009dcSAndroid Build Coastguard Worker   // sends pre_shared_key without psk_key_exchange_modes.
318*8fb009dcSAndroid Build Coastguard Worker   CBS unused;
319*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_client_hello_get_extension(client_hello, &unused,
320*8fb009dcSAndroid Build Coastguard Worker                                       TLSEXT_TYPE_psk_key_exchange_modes)) {
321*8fb009dcSAndroid Build Coastguard Worker     *out_alert = SSL_AD_MISSING_EXTENSION;
322*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
323*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_error;
324*8fb009dcSAndroid Build Coastguard Worker   }
325*8fb009dcSAndroid Build Coastguard Worker 
326*8fb009dcSAndroid Build Coastguard Worker   CBS ticket, binders;
327*8fb009dcSAndroid Build Coastguard Worker   uint32_t client_ticket_age;
328*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ext_pre_shared_key_parse_clienthello(
329*8fb009dcSAndroid Build Coastguard Worker           hs, &ticket, &binders, &client_ticket_age, out_alert, client_hello,
330*8fb009dcSAndroid Build Coastguard Worker           &pre_shared_key)) {
331*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_error;
332*8fb009dcSAndroid Build Coastguard Worker   }
333*8fb009dcSAndroid Build Coastguard Worker 
334*8fb009dcSAndroid Build Coastguard Worker   // If the peer did not offer psk_dhe, ignore the resumption.
335*8fb009dcSAndroid Build Coastguard Worker   if (!hs->accept_psk_mode) {
336*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_ignore_ticket;
337*8fb009dcSAndroid Build Coastguard Worker   }
338*8fb009dcSAndroid Build Coastguard Worker 
339*8fb009dcSAndroid Build Coastguard Worker   // TLS 1.3 session tickets are renewed separately as part of the
340*8fb009dcSAndroid Build Coastguard Worker   // NewSessionTicket.
341*8fb009dcSAndroid Build Coastguard Worker   bool unused_renew;
342*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL_SESSION> session;
343*8fb009dcSAndroid Build Coastguard Worker   enum ssl_ticket_aead_result_t ret =
344*8fb009dcSAndroid Build Coastguard Worker       ssl_process_ticket(hs, &session, &unused_renew, ticket, {});
345*8fb009dcSAndroid Build Coastguard Worker   switch (ret) {
346*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_success:
347*8fb009dcSAndroid Build Coastguard Worker       break;
348*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_error:
349*8fb009dcSAndroid Build Coastguard Worker       *out_alert = SSL_AD_INTERNAL_ERROR;
350*8fb009dcSAndroid Build Coastguard Worker       return ret;
351*8fb009dcSAndroid Build Coastguard Worker     default:
352*8fb009dcSAndroid Build Coastguard Worker       return ret;
353*8fb009dcSAndroid Build Coastguard Worker   }
354*8fb009dcSAndroid Build Coastguard Worker 
355*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_session_is_resumable(hs, session.get()) ||
356*8fb009dcSAndroid Build Coastguard Worker       // Historically, some TLS 1.3 tickets were missing ticket_age_add.
357*8fb009dcSAndroid Build Coastguard Worker       !session->ticket_age_add_valid) {
358*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_ignore_ticket;
359*8fb009dcSAndroid Build Coastguard Worker   }
360*8fb009dcSAndroid Build Coastguard Worker 
361*8fb009dcSAndroid Build Coastguard Worker   // Recover the client ticket age and convert to seconds.
362*8fb009dcSAndroid Build Coastguard Worker   client_ticket_age -= session->ticket_age_add;
363*8fb009dcSAndroid Build Coastguard Worker   client_ticket_age /= 1000;
364*8fb009dcSAndroid Build Coastguard Worker 
365*8fb009dcSAndroid Build Coastguard Worker   struct OPENSSL_timeval now;
366*8fb009dcSAndroid Build Coastguard Worker   ssl_get_current_time(ssl, &now);
367*8fb009dcSAndroid Build Coastguard Worker 
368*8fb009dcSAndroid Build Coastguard Worker   // Compute the server ticket age in seconds.
369*8fb009dcSAndroid Build Coastguard Worker   assert(now.tv_sec >= session->time);
370*8fb009dcSAndroid Build Coastguard Worker   uint64_t server_ticket_age = now.tv_sec - session->time;
371*8fb009dcSAndroid Build Coastguard Worker 
372*8fb009dcSAndroid Build Coastguard Worker   // To avoid overflowing |hs->ticket_age_skew|, we will not resume
373*8fb009dcSAndroid Build Coastguard Worker   // 68-year-old sessions.
374*8fb009dcSAndroid Build Coastguard Worker   if (server_ticket_age > INT32_MAX) {
375*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_ignore_ticket;
376*8fb009dcSAndroid Build Coastguard Worker   }
377*8fb009dcSAndroid Build Coastguard Worker 
378*8fb009dcSAndroid Build Coastguard Worker   *out_ticket_age_skew = static_cast<int32_t>(client_ticket_age) -
379*8fb009dcSAndroid Build Coastguard Worker                          static_cast<int32_t>(server_ticket_age);
380*8fb009dcSAndroid Build Coastguard Worker 
381*8fb009dcSAndroid Build Coastguard Worker   // Check the PSK binder.
382*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) {
383*8fb009dcSAndroid Build Coastguard Worker     *out_alert = SSL_AD_DECRYPT_ERROR;
384*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_error;
385*8fb009dcSAndroid Build Coastguard Worker   }
386*8fb009dcSAndroid Build Coastguard Worker 
387*8fb009dcSAndroid Build Coastguard Worker   *out_session = std::move(session);
388*8fb009dcSAndroid Build Coastguard Worker   return ssl_ticket_aead_success;
389*8fb009dcSAndroid Build Coastguard Worker }
390*8fb009dcSAndroid Build Coastguard Worker 
quic_ticket_compatible(const SSL_SESSION * session,const SSL_CONFIG * config)391*8fb009dcSAndroid Build Coastguard Worker static bool quic_ticket_compatible(const SSL_SESSION *session,
392*8fb009dcSAndroid Build Coastguard Worker                                    const SSL_CONFIG *config) {
393*8fb009dcSAndroid Build Coastguard Worker   if (!session->is_quic) {
394*8fb009dcSAndroid Build Coastguard Worker     return true;
395*8fb009dcSAndroid Build Coastguard Worker   }
396*8fb009dcSAndroid Build Coastguard Worker 
397*8fb009dcSAndroid Build Coastguard Worker   if (session->quic_early_data_context.empty() ||
398*8fb009dcSAndroid Build Coastguard Worker       config->quic_early_data_context.size() !=
399*8fb009dcSAndroid Build Coastguard Worker           session->quic_early_data_context.size() ||
400*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_memcmp(config->quic_early_data_context.data(),
401*8fb009dcSAndroid Build Coastguard Worker                     session->quic_early_data_context.data(),
402*8fb009dcSAndroid Build Coastguard Worker                     session->quic_early_data_context.size()) != 0) {
403*8fb009dcSAndroid Build Coastguard Worker     return false;
404*8fb009dcSAndroid Build Coastguard Worker   }
405*8fb009dcSAndroid Build Coastguard Worker   return true;
406*8fb009dcSAndroid Build Coastguard Worker }
407*8fb009dcSAndroid Build Coastguard Worker 
do_select_session(SSL_HANDSHAKE * hs)408*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
409*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
410*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
411*8fb009dcSAndroid Build Coastguard Worker   SSL_CLIENT_HELLO client_hello;
412*8fb009dcSAndroid Build Coastguard Worker   if (!hs->GetClientHello(&msg, &client_hello)) {
413*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
414*8fb009dcSAndroid Build Coastguard Worker   }
415*8fb009dcSAndroid Build Coastguard Worker 
416*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert = SSL_AD_DECODE_ERROR;
417*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL_SESSION> session;
418*8fb009dcSAndroid Build Coastguard Worker   bool offered_ticket = false;
419*8fb009dcSAndroid Build Coastguard Worker   switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew,
420*8fb009dcSAndroid Build Coastguard Worker                          &offered_ticket, msg, &client_hello)) {
421*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_ignore_ticket:
422*8fb009dcSAndroid Build Coastguard Worker       assert(!session);
423*8fb009dcSAndroid Build Coastguard Worker       if (!ssl_get_new_session(hs)) {
424*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
425*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_error;
426*8fb009dcSAndroid Build Coastguard Worker       }
427*8fb009dcSAndroid Build Coastguard Worker       break;
428*8fb009dcSAndroid Build Coastguard Worker 
429*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_success:
430*8fb009dcSAndroid Build Coastguard Worker       // Carry over authentication information from the previous handshake into
431*8fb009dcSAndroid Build Coastguard Worker       // a fresh session.
432*8fb009dcSAndroid Build Coastguard Worker       hs->new_session =
433*8fb009dcSAndroid Build Coastguard Worker           SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
434*8fb009dcSAndroid Build Coastguard Worker       if (hs->new_session == nullptr) {
435*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
436*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_error;
437*8fb009dcSAndroid Build Coastguard Worker       }
438*8fb009dcSAndroid Build Coastguard Worker 
439*8fb009dcSAndroid Build Coastguard Worker       ssl->s3->session_reused = true;
440*8fb009dcSAndroid Build Coastguard Worker       hs->can_release_private_key = true;
441*8fb009dcSAndroid Build Coastguard Worker 
442*8fb009dcSAndroid Build Coastguard Worker       // Resumption incorporates fresh key material, so refresh the timeout.
443*8fb009dcSAndroid Build Coastguard Worker       ssl_session_renew_timeout(ssl, hs->new_session.get(),
444*8fb009dcSAndroid Build Coastguard Worker                                 ssl->session_ctx->session_psk_dhe_timeout);
445*8fb009dcSAndroid Build Coastguard Worker       break;
446*8fb009dcSAndroid Build Coastguard Worker 
447*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_error:
448*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
449*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
450*8fb009dcSAndroid Build Coastguard Worker 
451*8fb009dcSAndroid Build Coastguard Worker     case ssl_ticket_aead_retry:
452*8fb009dcSAndroid Build Coastguard Worker       hs->tls13_state = state13_select_session;
453*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_pending_ticket;
454*8fb009dcSAndroid Build Coastguard Worker   }
455*8fb009dcSAndroid Build Coastguard Worker 
456*8fb009dcSAndroid Build Coastguard Worker   // Negotiate ALPS now, after ALPN is negotiated and |hs->new_session| is
457*8fb009dcSAndroid Build Coastguard Worker   // initialized.
458*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_negotiate_alps(hs, &alert, &client_hello)) {
459*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
460*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
461*8fb009dcSAndroid Build Coastguard Worker   }
462*8fb009dcSAndroid Build Coastguard Worker 
463*8fb009dcSAndroid Build Coastguard Worker   // Record connection properties in the new session.
464*8fb009dcSAndroid Build Coastguard Worker   hs->new_session->cipher = hs->new_cipher;
465*8fb009dcSAndroid Build Coastguard Worker   if (!tls1_get_shared_group(hs, &hs->new_session->group_id)) {
466*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP);
467*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
468*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
469*8fb009dcSAndroid Build Coastguard Worker   }
470*8fb009dcSAndroid Build Coastguard Worker 
471*8fb009dcSAndroid Build Coastguard Worker   // Determine if we need HelloRetryRequest.
472*8fb009dcSAndroid Build Coastguard Worker   bool found_key_share;
473*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share,
474*8fb009dcSAndroid Build Coastguard Worker                                            /*out_key_share=*/nullptr, &alert,
475*8fb009dcSAndroid Build Coastguard Worker                                            &client_hello)) {
476*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
477*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
478*8fb009dcSAndroid Build Coastguard Worker   }
479*8fb009dcSAndroid Build Coastguard Worker 
480*8fb009dcSAndroid Build Coastguard Worker   // Determine if we're negotiating 0-RTT.
481*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->enable_early_data) {
482*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_disabled;
483*8fb009dcSAndroid Build Coastguard Worker   } else if (!offered_ticket) {
484*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_no_session_offered;
485*8fb009dcSAndroid Build Coastguard Worker   } else if (!session) {
486*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_session_not_resumed;
487*8fb009dcSAndroid Build Coastguard Worker   } else if (session->ticket_max_early_data == 0) {
488*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_unsupported_for_session;
489*8fb009dcSAndroid Build Coastguard Worker   } else if (!hs->early_data_offered) {
490*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_peer_declined;
491*8fb009dcSAndroid Build Coastguard Worker   } else if (hs->channel_id_negotiated) {
492*8fb009dcSAndroid Build Coastguard Worker     // Channel ID is incompatible with 0-RTT.
493*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_channel_id;
494*8fb009dcSAndroid Build Coastguard Worker   } else if (MakeConstSpan(ssl->s3->alpn_selected) != session->early_alpn) {
495*8fb009dcSAndroid Build Coastguard Worker     // The negotiated ALPN must match the one in the ticket.
496*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_alpn_mismatch;
497*8fb009dcSAndroid Build Coastguard Worker   } else if (hs->new_session->has_application_settings !=
498*8fb009dcSAndroid Build Coastguard Worker                  session->has_application_settings ||
499*8fb009dcSAndroid Build Coastguard Worker              MakeConstSpan(hs->new_session->local_application_settings) !=
500*8fb009dcSAndroid Build Coastguard Worker                  session->local_application_settings) {
501*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_alps_mismatch;
502*8fb009dcSAndroid Build Coastguard Worker   } else if (ssl->s3->ticket_age_skew < -kMaxTicketAgeSkewSeconds ||
503*8fb009dcSAndroid Build Coastguard Worker              kMaxTicketAgeSkewSeconds < ssl->s3->ticket_age_skew) {
504*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_ticket_age_skew;
505*8fb009dcSAndroid Build Coastguard Worker   } else if (!quic_ticket_compatible(session.get(), hs->config)) {
506*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_quic_parameter_mismatch;
507*8fb009dcSAndroid Build Coastguard Worker   } else if (!found_key_share) {
508*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_hello_retry_request;
509*8fb009dcSAndroid Build Coastguard Worker   } else {
510*8fb009dcSAndroid Build Coastguard Worker     // |ssl_session_is_resumable| forbids cross-cipher resumptions even if the
511*8fb009dcSAndroid Build Coastguard Worker     // PRF hashes match.
512*8fb009dcSAndroid Build Coastguard Worker     assert(hs->new_cipher == session->cipher);
513*8fb009dcSAndroid Build Coastguard Worker 
514*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_reason = ssl_early_data_accepted;
515*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->early_data_accepted = true;
516*8fb009dcSAndroid Build Coastguard Worker   }
517*8fb009dcSAndroid Build Coastguard Worker 
518*8fb009dcSAndroid Build Coastguard Worker   // Store the ALPN and ALPS values in the session for 0-RTT. Note the peer
519*8fb009dcSAndroid Build Coastguard Worker   // applications settings are not generally known until client
520*8fb009dcSAndroid Build Coastguard Worker   // EncryptedExtensions.
521*8fb009dcSAndroid Build Coastguard Worker   if (!hs->new_session->early_alpn.CopyFrom(ssl->s3->alpn_selected)) {
522*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
523*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
524*8fb009dcSAndroid Build Coastguard Worker   }
525*8fb009dcSAndroid Build Coastguard Worker 
526*8fb009dcSAndroid Build Coastguard Worker   // The peer applications settings are usually received later, in
527*8fb009dcSAndroid Build Coastguard Worker   // EncryptedExtensions. But, in 0-RTT handshakes, we carry over the
528*8fb009dcSAndroid Build Coastguard Worker   // values from |session|. Do this now, before |session| is discarded.
529*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->early_data_accepted &&
530*8fb009dcSAndroid Build Coastguard Worker       hs->new_session->has_application_settings &&
531*8fb009dcSAndroid Build Coastguard Worker       !hs->new_session->peer_application_settings.CopyFrom(
532*8fb009dcSAndroid Build Coastguard Worker           session->peer_application_settings)) {
533*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
534*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
535*8fb009dcSAndroid Build Coastguard Worker   }
536*8fb009dcSAndroid Build Coastguard Worker 
537*8fb009dcSAndroid Build Coastguard Worker   // Copy the QUIC early data context to the session.
538*8fb009dcSAndroid Build Coastguard Worker   if (ssl->enable_early_data && ssl->quic_method) {
539*8fb009dcSAndroid Build Coastguard Worker     if (!hs->new_session->quic_early_data_context.CopyFrom(
540*8fb009dcSAndroid Build Coastguard Worker             hs->config->quic_early_data_context)) {
541*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
542*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
543*8fb009dcSAndroid Build Coastguard Worker     }
544*8fb009dcSAndroid Build Coastguard Worker   }
545*8fb009dcSAndroid Build Coastguard Worker 
546*8fb009dcSAndroid Build Coastguard Worker   if (ssl->ctx->dos_protection_cb != NULL &&
547*8fb009dcSAndroid Build Coastguard Worker       ssl->ctx->dos_protection_cb(&client_hello) == 0) {
548*8fb009dcSAndroid Build Coastguard Worker     // Connection rejected for DOS reasons.
549*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
550*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
551*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
552*8fb009dcSAndroid Build Coastguard Worker   }
553*8fb009dcSAndroid Build Coastguard Worker 
554*8fb009dcSAndroid Build Coastguard Worker   size_t hash_len = EVP_MD_size(
555*8fb009dcSAndroid Build Coastguard Worker       ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher));
556*8fb009dcSAndroid Build Coastguard Worker 
557*8fb009dcSAndroid Build Coastguard Worker   // Set up the key schedule and incorporate the PSK into the running secret.
558*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_init_key_schedule(
559*8fb009dcSAndroid Build Coastguard Worker           hs, ssl->s3->session_reused
560*8fb009dcSAndroid Build Coastguard Worker                   ? MakeConstSpan(hs->new_session->secret,
561*8fb009dcSAndroid Build Coastguard Worker                                   hs->new_session->secret_length)
562*8fb009dcSAndroid Build Coastguard Worker                   : MakeConstSpan(kZeroes, hash_len)) ||
563*8fb009dcSAndroid Build Coastguard Worker       !ssl_hash_message(hs, msg)) {
564*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
565*8fb009dcSAndroid Build Coastguard Worker   }
566*8fb009dcSAndroid Build Coastguard Worker 
567*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->early_data_accepted) {
568*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_derive_early_secret(hs)) {
569*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
570*8fb009dcSAndroid Build Coastguard Worker     }
571*8fb009dcSAndroid Build Coastguard Worker   } else if (hs->early_data_offered) {
572*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->skip_early_data = true;
573*8fb009dcSAndroid Build Coastguard Worker   }
574*8fb009dcSAndroid Build Coastguard Worker 
575*8fb009dcSAndroid Build Coastguard Worker   if (!found_key_share) {
576*8fb009dcSAndroid Build Coastguard Worker     ssl->method->next_message(ssl);
577*8fb009dcSAndroid Build Coastguard Worker     if (!hs->transcript.UpdateForHelloRetryRequest()) {
578*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
579*8fb009dcSAndroid Build Coastguard Worker     }
580*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_send_hello_retry_request;
581*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_ok;
582*8fb009dcSAndroid Build Coastguard Worker   }
583*8fb009dcSAndroid Build Coastguard Worker 
584*8fb009dcSAndroid Build Coastguard Worker   if (!resolve_ecdhe_secret(hs, &client_hello)) {
585*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
586*8fb009dcSAndroid Build Coastguard Worker   }
587*8fb009dcSAndroid Build Coastguard Worker 
588*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
589*8fb009dcSAndroid Build Coastguard Worker   hs->ech_client_hello_buf.Reset();
590*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_send_server_hello;
591*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
592*8fb009dcSAndroid Build Coastguard Worker }
593*8fb009dcSAndroid Build Coastguard Worker 
do_send_hello_retry_request(SSL_HANDSHAKE * hs)594*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
595*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
596*8fb009dcSAndroid Build Coastguard Worker   if (hs->hints_requested) {
597*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_hints_ready;
598*8fb009dcSAndroid Build Coastguard Worker   }
599*8fb009dcSAndroid Build Coastguard Worker 
600*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
601*8fb009dcSAndroid Build Coastguard Worker   CBB body, session_id, extensions;
602*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
603*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&body, TLS1_2_VERSION) ||
604*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) ||
605*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8_length_prefixed(&body, &session_id) ||
606*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) ||
607*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) ||
608*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8(&body, 0 /* no compression */) ||
609*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&body, &extensions) ||
610*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) ||
611*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, 2 /* length */) ||
612*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, ssl->version) ||
613*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
614*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, 2 /* length */) ||
615*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&extensions, hs->new_session->group_id)) {
616*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
617*8fb009dcSAndroid Build Coastguard Worker   }
618*8fb009dcSAndroid Build Coastguard Worker   if (hs->ech_is_inner) {
619*8fb009dcSAndroid Build Coastguard Worker     // Fill a placeholder for the ECH confirmation value.
620*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&extensions, TLSEXT_TYPE_encrypted_client_hello) ||
621*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16(&extensions, ECH_CONFIRMATION_SIGNAL_LEN) ||
622*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_zeros(&extensions, ECH_CONFIRMATION_SIGNAL_LEN)) {
623*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
624*8fb009dcSAndroid Build Coastguard Worker     }
625*8fb009dcSAndroid Build Coastguard Worker   }
626*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> hrr;
627*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->finish_message(ssl, cbb.get(), &hrr)) {
628*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
629*8fb009dcSAndroid Build Coastguard Worker   }
630*8fb009dcSAndroid Build Coastguard Worker   if (hs->ech_is_inner) {
631*8fb009dcSAndroid Build Coastguard Worker     // Now that the message is encoded, fill in the whole value.
632*8fb009dcSAndroid Build Coastguard Worker     size_t offset = hrr.size() - ECH_CONFIRMATION_SIGNAL_LEN;
633*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_ech_accept_confirmation(
634*8fb009dcSAndroid Build Coastguard Worker             hs, MakeSpan(hrr).last(ECH_CONFIRMATION_SIGNAL_LEN),
635*8fb009dcSAndroid Build Coastguard Worker             ssl->s3->client_random, hs->transcript, /*is_hrr=*/true, hrr,
636*8fb009dcSAndroid Build Coastguard Worker             offset)) {
637*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
638*8fb009dcSAndroid Build Coastguard Worker     }
639*8fb009dcSAndroid Build Coastguard Worker   }
640*8fb009dcSAndroid Build Coastguard Worker 
641*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->add_message(ssl, std::move(hrr)) ||
642*8fb009dcSAndroid Build Coastguard Worker       !ssl->method->add_change_cipher_spec(ssl)) {
643*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
644*8fb009dcSAndroid Build Coastguard Worker   }
645*8fb009dcSAndroid Build Coastguard Worker 
646*8fb009dcSAndroid Build Coastguard Worker   ssl->s3->used_hello_retry_request = true;
647*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_second_client_hello;
648*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_flush;
649*8fb009dcSAndroid Build Coastguard Worker }
650*8fb009dcSAndroid Build Coastguard Worker 
do_read_second_client_hello(SSL_HANDSHAKE * hs)651*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
652*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
653*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
654*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->get_message(ssl, &msg)) {
655*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_read_message;
656*8fb009dcSAndroid Build Coastguard Worker   }
657*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) {
658*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
659*8fb009dcSAndroid Build Coastguard Worker   }
660*8fb009dcSAndroid Build Coastguard Worker   SSL_CLIENT_HELLO client_hello;
661*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_client_hello_init(ssl, &client_hello, msg.body)) {
662*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
663*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
664*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
665*8fb009dcSAndroid Build Coastguard Worker   }
666*8fb009dcSAndroid Build Coastguard Worker 
667*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->ech_status == ssl_ech_accepted) {
668*8fb009dcSAndroid Build Coastguard Worker     // If we previously accepted the ClientHelloInner, the second ClientHello
669*8fb009dcSAndroid Build Coastguard Worker     // must contain an outer encrypted_client_hello extension.
670*8fb009dcSAndroid Build Coastguard Worker     CBS ech_body;
671*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_client_hello_get_extension(&client_hello, &ech_body,
672*8fb009dcSAndroid Build Coastguard Worker                                         TLSEXT_TYPE_encrypted_client_hello)) {
673*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
674*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
675*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
676*8fb009dcSAndroid Build Coastguard Worker     }
677*8fb009dcSAndroid Build Coastguard Worker     uint16_t kdf_id, aead_id;
678*8fb009dcSAndroid Build Coastguard Worker     uint8_t type, config_id;
679*8fb009dcSAndroid Build Coastguard Worker     CBS enc, payload;
680*8fb009dcSAndroid Build Coastguard Worker     if (!CBS_get_u8(&ech_body, &type) ||     //
681*8fb009dcSAndroid Build Coastguard Worker         type != ECH_CLIENT_OUTER ||          //
682*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u16(&ech_body, &kdf_id) ||  //
683*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u16(&ech_body, &aead_id) ||
684*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u8(&ech_body, &config_id) ||
685*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u16_length_prefixed(&ech_body, &enc) ||
686*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u16_length_prefixed(&ech_body, &payload) ||
687*8fb009dcSAndroid Build Coastguard Worker         CBS_len(&ech_body) != 0) {
688*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
689*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
690*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
691*8fb009dcSAndroid Build Coastguard Worker     }
692*8fb009dcSAndroid Build Coastguard Worker 
693*8fb009dcSAndroid Build Coastguard Worker     if (kdf_id != EVP_HPKE_KDF_id(EVP_HPKE_CTX_kdf(hs->ech_hpke_ctx.get())) ||
694*8fb009dcSAndroid Build Coastguard Worker         aead_id !=
695*8fb009dcSAndroid Build Coastguard Worker             EVP_HPKE_AEAD_id(EVP_HPKE_CTX_aead(hs->ech_hpke_ctx.get())) ||
696*8fb009dcSAndroid Build Coastguard Worker         config_id != hs->ech_config_id || CBS_len(&enc) > 0) {
697*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
698*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
699*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
700*8fb009dcSAndroid Build Coastguard Worker     }
701*8fb009dcSAndroid Build Coastguard Worker 
702*8fb009dcSAndroid Build Coastguard Worker     // Decrypt the payload with the HPKE context from the first ClientHello.
703*8fb009dcSAndroid Build Coastguard Worker     uint8_t alert = SSL_AD_DECODE_ERROR;
704*8fb009dcSAndroid Build Coastguard Worker     bool unused;
705*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_client_hello_decrypt(hs, &alert, &unused,
706*8fb009dcSAndroid Build Coastguard Worker                                   &hs->ech_client_hello_buf, &client_hello,
707*8fb009dcSAndroid Build Coastguard Worker                                   payload)) {
708*8fb009dcSAndroid Build Coastguard Worker       // Decryption failure is fatal in the second ClientHello.
709*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
710*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
711*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
712*8fb009dcSAndroid Build Coastguard Worker     }
713*8fb009dcSAndroid Build Coastguard Worker 
714*8fb009dcSAndroid Build Coastguard Worker     // Reparse |client_hello| from the buffer owned by |hs|.
715*8fb009dcSAndroid Build Coastguard Worker     if (!hs->GetClientHello(&msg, &client_hello)) {
716*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
717*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
718*8fb009dcSAndroid Build Coastguard Worker     }
719*8fb009dcSAndroid Build Coastguard Worker   }
720*8fb009dcSAndroid Build Coastguard Worker 
721*8fb009dcSAndroid Build Coastguard Worker   // We perform all our negotiation based on the first ClientHello (for
722*8fb009dcSAndroid Build Coastguard Worker   // consistency with what |select_certificate_cb| observed), which is in the
723*8fb009dcSAndroid Build Coastguard Worker   // transcript, so we can ignore most of this second one.
724*8fb009dcSAndroid Build Coastguard Worker   //
725*8fb009dcSAndroid Build Coastguard Worker   // We do, however, check the second PSK binder. This covers the client key
726*8fb009dcSAndroid Build Coastguard Worker   // share, in case we ever send half-RTT data (we currently do not). It is also
727*8fb009dcSAndroid Build Coastguard Worker   // a tricky computation, so we enforce the peer handled it correctly.
728*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->session_reused) {
729*8fb009dcSAndroid Build Coastguard Worker     CBS pre_shared_key;
730*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_client_hello_get_extension(&client_hello, &pre_shared_key,
731*8fb009dcSAndroid Build Coastguard Worker                                         TLSEXT_TYPE_pre_shared_key)) {
732*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_INCONSISTENT_CLIENT_HELLO);
733*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
734*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
735*8fb009dcSAndroid Build Coastguard Worker     }
736*8fb009dcSAndroid Build Coastguard Worker 
737*8fb009dcSAndroid Build Coastguard Worker     CBS ticket, binders;
738*8fb009dcSAndroid Build Coastguard Worker     uint32_t client_ticket_age;
739*8fb009dcSAndroid Build Coastguard Worker     uint8_t alert = SSL_AD_DECODE_ERROR;
740*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_ext_pre_shared_key_parse_clienthello(
741*8fb009dcSAndroid Build Coastguard Worker             hs, &ticket, &binders, &client_ticket_age, &alert, &client_hello,
742*8fb009dcSAndroid Build Coastguard Worker             &pre_shared_key)) {
743*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
744*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
745*8fb009dcSAndroid Build Coastguard Worker     }
746*8fb009dcSAndroid Build Coastguard Worker 
747*8fb009dcSAndroid Build Coastguard Worker     // Note it is important that we do not obtain a new |SSL_SESSION| from
748*8fb009dcSAndroid Build Coastguard Worker     // |ticket|. We have already selected parameters based on the first
749*8fb009dcSAndroid Build Coastguard Worker     // ClientHello (in the transcript) and must not switch partway through.
750*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_verify_psk_binder(hs, hs->new_session.get(), msg, &binders)) {
751*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
752*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
753*8fb009dcSAndroid Build Coastguard Worker     }
754*8fb009dcSAndroid Build Coastguard Worker   }
755*8fb009dcSAndroid Build Coastguard Worker 
756*8fb009dcSAndroid Build Coastguard Worker   if (!resolve_ecdhe_secret(hs, &client_hello)) {
757*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
758*8fb009dcSAndroid Build Coastguard Worker   }
759*8fb009dcSAndroid Build Coastguard Worker 
760*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_hash_message(hs, msg)) {
761*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
762*8fb009dcSAndroid Build Coastguard Worker   }
763*8fb009dcSAndroid Build Coastguard Worker 
764*8fb009dcSAndroid Build Coastguard Worker   // ClientHello should be the end of the flight.
765*8fb009dcSAndroid Build Coastguard Worker   if (ssl->method->has_unprocessed_handshake_data(ssl)) {
766*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
767*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESS_HANDSHAKE_DATA);
768*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
769*8fb009dcSAndroid Build Coastguard Worker   }
770*8fb009dcSAndroid Build Coastguard Worker 
771*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
772*8fb009dcSAndroid Build Coastguard Worker   hs->ech_client_hello_buf.Reset();
773*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_send_server_hello;
774*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
775*8fb009dcSAndroid Build Coastguard Worker }
776*8fb009dcSAndroid Build Coastguard Worker 
do_send_server_hello(SSL_HANDSHAKE * hs)777*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
778*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
779*8fb009dcSAndroid Build Coastguard Worker 
780*8fb009dcSAndroid Build Coastguard Worker   Span<uint8_t> random(ssl->s3->server_random);
781*8fb009dcSAndroid Build Coastguard Worker 
782*8fb009dcSAndroid Build Coastguard Worker   SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
783*8fb009dcSAndroid Build Coastguard Worker   if (hints && !hs->hints_requested &&
784*8fb009dcSAndroid Build Coastguard Worker       hints->server_random_tls13.size() == random.size()) {
785*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_memcpy(random.data(), hints->server_random_tls13.data(),
786*8fb009dcSAndroid Build Coastguard Worker                    random.size());
787*8fb009dcSAndroid Build Coastguard Worker   } else {
788*8fb009dcSAndroid Build Coastguard Worker     RAND_bytes(random.data(), random.size());
789*8fb009dcSAndroid Build Coastguard Worker     if (hints && hs->hints_requested &&
790*8fb009dcSAndroid Build Coastguard Worker         !hints->server_random_tls13.CopyFrom(random)) {
791*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
792*8fb009dcSAndroid Build Coastguard Worker     }
793*8fb009dcSAndroid Build Coastguard Worker   }
794*8fb009dcSAndroid Build Coastguard Worker 
795*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> server_hello;
796*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
797*8fb009dcSAndroid Build Coastguard Worker   CBB body, extensions, session_id;
798*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
799*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&body, TLS1_2_VERSION) ||
800*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&body, ssl->s3->server_random,
801*8fb009dcSAndroid Build Coastguard Worker                      sizeof(ssl->s3->server_random)) ||
802*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8_length_prefixed(&body, &session_id) ||
803*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) ||
804*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&body, SSL_CIPHER_get_protocol_id(hs->new_cipher)) ||
805*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8(&body, 0) ||
806*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&body, &extensions) ||
807*8fb009dcSAndroid Build Coastguard Worker       !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
808*8fb009dcSAndroid Build Coastguard Worker       !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
809*8fb009dcSAndroid Build Coastguard Worker       !ssl_ext_supported_versions_add_serverhello(hs, &extensions) ||
810*8fb009dcSAndroid Build Coastguard Worker       !ssl->method->finish_message(ssl, cbb.get(), &server_hello)) {
811*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
812*8fb009dcSAndroid Build Coastguard Worker   }
813*8fb009dcSAndroid Build Coastguard Worker 
814*8fb009dcSAndroid Build Coastguard Worker   assert(ssl->s3->ech_status != ssl_ech_accepted || hs->ech_is_inner);
815*8fb009dcSAndroid Build Coastguard Worker   if (hs->ech_is_inner) {
816*8fb009dcSAndroid Build Coastguard Worker     // Fill in the ECH confirmation signal.
817*8fb009dcSAndroid Build Coastguard Worker     const size_t offset = ssl_ech_confirmation_signal_hello_offset(ssl);
818*8fb009dcSAndroid Build Coastguard Worker     Span<uint8_t> random_suffix = random.last(ECH_CONFIRMATION_SIGNAL_LEN);
819*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_ech_accept_confirmation(hs, random_suffix, ssl->s3->client_random,
820*8fb009dcSAndroid Build Coastguard Worker                                      hs->transcript,
821*8fb009dcSAndroid Build Coastguard Worker                                      /*is_hrr=*/false, server_hello, offset)) {
822*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
823*8fb009dcSAndroid Build Coastguard Worker     }
824*8fb009dcSAndroid Build Coastguard Worker 
825*8fb009dcSAndroid Build Coastguard Worker     // Update |server_hello|.
826*8fb009dcSAndroid Build Coastguard Worker     Span<uint8_t> server_hello_out =
827*8fb009dcSAndroid Build Coastguard Worker         MakeSpan(server_hello).subspan(offset, ECH_CONFIRMATION_SIGNAL_LEN);
828*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_memcpy(server_hello_out.data(), random_suffix.data(),
829*8fb009dcSAndroid Build Coastguard Worker                    ECH_CONFIRMATION_SIGNAL_LEN);
830*8fb009dcSAndroid Build Coastguard Worker   }
831*8fb009dcSAndroid Build Coastguard Worker 
832*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->add_message(ssl, std::move(server_hello))) {
833*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
834*8fb009dcSAndroid Build Coastguard Worker   }
835*8fb009dcSAndroid Build Coastguard Worker 
836*8fb009dcSAndroid Build Coastguard Worker   hs->key_share_ciphertext.Reset();  // No longer needed.
837*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->s3->used_hello_retry_request &&
838*8fb009dcSAndroid Build Coastguard Worker       !ssl->method->add_change_cipher_spec(ssl)) {
839*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
840*8fb009dcSAndroid Build Coastguard Worker   }
841*8fb009dcSAndroid Build Coastguard Worker 
842*8fb009dcSAndroid Build Coastguard Worker   // Derive and enable the handshake traffic secrets.
843*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_derive_handshake_secrets(hs) ||
844*8fb009dcSAndroid Build Coastguard Worker       !tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_seal,
845*8fb009dcSAndroid Build Coastguard Worker                              hs->new_session.get(),
846*8fb009dcSAndroid Build Coastguard Worker                              hs->server_handshake_secret())) {
847*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
848*8fb009dcSAndroid Build Coastguard Worker   }
849*8fb009dcSAndroid Build Coastguard Worker 
850*8fb009dcSAndroid Build Coastguard Worker   // Send EncryptedExtensions.
851*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body,
852*8fb009dcSAndroid Build Coastguard Worker                                  SSL3_MT_ENCRYPTED_EXTENSIONS) ||
853*8fb009dcSAndroid Build Coastguard Worker       !ssl_add_serverhello_tlsext(hs, &body) ||
854*8fb009dcSAndroid Build Coastguard Worker       !ssl_add_message_cbb(ssl, cbb.get())) {
855*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
856*8fb009dcSAndroid Build Coastguard Worker   }
857*8fb009dcSAndroid Build Coastguard Worker 
858*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->s3->session_reused) {
859*8fb009dcSAndroid Build Coastguard Worker     // Determine whether to request a client certificate.
860*8fb009dcSAndroid Build Coastguard Worker     hs->cert_request = !!(hs->config->verify_mode & SSL_VERIFY_PEER);
861*8fb009dcSAndroid Build Coastguard Worker     // Only request a certificate if Channel ID isn't negotiated.
862*8fb009dcSAndroid Build Coastguard Worker     if ((hs->config->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
863*8fb009dcSAndroid Build Coastguard Worker         hs->channel_id_negotiated) {
864*8fb009dcSAndroid Build Coastguard Worker       hs->cert_request = false;
865*8fb009dcSAndroid Build Coastguard Worker     }
866*8fb009dcSAndroid Build Coastguard Worker   }
867*8fb009dcSAndroid Build Coastguard Worker 
868*8fb009dcSAndroid Build Coastguard Worker   // Send a CertificateRequest, if necessary.
869*8fb009dcSAndroid Build Coastguard Worker   if (hs->cert_request) {
870*8fb009dcSAndroid Build Coastguard Worker     CBB cert_request_extensions, sigalg_contents, sigalgs_cbb;
871*8fb009dcSAndroid Build Coastguard Worker     if (!ssl->method->init_message(ssl, cbb.get(), &body,
872*8fb009dcSAndroid Build Coastguard Worker                                    SSL3_MT_CERTIFICATE_REQUEST) ||
873*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
874*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) ||
875*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16(&cert_request_extensions,
876*8fb009dcSAndroid Build Coastguard Worker                      TLSEXT_TYPE_signature_algorithms) ||
877*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&cert_request_extensions,
878*8fb009dcSAndroid Build Coastguard Worker                                      &sigalg_contents) ||
879*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) ||
880*8fb009dcSAndroid Build Coastguard Worker         !tls12_add_verify_sigalgs(hs, &sigalgs_cbb)) {
881*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
882*8fb009dcSAndroid Build Coastguard Worker     }
883*8fb009dcSAndroid Build Coastguard Worker 
884*8fb009dcSAndroid Build Coastguard Worker     if (ssl_has_client_CAs(hs->config)) {
885*8fb009dcSAndroid Build Coastguard Worker       CBB ca_contents;
886*8fb009dcSAndroid Build Coastguard Worker       if (!CBB_add_u16(&cert_request_extensions,
887*8fb009dcSAndroid Build Coastguard Worker                        TLSEXT_TYPE_certificate_authorities) ||
888*8fb009dcSAndroid Build Coastguard Worker           !CBB_add_u16_length_prefixed(&cert_request_extensions,
889*8fb009dcSAndroid Build Coastguard Worker                                        &ca_contents) ||
890*8fb009dcSAndroid Build Coastguard Worker           !ssl_add_client_CA_list(hs, &ca_contents) ||
891*8fb009dcSAndroid Build Coastguard Worker           !CBB_flush(&cert_request_extensions)) {
892*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_error;
893*8fb009dcSAndroid Build Coastguard Worker       }
894*8fb009dcSAndroid Build Coastguard Worker     }
895*8fb009dcSAndroid Build Coastguard Worker 
896*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_add_message_cbb(ssl, cbb.get())) {
897*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
898*8fb009dcSAndroid Build Coastguard Worker     }
899*8fb009dcSAndroid Build Coastguard Worker   }
900*8fb009dcSAndroid Build Coastguard Worker 
901*8fb009dcSAndroid Build Coastguard Worker   // Send the server Certificate message, if necessary.
902*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->s3->session_reused) {
903*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_add_certificate(hs)) {
904*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
905*8fb009dcSAndroid Build Coastguard Worker     }
906*8fb009dcSAndroid Build Coastguard Worker 
907*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_send_server_certificate_verify;
908*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_ok;
909*8fb009dcSAndroid Build Coastguard Worker   }
910*8fb009dcSAndroid Build Coastguard Worker 
911*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_send_server_finished;
912*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
913*8fb009dcSAndroid Build Coastguard Worker }
914*8fb009dcSAndroid Build Coastguard Worker 
do_send_server_certificate_verify(SSL_HANDSHAKE * hs)915*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
916*8fb009dcSAndroid Build Coastguard Worker   switch (tls13_add_certificate_verify(hs)) {
917*8fb009dcSAndroid Build Coastguard Worker     case ssl_private_key_success:
918*8fb009dcSAndroid Build Coastguard Worker       hs->tls13_state = state13_send_server_finished;
919*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_ok;
920*8fb009dcSAndroid Build Coastguard Worker 
921*8fb009dcSAndroid Build Coastguard Worker     case ssl_private_key_retry:
922*8fb009dcSAndroid Build Coastguard Worker       hs->tls13_state = state13_send_server_certificate_verify;
923*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_private_key_operation;
924*8fb009dcSAndroid Build Coastguard Worker 
925*8fb009dcSAndroid Build Coastguard Worker     case ssl_private_key_failure:
926*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
927*8fb009dcSAndroid Build Coastguard Worker   }
928*8fb009dcSAndroid Build Coastguard Worker 
929*8fb009dcSAndroid Build Coastguard Worker   assert(0);
930*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_error;
931*8fb009dcSAndroid Build Coastguard Worker }
932*8fb009dcSAndroid Build Coastguard Worker 
do_send_server_finished(SSL_HANDSHAKE * hs)933*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
934*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
935*8fb009dcSAndroid Build Coastguard Worker   if (hs->hints_requested) {
936*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_hints_ready;
937*8fb009dcSAndroid Build Coastguard Worker   }
938*8fb009dcSAndroid Build Coastguard Worker 
939*8fb009dcSAndroid Build Coastguard Worker   hs->can_release_private_key = true;
940*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_add_finished(hs) ||
941*8fb009dcSAndroid Build Coastguard Worker       // Update the secret to the master secret and derive traffic keys.
942*8fb009dcSAndroid Build Coastguard Worker       !tls13_advance_key_schedule(
943*8fb009dcSAndroid Build Coastguard Worker           hs, MakeConstSpan(kZeroes, hs->transcript.DigestLen())) ||
944*8fb009dcSAndroid Build Coastguard Worker       !tls13_derive_application_secrets(hs) ||
945*8fb009dcSAndroid Build Coastguard Worker       !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal,
946*8fb009dcSAndroid Build Coastguard Worker                              hs->new_session.get(),
947*8fb009dcSAndroid Build Coastguard Worker                              hs->server_traffic_secret_0())) {
948*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
949*8fb009dcSAndroid Build Coastguard Worker   }
950*8fb009dcSAndroid Build Coastguard Worker 
951*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_send_half_rtt_ticket;
952*8fb009dcSAndroid Build Coastguard Worker   return hs->handback ? ssl_hs_handback : ssl_hs_ok;
953*8fb009dcSAndroid Build Coastguard Worker }
954*8fb009dcSAndroid Build Coastguard Worker 
do_send_half_rtt_ticket(SSL_HANDSHAKE * hs)955*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_half_rtt_ticket(SSL_HANDSHAKE *hs) {
956*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
957*8fb009dcSAndroid Build Coastguard Worker 
958*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->early_data_accepted) {
959*8fb009dcSAndroid Build Coastguard Worker     // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
960*8fb009dcSAndroid Build Coastguard Worker     // the wire sooner and also avoids triggering a write on |SSL_read| when
961*8fb009dcSAndroid Build Coastguard Worker     // processing the client Finished. This requires computing the client
962*8fb009dcSAndroid Build Coastguard Worker     // Finished early. See RFC 8446, section 4.6.1.
963*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0,
964*8fb009dcSAndroid Build Coastguard Worker                                                0, 0};
965*8fb009dcSAndroid Build Coastguard Worker     if (ssl->quic_method == nullptr &&
966*8fb009dcSAndroid Build Coastguard Worker         !hs->transcript.Update(kEndOfEarlyData)) {
967*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
968*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
969*8fb009dcSAndroid Build Coastguard Worker     }
970*8fb009dcSAndroid Build Coastguard Worker 
971*8fb009dcSAndroid Build Coastguard Worker     size_t finished_len;
972*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_finished_mac(hs, hs->expected_client_finished().data(),
973*8fb009dcSAndroid Build Coastguard Worker                             &finished_len, false /* client */)) {
974*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
975*8fb009dcSAndroid Build Coastguard Worker     }
976*8fb009dcSAndroid Build Coastguard Worker 
977*8fb009dcSAndroid Build Coastguard Worker     if (finished_len != hs->expected_client_finished().size()) {
978*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
979*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
980*8fb009dcSAndroid Build Coastguard Worker     }
981*8fb009dcSAndroid Build Coastguard Worker 
982*8fb009dcSAndroid Build Coastguard Worker     // Feed the predicted Finished into the transcript. This allows us to derive
983*8fb009dcSAndroid Build Coastguard Worker     // the resumption secret early and send half-RTT tickets.
984*8fb009dcSAndroid Build Coastguard Worker     //
985*8fb009dcSAndroid Build Coastguard Worker     // TODO(davidben): This will need to be updated for DTLS 1.3.
986*8fb009dcSAndroid Build Coastguard Worker     assert(!SSL_is_dtls(hs->ssl));
987*8fb009dcSAndroid Build Coastguard Worker     assert(hs->expected_client_finished().size() <= 0xff);
988*8fb009dcSAndroid Build Coastguard Worker     uint8_t header[4] = {
989*8fb009dcSAndroid Build Coastguard Worker         SSL3_MT_FINISHED, 0, 0,
990*8fb009dcSAndroid Build Coastguard Worker         static_cast<uint8_t>(hs->expected_client_finished().size())};
991*8fb009dcSAndroid Build Coastguard Worker     bool unused_sent_tickets;
992*8fb009dcSAndroid Build Coastguard Worker     if (!hs->transcript.Update(header) ||
993*8fb009dcSAndroid Build Coastguard Worker         !hs->transcript.Update(hs->expected_client_finished()) ||
994*8fb009dcSAndroid Build Coastguard Worker         !tls13_derive_resumption_secret(hs) ||
995*8fb009dcSAndroid Build Coastguard Worker         !add_new_session_tickets(hs, &unused_sent_tickets)) {
996*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
997*8fb009dcSAndroid Build Coastguard Worker     }
998*8fb009dcSAndroid Build Coastguard Worker   }
999*8fb009dcSAndroid Build Coastguard Worker 
1000*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_second_client_flight;
1001*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_flush;
1002*8fb009dcSAndroid Build Coastguard Worker }
1003*8fb009dcSAndroid Build Coastguard Worker 
do_read_second_client_flight(SSL_HANDSHAKE * hs)1004*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
1005*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1006*8fb009dcSAndroid Build Coastguard Worker   if (ssl->s3->early_data_accepted) {
1007*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_set_traffic_key(ssl, ssl_encryption_early_data, evp_aead_open,
1008*8fb009dcSAndroid Build Coastguard Worker                                hs->new_session.get(),
1009*8fb009dcSAndroid Build Coastguard Worker                                hs->early_traffic_secret())) {
1010*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1011*8fb009dcSAndroid Build Coastguard Worker     }
1012*8fb009dcSAndroid Build Coastguard Worker     hs->can_early_write = true;
1013*8fb009dcSAndroid Build Coastguard Worker     hs->can_early_read = true;
1014*8fb009dcSAndroid Build Coastguard Worker     hs->in_early_data = true;
1015*8fb009dcSAndroid Build Coastguard Worker   }
1016*8fb009dcSAndroid Build Coastguard Worker 
1017*8fb009dcSAndroid Build Coastguard Worker   // QUIC doesn't use an EndOfEarlyData message (RFC 9001, section 8.3), so we
1018*8fb009dcSAndroid Build Coastguard Worker   // switch to client_handshake_secret before the early return.
1019*8fb009dcSAndroid Build Coastguard Worker   if (ssl->quic_method != nullptr) {
1020*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
1021*8fb009dcSAndroid Build Coastguard Worker                                hs->new_session.get(),
1022*8fb009dcSAndroid Build Coastguard Worker                                hs->client_handshake_secret())) {
1023*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1024*8fb009dcSAndroid Build Coastguard Worker     }
1025*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_process_end_of_early_data;
1026*8fb009dcSAndroid Build Coastguard Worker     return ssl->s3->early_data_accepted ? ssl_hs_early_return : ssl_hs_ok;
1027*8fb009dcSAndroid Build Coastguard Worker   }
1028*8fb009dcSAndroid Build Coastguard Worker 
1029*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_process_end_of_early_data;
1030*8fb009dcSAndroid Build Coastguard Worker   return ssl->s3->early_data_accepted ? ssl_hs_read_end_of_early_data
1031*8fb009dcSAndroid Build Coastguard Worker                                       : ssl_hs_ok;
1032*8fb009dcSAndroid Build Coastguard Worker }
1033*8fb009dcSAndroid Build Coastguard Worker 
do_process_end_of_early_data(SSL_HANDSHAKE * hs)1034*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
1035*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1036*8fb009dcSAndroid Build Coastguard Worker   // In protocols that use EndOfEarlyData, we must consume the extra message and
1037*8fb009dcSAndroid Build Coastguard Worker   // switch to client_handshake_secret after the early return.
1038*8fb009dcSAndroid Build Coastguard Worker   if (ssl->quic_method == nullptr) {
1039*8fb009dcSAndroid Build Coastguard Worker     // If early data was not accepted, the EndOfEarlyData will be in the
1040*8fb009dcSAndroid Build Coastguard Worker     // discarded early data.
1041*8fb009dcSAndroid Build Coastguard Worker     if (hs->ssl->s3->early_data_accepted) {
1042*8fb009dcSAndroid Build Coastguard Worker       SSLMessage msg;
1043*8fb009dcSAndroid Build Coastguard Worker       if (!ssl->method->get_message(ssl, &msg)) {
1044*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_read_message;
1045*8fb009dcSAndroid Build Coastguard Worker       }
1046*8fb009dcSAndroid Build Coastguard Worker       if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
1047*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_error;
1048*8fb009dcSAndroid Build Coastguard Worker       }
1049*8fb009dcSAndroid Build Coastguard Worker       if (CBS_len(&msg.body) != 0) {
1050*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1051*8fb009dcSAndroid Build Coastguard Worker         OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1052*8fb009dcSAndroid Build Coastguard Worker         return ssl_hs_error;
1053*8fb009dcSAndroid Build Coastguard Worker       }
1054*8fb009dcSAndroid Build Coastguard Worker       ssl->method->next_message(ssl);
1055*8fb009dcSAndroid Build Coastguard Worker     }
1056*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
1057*8fb009dcSAndroid Build Coastguard Worker                                hs->new_session.get(),
1058*8fb009dcSAndroid Build Coastguard Worker                                hs->client_handshake_secret())) {
1059*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1060*8fb009dcSAndroid Build Coastguard Worker     }
1061*8fb009dcSAndroid Build Coastguard Worker   }
1062*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_client_encrypted_extensions;
1063*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1064*8fb009dcSAndroid Build Coastguard Worker }
1065*8fb009dcSAndroid Build Coastguard Worker 
do_read_client_encrypted_extensions(SSL_HANDSHAKE * hs)1066*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_client_encrypted_extensions(
1067*8fb009dcSAndroid Build Coastguard Worker     SSL_HANDSHAKE *hs) {
1068*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1069*8fb009dcSAndroid Build Coastguard Worker   // For now, only one extension uses client EncryptedExtensions. This function
1070*8fb009dcSAndroid Build Coastguard Worker   // may be generalized if others use it in the future.
1071*8fb009dcSAndroid Build Coastguard Worker   if (hs->new_session->has_application_settings &&
1072*8fb009dcSAndroid Build Coastguard Worker       !ssl->s3->early_data_accepted) {
1073*8fb009dcSAndroid Build Coastguard Worker     SSLMessage msg;
1074*8fb009dcSAndroid Build Coastguard Worker     if (!ssl->method->get_message(ssl, &msg)) {
1075*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_read_message;
1076*8fb009dcSAndroid Build Coastguard Worker     }
1077*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) {
1078*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1079*8fb009dcSAndroid Build Coastguard Worker     }
1080*8fb009dcSAndroid Build Coastguard Worker 
1081*8fb009dcSAndroid Build Coastguard Worker     CBS body = msg.body, extensions;
1082*8fb009dcSAndroid Build Coastguard Worker     if (!CBS_get_u16_length_prefixed(&body, &extensions) ||
1083*8fb009dcSAndroid Build Coastguard Worker         CBS_len(&body) != 0) {
1084*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
1085*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
1086*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1087*8fb009dcSAndroid Build Coastguard Worker     }
1088*8fb009dcSAndroid Build Coastguard Worker 
1089*8fb009dcSAndroid Build Coastguard Worker     uint16_t extension_type = TLSEXT_TYPE_application_settings_old;
1090*8fb009dcSAndroid Build Coastguard Worker     if (hs->config->alps_use_new_codepoint) {
1091*8fb009dcSAndroid Build Coastguard Worker       extension_type = TLSEXT_TYPE_application_settings;
1092*8fb009dcSAndroid Build Coastguard Worker     }
1093*8fb009dcSAndroid Build Coastguard Worker     SSLExtension application_settings(extension_type);
1094*8fb009dcSAndroid Build Coastguard Worker     uint8_t alert = SSL_AD_DECODE_ERROR;
1095*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_parse_extensions(&extensions, &alert, {&application_settings},
1096*8fb009dcSAndroid Build Coastguard Worker                               /*ignore_unknown=*/false)) {
1097*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
1098*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1099*8fb009dcSAndroid Build Coastguard Worker     }
1100*8fb009dcSAndroid Build Coastguard Worker 
1101*8fb009dcSAndroid Build Coastguard Worker     if (!application_settings.present) {
1102*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
1103*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
1104*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1105*8fb009dcSAndroid Build Coastguard Worker     }
1106*8fb009dcSAndroid Build Coastguard Worker 
1107*8fb009dcSAndroid Build Coastguard Worker     // Note that, if 0-RTT was accepted, these values will already have been
1108*8fb009dcSAndroid Build Coastguard Worker     // initialized earlier.
1109*8fb009dcSAndroid Build Coastguard Worker     if (!hs->new_session->peer_application_settings.CopyFrom(
1110*8fb009dcSAndroid Build Coastguard Worker             application_settings.data) ||
1111*8fb009dcSAndroid Build Coastguard Worker         !ssl_hash_message(hs, msg)) {
1112*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
1113*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1114*8fb009dcSAndroid Build Coastguard Worker     }
1115*8fb009dcSAndroid Build Coastguard Worker 
1116*8fb009dcSAndroid Build Coastguard Worker     ssl->method->next_message(ssl);
1117*8fb009dcSAndroid Build Coastguard Worker   }
1118*8fb009dcSAndroid Build Coastguard Worker 
1119*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_client_certificate;
1120*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1121*8fb009dcSAndroid Build Coastguard Worker }
1122*8fb009dcSAndroid Build Coastguard Worker 
do_read_client_certificate(SSL_HANDSHAKE * hs)1123*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
1124*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1125*8fb009dcSAndroid Build Coastguard Worker   if (!hs->cert_request) {
1126*8fb009dcSAndroid Build Coastguard Worker     if (!ssl->s3->session_reused) {
1127*8fb009dcSAndroid Build Coastguard Worker       // OpenSSL returns X509_V_OK when no certificates are requested. This is
1128*8fb009dcSAndroid Build Coastguard Worker       // classed by them as a bug, but it's assumed by at least NGINX. (Only do
1129*8fb009dcSAndroid Build Coastguard Worker       // this in full handshakes as resumptions should carry over the previous
1130*8fb009dcSAndroid Build Coastguard Worker       // |verify_result|, though this is a no-op because servers do not
1131*8fb009dcSAndroid Build Coastguard Worker       // implement the client's odd soft-fail mode.)
1132*8fb009dcSAndroid Build Coastguard Worker       hs->new_session->verify_result = X509_V_OK;
1133*8fb009dcSAndroid Build Coastguard Worker     }
1134*8fb009dcSAndroid Build Coastguard Worker 
1135*8fb009dcSAndroid Build Coastguard Worker     // Skip this state.
1136*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_read_channel_id;
1137*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_ok;
1138*8fb009dcSAndroid Build Coastguard Worker   }
1139*8fb009dcSAndroid Build Coastguard Worker 
1140*8fb009dcSAndroid Build Coastguard Worker   const bool allow_anonymous =
1141*8fb009dcSAndroid Build Coastguard Worker       (hs->config->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
1142*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
1143*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->get_message(ssl, &msg)) {
1144*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_read_message;
1145*8fb009dcSAndroid Build Coastguard Worker   }
1146*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) ||
1147*8fb009dcSAndroid Build Coastguard Worker       !tls13_process_certificate(hs, msg, allow_anonymous) ||
1148*8fb009dcSAndroid Build Coastguard Worker       !ssl_hash_message(hs, msg)) {
1149*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
1150*8fb009dcSAndroid Build Coastguard Worker   }
1151*8fb009dcSAndroid Build Coastguard Worker 
1152*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
1153*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_client_certificate_verify;
1154*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1155*8fb009dcSAndroid Build Coastguard Worker }
1156*8fb009dcSAndroid Build Coastguard Worker 
do_read_client_certificate_verify(SSL_HANDSHAKE * hs)1157*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) {
1158*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1159*8fb009dcSAndroid Build Coastguard Worker   if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
1160*8fb009dcSAndroid Build Coastguard Worker     // Skip this state.
1161*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_read_channel_id;
1162*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_ok;
1163*8fb009dcSAndroid Build Coastguard Worker   }
1164*8fb009dcSAndroid Build Coastguard Worker 
1165*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
1166*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->get_message(ssl, &msg)) {
1167*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_read_message;
1168*8fb009dcSAndroid Build Coastguard Worker   }
1169*8fb009dcSAndroid Build Coastguard Worker 
1170*8fb009dcSAndroid Build Coastguard Worker   switch (ssl_verify_peer_cert(hs)) {
1171*8fb009dcSAndroid Build Coastguard Worker     case ssl_verify_ok:
1172*8fb009dcSAndroid Build Coastguard Worker       break;
1173*8fb009dcSAndroid Build Coastguard Worker     case ssl_verify_invalid:
1174*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1175*8fb009dcSAndroid Build Coastguard Worker     case ssl_verify_retry:
1176*8fb009dcSAndroid Build Coastguard Worker       hs->tls13_state = state13_read_client_certificate_verify;
1177*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_certificate_verify;
1178*8fb009dcSAndroid Build Coastguard Worker   }
1179*8fb009dcSAndroid Build Coastguard Worker 
1180*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
1181*8fb009dcSAndroid Build Coastguard Worker       !tls13_process_certificate_verify(hs, msg) ||
1182*8fb009dcSAndroid Build Coastguard Worker       !ssl_hash_message(hs, msg)) {
1183*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
1184*8fb009dcSAndroid Build Coastguard Worker   }
1185*8fb009dcSAndroid Build Coastguard Worker 
1186*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
1187*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_channel_id;
1188*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1189*8fb009dcSAndroid Build Coastguard Worker }
1190*8fb009dcSAndroid Build Coastguard Worker 
do_read_channel_id(SSL_HANDSHAKE * hs)1191*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
1192*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1193*8fb009dcSAndroid Build Coastguard Worker   if (!hs->channel_id_negotiated) {
1194*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_read_client_finished;
1195*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_ok;
1196*8fb009dcSAndroid Build Coastguard Worker   }
1197*8fb009dcSAndroid Build Coastguard Worker 
1198*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
1199*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->get_message(ssl, &msg)) {
1200*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_read_message;
1201*8fb009dcSAndroid Build Coastguard Worker   }
1202*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) ||
1203*8fb009dcSAndroid Build Coastguard Worker       !tls1_verify_channel_id(hs, msg) ||
1204*8fb009dcSAndroid Build Coastguard Worker       !ssl_hash_message(hs, msg)) {
1205*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
1206*8fb009dcSAndroid Build Coastguard Worker   }
1207*8fb009dcSAndroid Build Coastguard Worker 
1208*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
1209*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_read_client_finished;
1210*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1211*8fb009dcSAndroid Build Coastguard Worker }
1212*8fb009dcSAndroid Build Coastguard Worker 
do_read_client_finished(SSL_HANDSHAKE * hs)1213*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
1214*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
1215*8fb009dcSAndroid Build Coastguard Worker   SSLMessage msg;
1216*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->get_message(ssl, &msg)) {
1217*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_read_message;
1218*8fb009dcSAndroid Build Coastguard Worker   }
1219*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
1220*8fb009dcSAndroid Build Coastguard Worker       // If early data was accepted, we've already computed the client Finished
1221*8fb009dcSAndroid Build Coastguard Worker       // and derived the resumption secret.
1222*8fb009dcSAndroid Build Coastguard Worker       !tls13_process_finished(hs, msg, ssl->s3->early_data_accepted) ||
1223*8fb009dcSAndroid Build Coastguard Worker       // evp_aead_seal keys have already been switched.
1224*8fb009dcSAndroid Build Coastguard Worker       !tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_open,
1225*8fb009dcSAndroid Build Coastguard Worker                              hs->new_session.get(),
1226*8fb009dcSAndroid Build Coastguard Worker                              hs->client_traffic_secret_0())) {
1227*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
1228*8fb009dcSAndroid Build Coastguard Worker   }
1229*8fb009dcSAndroid Build Coastguard Worker 
1230*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->s3->early_data_accepted) {
1231*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_hash_message(hs, msg) ||
1232*8fb009dcSAndroid Build Coastguard Worker         !tls13_derive_resumption_secret(hs)) {
1233*8fb009dcSAndroid Build Coastguard Worker       return ssl_hs_error;
1234*8fb009dcSAndroid Build Coastguard Worker     }
1235*8fb009dcSAndroid Build Coastguard Worker 
1236*8fb009dcSAndroid Build Coastguard Worker     // We send post-handshake tickets as part of the handshake in 1-RTT.
1237*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_send_new_session_ticket;
1238*8fb009dcSAndroid Build Coastguard Worker   } else {
1239*8fb009dcSAndroid Build Coastguard Worker     // We already sent half-RTT tickets.
1240*8fb009dcSAndroid Build Coastguard Worker     hs->tls13_state = state13_done;
1241*8fb009dcSAndroid Build Coastguard Worker   }
1242*8fb009dcSAndroid Build Coastguard Worker 
1243*8fb009dcSAndroid Build Coastguard Worker   ssl->method->next_message(ssl);
1244*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1245*8fb009dcSAndroid Build Coastguard Worker }
1246*8fb009dcSAndroid Build Coastguard Worker 
do_send_new_session_ticket(SSL_HANDSHAKE * hs)1247*8fb009dcSAndroid Build Coastguard Worker static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
1248*8fb009dcSAndroid Build Coastguard Worker   bool sent_tickets;
1249*8fb009dcSAndroid Build Coastguard Worker   if (!add_new_session_tickets(hs, &sent_tickets)) {
1250*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_error;
1251*8fb009dcSAndroid Build Coastguard Worker   }
1252*8fb009dcSAndroid Build Coastguard Worker 
1253*8fb009dcSAndroid Build Coastguard Worker   hs->tls13_state = state13_done;
1254*8fb009dcSAndroid Build Coastguard Worker   // In TLS 1.3, the NewSessionTicket isn't flushed until the server performs a
1255*8fb009dcSAndroid Build Coastguard Worker   // write, to prevent a non-reading client from causing the server to hang in
1256*8fb009dcSAndroid Build Coastguard Worker   // the case of a small server write buffer. Consumers which don't write data
1257*8fb009dcSAndroid Build Coastguard Worker   // to the client will need to do a zero-byte write if they wish to flush the
1258*8fb009dcSAndroid Build Coastguard Worker   // tickets.
1259*8fb009dcSAndroid Build Coastguard Worker   if (hs->ssl->quic_method != nullptr && sent_tickets) {
1260*8fb009dcSAndroid Build Coastguard Worker     return ssl_hs_flush;
1261*8fb009dcSAndroid Build Coastguard Worker   }
1262*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1263*8fb009dcSAndroid Build Coastguard Worker }
1264*8fb009dcSAndroid Build Coastguard Worker 
tls13_server_handshake(SSL_HANDSHAKE * hs)1265*8fb009dcSAndroid Build Coastguard Worker enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
1266*8fb009dcSAndroid Build Coastguard Worker   while (hs->tls13_state != state13_done) {
1267*8fb009dcSAndroid Build Coastguard Worker     enum ssl_hs_wait_t ret = ssl_hs_error;
1268*8fb009dcSAndroid Build Coastguard Worker     enum tls13_server_hs_state_t state =
1269*8fb009dcSAndroid Build Coastguard Worker         static_cast<enum tls13_server_hs_state_t>(hs->tls13_state);
1270*8fb009dcSAndroid Build Coastguard Worker     switch (state) {
1271*8fb009dcSAndroid Build Coastguard Worker       case state13_select_parameters:
1272*8fb009dcSAndroid Build Coastguard Worker         ret = do_select_parameters(hs);
1273*8fb009dcSAndroid Build Coastguard Worker         break;
1274*8fb009dcSAndroid Build Coastguard Worker       case state13_select_session:
1275*8fb009dcSAndroid Build Coastguard Worker         ret = do_select_session(hs);
1276*8fb009dcSAndroid Build Coastguard Worker         break;
1277*8fb009dcSAndroid Build Coastguard Worker       case state13_send_hello_retry_request:
1278*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_hello_retry_request(hs);
1279*8fb009dcSAndroid Build Coastguard Worker         break;
1280*8fb009dcSAndroid Build Coastguard Worker       case state13_read_second_client_hello:
1281*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_second_client_hello(hs);
1282*8fb009dcSAndroid Build Coastguard Worker         break;
1283*8fb009dcSAndroid Build Coastguard Worker       case state13_send_server_hello:
1284*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_server_hello(hs);
1285*8fb009dcSAndroid Build Coastguard Worker         break;
1286*8fb009dcSAndroid Build Coastguard Worker       case state13_send_server_certificate_verify:
1287*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_server_certificate_verify(hs);
1288*8fb009dcSAndroid Build Coastguard Worker         break;
1289*8fb009dcSAndroid Build Coastguard Worker       case state13_send_server_finished:
1290*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_server_finished(hs);
1291*8fb009dcSAndroid Build Coastguard Worker         break;
1292*8fb009dcSAndroid Build Coastguard Worker       case state13_send_half_rtt_ticket:
1293*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_half_rtt_ticket(hs);
1294*8fb009dcSAndroid Build Coastguard Worker         break;
1295*8fb009dcSAndroid Build Coastguard Worker       case state13_read_second_client_flight:
1296*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_second_client_flight(hs);
1297*8fb009dcSAndroid Build Coastguard Worker         break;
1298*8fb009dcSAndroid Build Coastguard Worker       case state13_process_end_of_early_data:
1299*8fb009dcSAndroid Build Coastguard Worker         ret = do_process_end_of_early_data(hs);
1300*8fb009dcSAndroid Build Coastguard Worker         break;
1301*8fb009dcSAndroid Build Coastguard Worker       case state13_read_client_encrypted_extensions:
1302*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_client_encrypted_extensions(hs);
1303*8fb009dcSAndroid Build Coastguard Worker         break;
1304*8fb009dcSAndroid Build Coastguard Worker       case state13_read_client_certificate:
1305*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_client_certificate(hs);
1306*8fb009dcSAndroid Build Coastguard Worker         break;
1307*8fb009dcSAndroid Build Coastguard Worker       case state13_read_client_certificate_verify:
1308*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_client_certificate_verify(hs);
1309*8fb009dcSAndroid Build Coastguard Worker         break;
1310*8fb009dcSAndroid Build Coastguard Worker       case state13_read_channel_id:
1311*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_channel_id(hs);
1312*8fb009dcSAndroid Build Coastguard Worker         break;
1313*8fb009dcSAndroid Build Coastguard Worker       case state13_read_client_finished:
1314*8fb009dcSAndroid Build Coastguard Worker         ret = do_read_client_finished(hs);
1315*8fb009dcSAndroid Build Coastguard Worker         break;
1316*8fb009dcSAndroid Build Coastguard Worker       case state13_send_new_session_ticket:
1317*8fb009dcSAndroid Build Coastguard Worker         ret = do_send_new_session_ticket(hs);
1318*8fb009dcSAndroid Build Coastguard Worker         break;
1319*8fb009dcSAndroid Build Coastguard Worker       case state13_done:
1320*8fb009dcSAndroid Build Coastguard Worker         ret = ssl_hs_ok;
1321*8fb009dcSAndroid Build Coastguard Worker         break;
1322*8fb009dcSAndroid Build Coastguard Worker     }
1323*8fb009dcSAndroid Build Coastguard Worker 
1324*8fb009dcSAndroid Build Coastguard Worker     if (hs->tls13_state != state) {
1325*8fb009dcSAndroid Build Coastguard Worker       ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1);
1326*8fb009dcSAndroid Build Coastguard Worker     }
1327*8fb009dcSAndroid Build Coastguard Worker 
1328*8fb009dcSAndroid Build Coastguard Worker     if (ret != ssl_hs_ok) {
1329*8fb009dcSAndroid Build Coastguard Worker       return ret;
1330*8fb009dcSAndroid Build Coastguard Worker     }
1331*8fb009dcSAndroid Build Coastguard Worker   }
1332*8fb009dcSAndroid Build Coastguard Worker 
1333*8fb009dcSAndroid Build Coastguard Worker   return ssl_hs_ok;
1334*8fb009dcSAndroid Build Coastguard Worker }
1335*8fb009dcSAndroid Build Coastguard Worker 
tls13_server_handshake_state(SSL_HANDSHAKE * hs)1336*8fb009dcSAndroid Build Coastguard Worker const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) {
1337*8fb009dcSAndroid Build Coastguard Worker   enum tls13_server_hs_state_t state =
1338*8fb009dcSAndroid Build Coastguard Worker       static_cast<enum tls13_server_hs_state_t>(hs->tls13_state);
1339*8fb009dcSAndroid Build Coastguard Worker   switch (state) {
1340*8fb009dcSAndroid Build Coastguard Worker     case state13_select_parameters:
1341*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server select_parameters";
1342*8fb009dcSAndroid Build Coastguard Worker     case state13_select_session:
1343*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server select_session";
1344*8fb009dcSAndroid Build Coastguard Worker     case state13_send_hello_retry_request:
1345*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_hello_retry_request";
1346*8fb009dcSAndroid Build Coastguard Worker     case state13_read_second_client_hello:
1347*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_second_client_hello";
1348*8fb009dcSAndroid Build Coastguard Worker     case state13_send_server_hello:
1349*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_server_hello";
1350*8fb009dcSAndroid Build Coastguard Worker     case state13_send_server_certificate_verify:
1351*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_server_certificate_verify";
1352*8fb009dcSAndroid Build Coastguard Worker     case state13_send_half_rtt_ticket:
1353*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_half_rtt_ticket";
1354*8fb009dcSAndroid Build Coastguard Worker     case state13_send_server_finished:
1355*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_server_finished";
1356*8fb009dcSAndroid Build Coastguard Worker     case state13_read_second_client_flight:
1357*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_second_client_flight";
1358*8fb009dcSAndroid Build Coastguard Worker     case state13_process_end_of_early_data:
1359*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server process_end_of_early_data";
1360*8fb009dcSAndroid Build Coastguard Worker     case state13_read_client_encrypted_extensions:
1361*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_client_encrypted_extensions";
1362*8fb009dcSAndroid Build Coastguard Worker     case state13_read_client_certificate:
1363*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_client_certificate";
1364*8fb009dcSAndroid Build Coastguard Worker     case state13_read_client_certificate_verify:
1365*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_client_certificate_verify";
1366*8fb009dcSAndroid Build Coastguard Worker     case state13_read_channel_id:
1367*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_channel_id";
1368*8fb009dcSAndroid Build Coastguard Worker     case state13_read_client_finished:
1369*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server read_client_finished";
1370*8fb009dcSAndroid Build Coastguard Worker     case state13_send_new_session_ticket:
1371*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server send_new_session_ticket";
1372*8fb009dcSAndroid Build Coastguard Worker     case state13_done:
1373*8fb009dcSAndroid Build Coastguard Worker       return "TLS 1.3 server done";
1374*8fb009dcSAndroid Build Coastguard Worker   }
1375*8fb009dcSAndroid Build Coastguard Worker 
1376*8fb009dcSAndroid Build Coastguard Worker   return "TLS 1.3 server unknown";
1377*8fb009dcSAndroid Build Coastguard Worker }
1378*8fb009dcSAndroid Build Coastguard Worker 
1379*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
1380