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