blob: c48c5b44ecf0099d12fd76368fd70f1d122e427c [file] [log] [blame]
Steven Valdez143e8b32016-07-11 13:19:03 -04001/* Copyright (c) 2016, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
David Benjaminc11ea9422017-08-29 16:33:21 -040015// Per C99, various stdint.h macros are unavailable in C++ unless some macros
16// are defined. C++11 overruled this decision, but older Android NDKs still
17// require it.
David Benjamind304a2f2017-07-12 23:00:28 -040018#if !defined(__STDC_LIMIT_MACROS)
19#define __STDC_LIMIT_MACROS
20#endif
21
Steven Valdez143e8b32016-07-11 13:19:03 -040022#include <openssl/ssl.h>
23
24#include <assert.h>
25#include <string.h>
26
David Benjaminabbbee12016-10-31 19:20:42 -040027#include <openssl/aead.h>
Steven Valdez143e8b32016-07-11 13:19:03 -040028#include <openssl/bytestring.h>
29#include <openssl/digest.h>
30#include <openssl/err.h>
31#include <openssl/mem.h>
32#include <openssl/rand.h>
33#include <openssl/stack.h>
34
David Benjamin17cf2cb2016-12-13 01:07:13 -050035#include "../crypto/internal.h"
Steven Valdez143e8b32016-07-11 13:19:03 -040036#include "internal.h"
37
38
David Benjamin86e95b82017-07-18 16:34:25 -040039namespace bssl {
40
Steven Valdez143e8b32016-07-11 13:19:03 -040041enum server_hs_state_t {
David Benjamindaa05392017-02-02 23:33:21 -050042 state_select_parameters = 0,
David Benjamin707af292017-03-10 17:47:18 -050043 state_select_session,
Steven Valdez5440fe02016-07-18 12:40:30 -040044 state_send_hello_retry_request,
David Benjamin7934f082017-08-01 16:32:25 -040045 state_read_second_client_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040046 state_send_server_hello,
Steven Valdez143e8b32016-07-11 13:19:03 -040047 state_send_server_certificate_verify,
Steven Valdez143e8b32016-07-11 13:19:03 -040048 state_send_server_finished,
Steven Valdez2d850622017-01-11 11:34:52 -050049 state_read_second_client_flight,
Steven Valdez520e1222017-06-13 12:45:25 -040050 state_process_change_cipher_spec,
Steven Valdez2d850622017-01-11 11:34:52 -050051 state_process_end_of_early_data,
David Benjamin7934f082017-08-01 16:32:25 -040052 state_read_client_certificate,
53 state_read_client_certificate_verify,
54 state_read_channel_id,
55 state_read_client_finished,
Steven Valdez1e6f11a2016-07-27 11:10:52 -040056 state_send_new_session_ticket,
Steven Valdez143e8b32016-07-11 13:19:03 -040057 state_done,
58};
59
Steven Valdez5440fe02016-07-18 12:40:30 -040060static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
61
David Benjamin046bc1f2017-08-31 15:06:42 -040062static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, bool *out_need_retry,
David Benjamin731058e2016-12-03 23:15:13 -050063 SSL_CLIENT_HELLO *client_hello) {
David Benjamin6e4fc332016-11-17 16:43:08 +090064 SSL *const ssl = hs->ssl;
David Benjamin046bc1f2017-08-31 15:06:42 -040065 *out_need_retry = false;
Steven Valdez5440fe02016-07-18 12:40:30 -040066
David Benjaminc11ea9422017-08-29 16:33:21 -040067 // We only support connections that include an ECDHE key exchange.
Steven Valdez5440fe02016-07-18 12:40:30 -040068 CBS key_share;
David Benjamin731058e2016-12-03 23:15:13 -050069 if (!ssl_client_hello_get_extension(client_hello, &key_share,
70 TLSEXT_TYPE_key_share)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040071 OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
David Benjamind1e3ce12017-10-06 18:31:15 -040072 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
David Benjamin6929f272016-11-16 19:10:08 +090073 return 0;
Steven Valdez5440fe02016-07-18 12:40:30 -040074 }
75
David Benjamin74795b32017-08-31 15:13:12 -040076 bool found_key_share;
David Benjamin499742c2017-07-22 12:45:38 -040077 Array<uint8_t> dhe_secret;
David Benjamin7e1f9842016-09-20 19:24:40 -040078 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin8baf9632016-11-17 17:11:16 +090079 if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
David Benjamin499742c2017-07-22 12:45:38 -040080 &alert, &key_share)) {
David Benjamind1e3ce12017-10-06 18:31:15 -040081 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
Steven Valdez5440fe02016-07-18 12:40:30 -040082 return 0;
83 }
84
85 if (!found_key_share) {
David Benjamin046bc1f2017-08-31 15:06:42 -040086 *out_need_retry = true;
Steven Valdez5440fe02016-07-18 12:40:30 -040087 return 0;
88 }
89
David Benjamin499742c2017-07-22 12:45:38 -040090 return tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size());
Steven Valdez5440fe02016-07-18 12:40:30 -040091}
92
Steven Valdez038da9b2017-07-10 12:57:25 -040093static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs,
94 CBB *out) {
95 CBB contents;
96 if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
97 !CBB_add_u16_length_prefixed(out, &contents) ||
98 !CBB_add_u16(&contents, hs->ssl->version) ||
99 !CBB_flush(out)) {
100 return 0;
101 }
102
103 return 1;
104}
105
David Benjamin34202b92016-11-16 19:07:53 +0900106static const SSL_CIPHER *choose_tls13_cipher(
David Benjamin731058e2016-12-03 23:15:13 -0500107 const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
David Benjamin34202b92016-11-16 19:07:53 +0900108 if (client_hello->cipher_suites_len % 2 != 0) {
109 return NULL;
110 }
111
112 CBS cipher_suites;
113 CBS_init(&cipher_suites, client_hello->cipher_suites,
114 client_hello->cipher_suites_len);
115
116 const int aes_is_fine = EVP_has_aes_hardware();
David Benjamind1e3ce12017-10-06 18:31:15 -0400117 const uint16_t version = ssl_protocol_version(ssl);
David Benjamin34202b92016-11-16 19:07:53 +0900118
119 const SSL_CIPHER *best = NULL;
120 while (CBS_len(&cipher_suites) > 0) {
121 uint16_t cipher_suite;
122 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
123 return NULL;
124 }
125
David Benjaminc11ea9422017-08-29 16:33:21 -0400126 // Limit to TLS 1.3 ciphers we know about.
David Benjamin34202b92016-11-16 19:07:53 +0900127 const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite);
David Benjaminf01f42a2016-11-16 19:05:33 +0900128 if (candidate == NULL ||
129 SSL_CIPHER_get_min_version(candidate) > version ||
130 SSL_CIPHER_get_max_version(candidate) < version) {
David Benjamin34202b92016-11-16 19:07:53 +0900131 continue;
132 }
133
David Benjaminc11ea9422017-08-29 16:33:21 -0400134 // TLS 1.3 removes legacy ciphers, so honor the client order, but prefer
135 // ChaCha20 if we do not have AES hardware.
David Benjamin34202b92016-11-16 19:07:53 +0900136 if (aes_is_fine) {
137 return candidate;
138 }
139
140 if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) {
141 return candidate;
142 }
143
144 if (best == NULL) {
145 best = candidate;
146 }
147 }
148
149 return best;
150}
151
David Benjamin794cc592017-03-25 22:24:23 -0500152static int add_new_session_tickets(SSL_HANDSHAKE *hs) {
153 SSL *const ssl = hs->ssl;
David Benjaminc11ea9422017-08-29 16:33:21 -0400154 // TLS 1.3 recommends single-use tickets, so issue multiple tickets in case
155 // the client makes several connections before getting a renewal.
David Benjamin794cc592017-03-25 22:24:23 -0500156 static const int kNumTickets = 2;
157
David Benjaminc11ea9422017-08-29 16:33:21 -0400158 // Rebase the session timestamp so that it is measured from ticket
159 // issuance.
David Benjamin31b0c9b2017-07-20 14:49:15 -0400160 ssl_session_rebase_time(ssl, hs->new_session.get());
David Benjamin794cc592017-03-25 22:24:23 -0500161
162 for (int i = 0; i < kNumTickets; i++) {
David Benjamin31b0c9b2017-07-20 14:49:15 -0400163 if (!RAND_bytes((uint8_t *)&hs->new_session->ticket_age_add, 4)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400164 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500165 }
David Benjamin31b0c9b2017-07-20 14:49:15 -0400166 hs->new_session->ticket_age_add_valid = 1;
David Benjamin794cc592017-03-25 22:24:23 -0500167
Steven Valdezbe165a22017-10-10 11:45:01 -0400168 if (ssl->cert->enable_early_data) {
169 hs->new_session->ticket_max_early_data = kMaxEarlyDataAccepted;
170 }
171
David Benjamin1386aad2017-07-19 23:57:40 -0400172 ScopedCBB cbb;
David Benjamin794cc592017-03-25 22:24:23 -0500173 CBB body, ticket, extensions;
David Benjamin1386aad2017-07-19 23:57:40 -0400174 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin794cc592017-03-25 22:24:23 -0500175 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400176 !CBB_add_u32(&body, hs->new_session->timeout) ||
177 !CBB_add_u32(&body, hs->new_session->ticket_age_add) ||
David Benjamin794cc592017-03-25 22:24:23 -0500178 !CBB_add_u16_length_prefixed(&body, &ticket) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400179 !ssl_encrypt_ticket(ssl, &ticket, hs->new_session.get()) ||
David Benjamin794cc592017-03-25 22:24:23 -0500180 !CBB_add_u16_length_prefixed(&body, &extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400181 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500182 }
183
Alessandro Ghedini67bb45f2017-03-30 16:33:24 -0500184 if (ssl->cert->enable_early_data) {
David Benjamin794cc592017-03-25 22:24:23 -0500185 CBB early_data_info;
186 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
187 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400188 !CBB_add_u32(&early_data_info,
189 hs->new_session->ticket_max_early_data) ||
David Benjamin794cc592017-03-25 22:24:23 -0500190 !CBB_flush(&extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400191 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500192 }
193 }
194
David Benjaminc11ea9422017-08-29 16:33:21 -0400195 // Add a fake extension. See draft-davidben-tls-grease-01.
David Benjamin794cc592017-03-25 22:24:23 -0500196 if (!CBB_add_u16(&extensions,
197 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
198 !CBB_add_u16(&extensions, 0 /* empty */)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400199 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500200 }
201
David Benjamin1386aad2017-07-19 23:57:40 -0400202 if (!ssl_add_message_cbb(ssl, cbb.get())) {
203 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500204 }
205 }
206
207 return 1;
David Benjamin794cc592017-03-25 22:24:23 -0500208}
209
David Benjaminc3c88822016-11-14 10:32:04 +0900210static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400211 // At this point, most ClientHello extensions have already been processed by
212 // the common handshake logic. Resolve the remaining non-PSK parameters.
David Benjaminc3c88822016-11-14 10:32:04 +0900213 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400214 SSLMessage msg;
215 if (!ssl->method->get_message(ssl, &msg)) {
216 return ssl_hs_read_message;
217 }
David Benjamin731058e2016-12-03 23:15:13 -0500218 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400219 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin34202b92016-11-16 19:07:53 +0900220 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400221 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin34202b92016-11-16 19:07:53 +0900222 return ssl_hs_error;
223 }
224
Steven Valdez520e1222017-06-13 12:45:25 -0400225 OPENSSL_memcpy(hs->session_id, client_hello.session_id,
226 client_hello.session_id_len);
227 hs->session_id_len = client_hello.session_id_len;
228
David Benjaminc11ea9422017-08-29 16:33:21 -0400229 // Negotiate the cipher suite.
David Benjamin45738dd2017-02-09 20:01:26 -0500230 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
231 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900232 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
David Benjamind1e3ce12017-10-06 18:31:15 -0400233 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
David Benjaminf01f42a2016-11-16 19:05:33 +0900234 return ssl_hs_error;
235 }
236
David Benjaminc11ea9422017-08-29 16:33:21 -0400237 // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
238 // deferred. Complete it now.
David Benjamin707af292017-03-10 17:47:18 -0500239 uint8_t alert = SSL_AD_DECODE_ERROR;
240 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400241 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500242 return ssl_hs_error;
243 }
244
David Benjaminc11ea9422017-08-29 16:33:21 -0400245 // The PRF hash is now known. Set up the key schedule and hash the
246 // ClientHello.
Steven Valdez908ac192017-01-12 13:17:07 -0500247 if (!tls13_init_key_schedule(hs) ||
David Benjamin7934f082017-08-01 16:32:25 -0400248 !ssl_hash_message(hs, msg)) {
Steven Valdez908ac192017-01-12 13:17:07 -0500249 return ssl_hs_error;
250 }
251
David Benjamin707af292017-03-10 17:47:18 -0500252 hs->tls13_state = state_select_session;
253 return ssl_hs_ok;
254}
Steven Valdez908ac192017-01-12 13:17:07 -0500255
David Benjamin707af292017-03-10 17:47:18 -0500256static enum ssl_ticket_aead_result_t select_session(
David Benjamin37af90f2017-07-29 01:42:16 -0400257 SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
David Benjamin7934f082017-08-01 16:32:25 -0400258 int32_t *out_ticket_age_skew, const SSLMessage &msg,
259 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin707af292017-03-10 17:47:18 -0500260 SSL *const ssl = hs->ssl;
261 *out_session = NULL;
262
David Benjaminc11ea9422017-08-29 16:33:21 -0400263 // Decode the ticket if we agreed on a PSK key exchange mode.
David Benjamin707af292017-03-10 17:47:18 -0500264 CBS pre_shared_key;
265 if (!hs->accept_psk_mode ||
266 !ssl_client_hello_get_extension(client_hello, &pre_shared_key,
267 TLSEXT_TYPE_pre_shared_key)) {
268 return ssl_ticket_aead_ignore_ticket;
269 }
270
David Benjaminc11ea9422017-08-29 16:33:21 -0400271 // Verify that the pre_shared_key extension is the last extension in
272 // ClientHello.
David Benjamin707af292017-03-10 17:47:18 -0500273 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
274 client_hello->extensions + client_hello->extensions_len) {
275 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
276 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
277 return ssl_ticket_aead_error;
278 }
279
280 CBS ticket, binders;
281 uint32_t client_ticket_age;
282 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders,
283 &client_ticket_age, out_alert,
284 &pre_shared_key)) {
285 return ssl_ticket_aead_error;
286 }
287
David Benjaminc11ea9422017-08-29 16:33:21 -0400288 // TLS 1.3 session tickets are renewed separately as part of the
289 // NewSessionTicket.
David Benjaminfd45ee72017-08-31 14:49:09 -0400290 bool unused_renew;
David Benjamin37af90f2017-07-29 01:42:16 -0400291 UniquePtr<SSL_SESSION> session;
David Benjamin707af292017-03-10 17:47:18 -0500292 enum ssl_ticket_aead_result_t ret =
293 ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket),
294 CBS_len(&ticket), NULL, 0);
295 switch (ret) {
296 case ssl_ticket_aead_success:
297 break;
298 case ssl_ticket_aead_error:
299 *out_alert = SSL_AD_INTERNAL_ERROR;
300 return ret;
301 default:
302 return ret;
303 }
304
David Benjamin37af90f2017-07-29 01:42:16 -0400305 if (!ssl_session_is_resumable(hs, session.get()) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400306 // Historically, some TLS 1.3 tickets were missing ticket_age_add.
David Benjamin707af292017-03-10 17:47:18 -0500307 !session->ticket_age_add_valid) {
David Benjamin707af292017-03-10 17:47:18 -0500308 return ssl_ticket_aead_ignore_ticket;
309 }
310
David Benjaminc11ea9422017-08-29 16:33:21 -0400311 // Recover the client ticket age and convert to seconds.
David Benjamin707af292017-03-10 17:47:18 -0500312 client_ticket_age -= session->ticket_age_add;
313 client_ticket_age /= 1000;
314
315 struct OPENSSL_timeval now;
316 ssl_get_current_time(ssl, &now);
317
David Benjaminc11ea9422017-08-29 16:33:21 -0400318 // Compute the server ticket age in seconds.
David Benjamin707af292017-03-10 17:47:18 -0500319 assert(now.tv_sec >= session->time);
320 uint64_t server_ticket_age = now.tv_sec - session->time;
321
David Benjaminc11ea9422017-08-29 16:33:21 -0400322 // To avoid overflowing |hs->ticket_age_skew|, we will not resume
323 // 68-year-old sessions.
David Benjamin707af292017-03-10 17:47:18 -0500324 if (server_ticket_age > INT32_MAX) {
David Benjamin707af292017-03-10 17:47:18 -0500325 return ssl_ticket_aead_ignore_ticket;
326 }
327
David Benjaminc11ea9422017-08-29 16:33:21 -0400328 // TODO(davidben,svaldez): Measure this value to decide on tolerance. For
329 // now, accept all values. https://crbug.com/boringssl/113.
David Benjamin707af292017-03-10 17:47:18 -0500330 *out_ticket_age_skew =
331 (int32_t)client_ticket_age - (int32_t)server_ticket_age;
332
David Benjaminc11ea9422017-08-29 16:33:21 -0400333 // Check the PSK binder.
David Benjamin7934f082017-08-01 16:32:25 -0400334 if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) {
David Benjamin707af292017-03-10 17:47:18 -0500335 *out_alert = SSL_AD_DECRYPT_ERROR;
336 return ssl_ticket_aead_error;
337 }
338
David Benjamin37af90f2017-07-29 01:42:16 -0400339 *out_session = std::move(session);
David Benjamin707af292017-03-10 17:47:18 -0500340 return ssl_ticket_aead_success;
341}
342
343static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
344 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400345 SSLMessage msg;
346 if (!ssl->method->get_message(ssl, &msg)) {
347 return ssl_hs_read_message;
348 }
David Benjamin707af292017-03-10 17:47:18 -0500349 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400350 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin707af292017-03-10 17:47:18 -0500351 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400352 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500353 return ssl_hs_error;
354 }
355
David Benjamin4eb95cc2016-11-16 17:08:23 +0900356 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin37af90f2017-07-29 01:42:16 -0400357 UniquePtr<SSL_SESSION> session;
David Benjamin7934f082017-08-01 16:32:25 -0400358 switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, msg,
David Benjamin707af292017-03-10 17:47:18 -0500359 &client_hello)) {
360 case ssl_ticket_aead_ignore_ticket:
David Benjamin37af90f2017-07-29 01:42:16 -0400361 assert(!session);
David Benjamin707af292017-03-10 17:47:18 -0500362 if (!ssl_get_new_session(hs, 1 /* server */)) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400363 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjaminf01f42a2016-11-16 19:05:33 +0900364 return ssl_hs_error;
365 }
David Benjamin707af292017-03-10 17:47:18 -0500366 break;
Steven Valdeza833c352016-11-01 13:39:36 -0400367
David Benjamin707af292017-03-10 17:47:18 -0500368 case ssl_ticket_aead_success:
David Benjaminc11ea9422017-08-29 16:33:21 -0400369 // Carry over authentication information from the previous handshake into
370 // a fresh session.
David Benjamin37af90f2017-07-29 01:42:16 -0400371 hs->new_session =
372 SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
Steven Valdez2d850622017-01-11 11:34:52 -0500373
David Benjaminc11ea9422017-08-29 16:33:21 -0400374 if (// Early data must be acceptable for this ticket.
Alessandro Ghedini67bb45f2017-03-30 16:33:24 -0500375 ssl->cert->enable_early_data &&
Steven Valdez2d850622017-01-11 11:34:52 -0500376 session->ticket_max_early_data != 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400377 // The client must have offered early data.
Steven Valdez2d850622017-01-11 11:34:52 -0500378 hs->early_data_offered &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400379 // Channel ID is incompatible with 0-RTT.
Steven Valdez2a070722017-03-25 20:54:16 -0500380 !ssl->s3->tlsext_channel_id_valid &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400381 // Custom extensions is incompatible with 0-RTT.
Steven Valdezf4ecc842017-08-10 14:02:56 -0400382 hs->custom_extensions.received == 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400383 // The negotiated ALPN must match the one in the ticket.
Steven Valdez2d850622017-01-11 11:34:52 -0500384 ssl->s3->alpn_selected_len == session->early_alpn_len &&
385 OPENSSL_memcmp(ssl->s3->alpn_selected, session->early_alpn,
386 ssl->s3->alpn_selected_len) == 0) {
David Benjamin7e58c5e2017-10-11 13:01:08 -0400387 ssl->early_data_accepted = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500388 }
389
David Benjamin707af292017-03-10 17:47:18 -0500390 if (hs->new_session == NULL) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400391 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500392 return ssl_hs_error;
393 }
394
David Benjamin046bc1f2017-08-31 15:06:42 -0400395 ssl->s3->session_reused = true;
David Benjamin707af292017-03-10 17:47:18 -0500396
David Benjaminc11ea9422017-08-29 16:33:21 -0400397 // Resumption incorporates fresh key material, so refresh the timeout.
David Benjamin31b0c9b2017-07-20 14:49:15 -0400398 ssl_session_renew_timeout(ssl, hs->new_session.get(),
David Benjamin707af292017-03-10 17:47:18 -0500399 ssl->session_ctx->session_psk_dhe_timeout);
400 break;
401
402 case ssl_ticket_aead_error:
David Benjamind1e3ce12017-10-06 18:31:15 -0400403 ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
David Benjamin707af292017-03-10 17:47:18 -0500404 return ssl_hs_error;
405
406 case ssl_ticket_aead_retry:
407 hs->tls13_state = state_select_session;
408 return ssl_hs_pending_ticket;
409 }
410
David Benjaminc11ea9422017-08-29 16:33:21 -0400411 // Record connection properties in the new session.
David Benjamin707af292017-03-10 17:47:18 -0500412 hs->new_session->cipher = hs->new_cipher;
413
David Benjaminc11ea9422017-08-29 16:33:21 -0400414 // Store the initial negotiated ALPN in the session.
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500415 if (ssl->s3->alpn_selected != NULL) {
David Benjamind304a2f2017-07-12 23:00:28 -0400416 hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
417 ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
David Benjamin45738dd2017-02-09 20:01:26 -0500418 if (hs->new_session->early_alpn == NULL) {
David Benjamind1e3ce12017-10-06 18:31:15 -0400419 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500420 return ssl_hs_error;
421 }
David Benjamin45738dd2017-02-09 20:01:26 -0500422 hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500423 }
424
David Benjamin707af292017-03-10 17:47:18 -0500425 if (ssl->ctx->dos_protection_cb != NULL &&
426 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400427 // Connection rejected for DOS reasons.
David Benjamin707af292017-03-10 17:47:18 -0500428 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400429 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
David Benjamin707af292017-03-10 17:47:18 -0500430 return ssl_hs_error;
431 }
432
David Benjaminc11ea9422017-08-29 16:33:21 -0400433 // Incorporate the PSK into the running secret.
David Benjamin8f820b42016-11-30 11:24:40 -0500434 if (ssl->s3->session_reused) {
David Benjamin45738dd2017-02-09 20:01:26 -0500435 if (!tls13_advance_key_schedule(hs, hs->new_session->master_key,
436 hs->new_session->master_key_length)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500437 return ssl_hs_error;
438 }
Steven Valdez908ac192017-01-12 13:17:07 -0500439 } else if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400440 return ssl_hs_error;
441 }
442
Steven Valdez2d850622017-01-11 11:34:52 -0500443 if (ssl->early_data_accepted) {
444 if (!tls13_derive_early_secrets(hs)) {
445 return ssl_hs_error;
446 }
447 } else if (hs->early_data_offered) {
David Benjamin046bc1f2017-08-31 15:06:42 -0400448 ssl->s3->skip_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500449 }
450
David Benjaminc11ea9422017-08-29 16:33:21 -0400451 // Resolve ECDHE and incorporate it into the secret.
David Benjamin046bc1f2017-08-31 15:06:42 -0400452 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900453 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400454 if (need_retry) {
David Benjamin7e58c5e2017-10-11 13:01:08 -0400455 ssl->early_data_accepted = false;
David Benjamin046bc1f2017-08-31 15:06:42 -0400456 ssl->s3->skip_early_data = true;
David Benjamin8f94c312017-08-01 17:35:55 -0400457 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500458 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400459 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400460 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400461 return ssl_hs_error;
462 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400463
David Benjamin8f94c312017-08-01 17:35:55 -0400464 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500465 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400466 return ssl_hs_ok;
467}
Steven Valdez143e8b32016-07-11 13:19:03 -0400468
David Benjaminc3c88822016-11-14 10:32:04 +0900469static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
470 SSL *const ssl = hs->ssl;
David Benjamin1386aad2017-07-19 23:57:40 -0400471 ScopedCBB cbb;
472 CBB body, extensions;
Steven Valdez5440fe02016-07-18 12:40:30 -0400473 uint16_t group_id;
David Benjamin1386aad2017-07-19 23:57:40 -0400474 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez5440fe02016-07-18 12:40:30 -0400475 SSL3_MT_HELLO_RETRY_REQUEST) ||
476 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900477 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400478 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400479 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
480 !CBB_add_u16(&extensions, 2 /* length */) ||
481 !CBB_add_u16(&extensions, group_id) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400482 !ssl_add_message_cbb(ssl, cbb.get())) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400483 return ssl_hs_error;
484 }
485
David Benjamin7934f082017-08-01 16:32:25 -0400486 hs->tls13_state = state_read_second_client_hello;
487 return ssl_hs_flush;
Steven Valdez5440fe02016-07-18 12:40:30 -0400488}
489
David Benjamin7934f082017-08-01 16:32:25 -0400490static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900491 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400492 SSLMessage msg;
493 if (!ssl->method->get_message(ssl, &msg)) {
494 return ssl_hs_read_message;
495 }
496 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400497 return ssl_hs_error;
498 }
David Benjamin731058e2016-12-03 23:15:13 -0500499 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400500 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400501 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
David Benjamind1e3ce12017-10-06 18:31:15 -0400502 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
Steven Valdez5440fe02016-07-18 12:40:30 -0400503 return ssl_hs_error;
504 }
505
David Benjamin046bc1f2017-08-31 15:06:42 -0400506 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900507 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400508 if (need_retry) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400509 // Only send one HelloRetryRequest.
David Benjamind1e3ce12017-10-06 18:31:15 -0400510 ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
Steven Valdez5440fe02016-07-18 12:40:30 -0400511 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400512 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400513 return ssl_hs_error;
514 }
515
David Benjamin7934f082017-08-01 16:32:25 -0400516 if (!ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400517 return ssl_hs_error;
518 }
519
David Benjamin8f94c312017-08-01 17:35:55 -0400520 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500521 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400522 return ssl_hs_ok;
523}
524
David Benjaminc3c88822016-11-14 10:32:04 +0900525static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
526 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500527
Steven Valdez038da9b2017-07-10 12:57:25 -0400528 uint16_t version = ssl->version;
Steven Valdez16821262017-09-08 17:03:42 -0400529 if (ssl_is_resumption_experiment(ssl->version)) {
Steven Valdez038da9b2017-07-10 12:57:25 -0400530 version = TLS1_2_VERSION;
531 }
532
David Benjaminc11ea9422017-08-29 16:33:21 -0400533 // Send a ServerHello.
David Benjamin1386aad2017-07-19 23:57:40 -0400534 ScopedCBB cbb;
535 CBB body, extensions, session_id;
536 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
Steven Valdez038da9b2017-07-10 12:57:25 -0400537 !CBB_add_u16(&body, version) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400538 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
539 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
Steven Valdez16821262017-09-08 17:03:42 -0400540 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez520e1222017-06-13 12:45:25 -0400541 (!CBB_add_u8_length_prefixed(&body, &session_id) ||
542 !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len))) ||
David Benjamin45738dd2017-02-09 20:01:26 -0500543 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
Steven Valdez16821262017-09-08 17:03:42 -0400544 (ssl_is_resumption_experiment(ssl->version) && !CBB_add_u8(&body, 0)) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400545 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900546 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Steven Valdez924a3522017-03-02 16:05:03 -0500547 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
Steven Valdez16821262017-09-08 17:03:42 -0400548 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez038da9b2017-07-10 12:57:25 -0400549 !ssl_ext_supported_versions_add_serverhello(hs, &extensions)) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400550 !ssl_add_message_cbb(ssl, cbb.get())) {
551 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400552 }
553
Steven Valdez16821262017-09-08 17:03:42 -0400554 if (ssl_is_resumption_experiment(ssl->version) &&
David Benjamin666d16e2017-10-06 18:45:16 -0400555 !ssl->method->add_change_cipher_spec(ssl)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400556 return ssl_hs_error;
Steven Valdez520e1222017-06-13 12:45:25 -0400557 }
558
David Benjaminc11ea9422017-08-29 16:33:21 -0400559 // Derive and enable the handshake traffic secrets.
Steven Valdez4cb84942016-12-16 11:29:28 -0500560 if (!tls13_derive_handshake_secrets(hs) ||
Steven Valdez4cb84942016-12-16 11:29:28 -0500561 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
562 hs->hash_len)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400563 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400564 }
565
David Benjaminc11ea9422017-08-29 16:33:21 -0400566 // Send EncryptedExtensions.
David Benjamin1386aad2017-07-19 23:57:40 -0400567 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez143e8b32016-07-11 13:19:03 -0400568 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500569 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400570 !ssl_add_message_cbb(ssl, cbb.get())) {
571 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400572 }
573
David Benjaminc3648fa2017-07-01 10:50:56 -0400574 if (!ssl->s3->session_reused) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400575 // Determine whether to request a client certificate.
David Benjaminc3648fa2017-07-01 10:50:56 -0400576 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
David Benjaminc11ea9422017-08-29 16:33:21 -0400577 // Only request a certificate if Channel ID isn't negotiated.
David Benjaminc3648fa2017-07-01 10:50:56 -0400578 if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
579 ssl->s3->tlsext_channel_id_valid) {
David Benjaminfd45ee72017-08-31 14:49:09 -0400580 hs->cert_request = false;
David Benjaminc3648fa2017-07-01 10:50:56 -0400581 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400582 }
583
David Benjaminc11ea9422017-08-29 16:33:21 -0400584 // Send a CertificateRequest, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500585 if (hs->cert_request) {
586 CBB sigalgs_cbb;
David Benjamin1386aad2017-07-19 23:57:40 -0400587 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin81b7bc32017-01-12 19:44:57 -0500588 SSL3_MT_CERTIFICATE_REQUEST) ||
David Benjamin69522112017-03-28 15:38:29 -0500589 !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
590 !CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
591 !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) ||
592 !ssl_add_client_CA_list(ssl, &body) ||
David Benjamin81b7bc32017-01-12 19:44:57 -0500593 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400594 !ssl_add_message_cbb(ssl, cbb.get())) {
595 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400596 }
597 }
598
David Benjaminc11ea9422017-08-29 16:33:21 -0400599 // Send the server Certificate message, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500600 if (!ssl->s3->session_reused) {
601 if (!ssl_has_certificate(ssl)) {
602 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
David Benjamin1386aad2017-07-19 23:57:40 -0400603 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500604 }
605
David Benjamin0f24bed2017-01-12 19:46:50 -0500606 if (!tls13_add_certificate(hs)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400607 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500608 }
609
610 hs->tls13_state = state_send_server_certificate_verify;
611 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400612 }
613
David Benjamin81b7bc32017-01-12 19:44:57 -0500614 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500615 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400616}
617
David Benjamin44148742017-06-17 13:20:59 -0400618static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
619 switch (tls13_add_certificate_verify(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400620 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500621 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500622 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400623
624 case ssl_private_key_retry:
David Benjamin44148742017-06-17 13:20:59 -0400625 hs->tls13_state = state_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400626 return ssl_hs_private_key_operation;
627
628 case ssl_private_key_failure:
629 return ssl_hs_error;
630 }
631
632 assert(0);
633 return ssl_hs_error;
634}
635
David Benjaminc3c88822016-11-14 10:32:04 +0900636static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900637 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500638 if (!tls13_add_finished(hs) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400639 // Update the secret to the master secret and derive traffic keys.
David Benjamin25ac2512017-01-12 19:31:28 -0500640 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900641 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400642 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
643 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400644 return ssl_hs_error;
645 }
646
David Benjamin794cc592017-03-25 22:24:23 -0500647 if (ssl->early_data_accepted) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400648 // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
649 // the wire sooner and also avoids triggering a write on |SSL_read| when
650 // processing the client Finished. This requires computing the client
651 // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1.
David Benjamin794cc592017-03-25 22:24:23 -0500652 size_t finished_len;
653 if (!tls13_finished_mac(hs, hs->expected_client_finished, &finished_len,
654 0 /* client */)) {
655 return ssl_hs_error;
656 }
657
658 if (finished_len != hs->hash_len) {
659 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
660 return ssl_hs_error;
661 }
662
David Benjaminc11ea9422017-08-29 16:33:21 -0400663 // Feed the predicted Finished into the transcript. This allows us to derive
664 // the resumption secret early and send half-RTT tickets.
665 //
666 // TODO(davidben): This will need to be updated for DTLS 1.3.
David Benjamin794cc592017-03-25 22:24:23 -0500667 assert(!SSL_is_dtls(hs->ssl));
David Benjamind304a2f2017-07-12 23:00:28 -0400668 assert(hs->hash_len <= 0xff);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400669 uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0,
670 static_cast<uint8_t>(hs->hash_len)};
671 if (!hs->transcript.Update(header, sizeof(header)) ||
672 !hs->transcript.Update(hs->expected_client_finished, hs->hash_len) ||
David Benjamin8f94c312017-08-01 17:35:55 -0400673 !tls13_derive_resumption_secret(hs) ||
674 !add_new_session_tickets(hs)) {
David Benjamin794cc592017-03-25 22:24:23 -0500675 return ssl_hs_error;
676 }
677 }
678
Steven Valdez2d850622017-01-11 11:34:52 -0500679 hs->tls13_state = state_read_second_client_flight;
680 return ssl_hs_flush;
681}
682
683static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
684 SSL *const ssl = hs->ssl;
685 if (ssl->early_data_accepted) {
686 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->early_traffic_secret,
687 hs->hash_len)) {
688 return ssl_hs_error;
689 }
David Benjaminfd45ee72017-08-31 14:49:09 -0400690 hs->can_early_write = true;
691 hs->can_early_read = true;
692 hs->in_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500693 hs->tls13_state = state_process_end_of_early_data;
694 return ssl_hs_read_end_of_early_data;
695 }
Steven Valdez2d850622017-01-11 11:34:52 -0500696 hs->tls13_state = state_process_end_of_early_data;
697 return ssl_hs_ok;
698}
699
700static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
Steven Valdez520e1222017-06-13 12:45:25 -0400701 hs->tls13_state = state_process_change_cipher_spec;
David Benjaminc11ea9422017-08-29 16:33:21 -0400702 // If early data was accepted, the ChangeCipherSpec message will be in the
703 // discarded early data.
Steven Valdez520e1222017-06-13 12:45:25 -0400704 if (hs->early_data_offered && !hs->ssl->early_data_accepted) {
705 return ssl_hs_ok;
706 }
Steven Valdezc7d4d212017-09-11 13:53:08 -0400707 return ssl_is_resumption_client_ccs_experiment(hs->ssl->version)
Steven Valdez520e1222017-06-13 12:45:25 -0400708 ? ssl_hs_read_change_cipher_spec
709 : ssl_hs_ok;
710}
711
712static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
Steven Valdez2d850622017-01-11 11:34:52 -0500713 SSL *const ssl = hs->ssl;
714 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
715 hs->hash_len)) {
716 return ssl_hs_error;
717 }
David Benjamin7934f082017-08-01 16:32:25 -0400718 hs->tls13_state = ssl->early_data_accepted ? state_read_client_finished
719 : state_read_client_certificate;
720 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400721}
722
David Benjamin7934f082017-08-01 16:32:25 -0400723static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900724 SSL *const ssl = hs->ssl;
725 if (!hs->cert_request) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400726 // OpenSSL returns X509_V_OK when no certificates are requested. This is
727 // classed by them as a bug, but it's assumed by at least NGINX.
David Benjamin45738dd2017-02-09 20:01:26 -0500728 hs->new_session->verify_result = X509_V_OK;
Adam Langley37646832016-08-01 16:16:46 -0700729
David Benjaminc11ea9422017-08-29 16:33:21 -0400730 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400731 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400732 return ssl_hs_ok;
733 }
734
David Benjamin4087df92016-08-01 20:16:31 -0400735 const int allow_anonymous =
736 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
David Benjamin7934f082017-08-01 16:32:25 -0400737 SSLMessage msg;
738 if (!ssl->method->get_message(ssl, &msg)) {
739 return ssl_hs_read_message;
740 }
741 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) ||
742 !tls13_process_certificate(hs, msg, allow_anonymous) ||
743 !ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400744 return ssl_hs_error;
745 }
746
David Benjamin8f94c312017-08-01 17:35:55 -0400747 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400748 hs->tls13_state = state_read_client_certificate_verify;
749 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400750}
751
David Benjamin7934f082017-08-01 16:32:25 -0400752static enum ssl_hs_wait_t do_read_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900753 SSL_HANDSHAKE *hs) {
754 SSL *const ssl = hs->ssl;
David Benjamin45738dd2017-02-09 20:01:26 -0500755 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400756 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400757 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400758 return ssl_hs_ok;
759 }
760
David Benjamin7934f082017-08-01 16:32:25 -0400761 SSLMessage msg;
762 if (!ssl->method->get_message(ssl, &msg)) {
763 return ssl_hs_read_message;
764 }
765
David Benjamin3a1dd462017-07-11 16:13:10 -0400766 switch (ssl_verify_peer_cert(hs)) {
767 case ssl_verify_ok:
768 break;
769 case ssl_verify_invalid:
770 return ssl_hs_error;
771 case ssl_verify_retry:
David Benjamin7934f082017-08-01 16:32:25 -0400772 hs->tls13_state = state_read_client_certificate_verify;
David Benjamin3a1dd462017-07-11 16:13:10 -0400773 return ssl_hs_certificate_verify;
774 }
775
David Benjamin7934f082017-08-01 16:32:25 -0400776 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
777 !tls13_process_certificate_verify(hs, msg) ||
778 !ssl_hash_message(hs, msg)) {
David Benjamin6929f272016-11-16 19:10:08 +0900779 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400780 }
781
David Benjamin8f94c312017-08-01 17:35:55 -0400782 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400783 hs->tls13_state = state_read_channel_id;
784 return ssl_hs_ok;
Nick Harper60a85cb2016-09-23 16:25:11 -0700785}
786
David Benjamin7934f082017-08-01 16:32:25 -0400787static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
David Benjamin8f94c312017-08-01 17:35:55 -0400788 SSL *const ssl = hs->ssl;
789 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin7934f082017-08-01 16:32:25 -0400790 hs->tls13_state = state_read_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700791 return ssl_hs_ok;
792 }
793
David Benjamin7934f082017-08-01 16:32:25 -0400794 SSLMessage msg;
795 if (!ssl->method->get_message(ssl, &msg)) {
796 return ssl_hs_read_message;
797 }
798 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) ||
799 !tls1_verify_channel_id(hs, msg) ||
800 !ssl_hash_message(hs, msg)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700801 return ssl_hs_error;
802 }
803
David Benjamin8f94c312017-08-01 17:35:55 -0400804 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400805 hs->tls13_state = state_read_client_finished;
806 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400807}
808
David Benjamin7934f082017-08-01 16:32:25 -0400809static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900810 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400811 SSLMessage msg;
812 if (!ssl->method->get_message(ssl, &msg)) {
813 return ssl_hs_read_message;
814 }
815 if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400816 // If early data was accepted, we've already computed the client Finished
817 // and derived the resumption secret.
David Benjamin7934f082017-08-01 16:32:25 -0400818 !tls13_process_finished(hs, msg, ssl->early_data_accepted) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400819 // evp_aead_seal keys have already been switched.
Steven Valdeza833c352016-11-01 13:39:36 -0400820 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
David Benjamin794cc592017-03-25 22:24:23 -0500821 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400822 return ssl_hs_error;
823 }
824
David Benjamin794cc592017-03-25 22:24:23 -0500825 if (!ssl->early_data_accepted) {
David Benjamin7934f082017-08-01 16:32:25 -0400826 if (!ssl_hash_message(hs, msg) ||
David Benjamin794cc592017-03-25 22:24:23 -0500827 !tls13_derive_resumption_secret(hs)) {
828 return ssl_hs_error;
829 }
830
David Benjaminc11ea9422017-08-29 16:33:21 -0400831 // We send post-handshake tickets as part of the handshake in 1-RTT.
David Benjamin794cc592017-03-25 22:24:23 -0500832 hs->tls13_state = state_send_new_session_ticket;
David Benjamin8f94c312017-08-01 17:35:55 -0400833 } else {
David Benjaminc11ea9422017-08-29 16:33:21 -0400834 // We already sent half-RTT tickets.
David Benjamin8f94c312017-08-01 17:35:55 -0400835 hs->tls13_state = state_done;
David Benjamin794cc592017-03-25 22:24:23 -0500836 }
837
David Benjamin8f94c312017-08-01 17:35:55 -0400838 ssl->method->next_message(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400839 return ssl_hs_ok;
840}
841
David Benjaminc3c88822016-11-14 10:32:04 +0900842static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400843 // If the client doesn't accept resumption with PSK_DHE_KE, don't send a
844 // session ticket.
Steven Valdeza833c352016-11-01 13:39:36 -0400845 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500846 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400847 return ssl_hs_ok;
848 }
849
David Benjamin794cc592017-03-25 22:24:23 -0500850 if (!add_new_session_tickets(hs)) {
851 return ssl_hs_error;
Steven Valdez08b65f42016-12-07 15:29:45 -0500852 }
853
David Benjamin25ac2512017-01-12 19:31:28 -0500854 hs->tls13_state = state_done;
855 return ssl_hs_flush;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400856}
857
David Benjaminc3c88822016-11-14 10:32:04 +0900858enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500859 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400860 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamind304a2f2017-07-12 23:00:28 -0400861 enum server_hs_state_t state =
862 static_cast<enum server_hs_state_t>(hs->tls13_state);
Steven Valdez143e8b32016-07-11 13:19:03 -0400863 switch (state) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400864 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900865 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400866 break;
David Benjamin707af292017-03-10 17:47:18 -0500867 case state_select_session:
868 ret = do_select_session(hs);
869 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400870 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900871 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400872 break;
David Benjamin7934f082017-08-01 16:32:25 -0400873 case state_read_second_client_hello:
874 ret = do_read_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400875 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400876 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900877 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400878 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400879 case state_send_server_certificate_verify:
David Benjamin44148742017-06-17 13:20:59 -0400880 ret = do_send_server_certificate_verify(hs);
Steven Valdez2d850622017-01-11 11:34:52 -0500881 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400882 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900883 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400884 break;
Steven Valdez2d850622017-01-11 11:34:52 -0500885 case state_read_second_client_flight:
886 ret = do_read_second_client_flight(hs);
887 break;
888 case state_process_end_of_early_data:
889 ret = do_process_end_of_early_data(hs);
890 break;
Steven Valdez520e1222017-06-13 12:45:25 -0400891 case state_process_change_cipher_spec:
892 ret = do_process_change_cipher_spec(hs);
893 break;
David Benjamin7934f082017-08-01 16:32:25 -0400894 case state_read_client_certificate:
895 ret = do_read_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400896 break;
David Benjamin7934f082017-08-01 16:32:25 -0400897 case state_read_client_certificate_verify:
898 ret = do_read_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400899 break;
David Benjamin7934f082017-08-01 16:32:25 -0400900 case state_read_channel_id:
901 ret = do_read_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700902 break;
David Benjamin7934f082017-08-01 16:32:25 -0400903 case state_read_client_finished:
904 ret = do_read_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400905 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400906 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900907 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400908 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400909 case state_done:
910 ret = ssl_hs_ok;
911 break;
912 }
913
Steven Valdez4d71a9a2017-08-14 15:08:34 -0400914 if (hs->tls13_state != state) {
David Benjaminf60bcfb2017-08-18 15:23:44 -0400915 ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1);
916 }
917
Steven Valdez143e8b32016-07-11 13:19:03 -0400918 if (ret != ssl_hs_ok) {
919 return ret;
920 }
921 }
922
923 return ssl_hs_ok;
924}
David Benjamin86e95b82017-07-18 16:34:25 -0400925
David Benjaminf60bcfb2017-08-18 15:23:44 -0400926const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) {
927 enum server_hs_state_t state =
928 static_cast<enum server_hs_state_t>(hs->tls13_state);
929 switch (state) {
930 case state_select_parameters:
931 return "TLS 1.3 server select_parameters";
932 case state_select_session:
933 return "TLS 1.3 server select_session";
934 case state_send_hello_retry_request:
935 return "TLS 1.3 server send_hello_retry_request";
936 case state_read_second_client_hello:
937 return "TLS 1.3 server read_second_client_hello";
938 case state_send_server_hello:
939 return "TLS 1.3 server send_server_hello";
940 case state_send_server_certificate_verify:
941 return "TLS 1.3 server send_server_certificate_verify";
942 case state_send_server_finished:
943 return "TLS 1.3 server send_server_finished";
944 case state_read_second_client_flight:
945 return "TLS 1.3 server read_second_client_flight";
946 case state_process_change_cipher_spec:
947 return "TLS 1.3 server process_change_cipher_spec";
948 case state_process_end_of_early_data:
949 return "TLS 1.3 server process_end_of_early_data";
950 case state_read_client_certificate:
951 return "TLS 1.3 server read_client_certificate";
952 case state_read_client_certificate_verify:
953 return "TLS 1.3 server read_client_certificate_verify";
954 case state_read_channel_id:
955 return "TLS 1.3 server read_channel_id";
956 case state_read_client_finished:
957 return "TLS 1.3 server read_client_finished";
958 case state_send_new_session_ticket:
959 return "TLS 1.3 server send_new_session_ticket";
960 case state_done:
961 return "TLS 1.3 server done";
962 }
963
964 return "TLS 1.3 server unknown";
965}
966
David Benjamin86e95b82017-07-18 16:34:25 -0400967} // namespace bssl