blob: ea1beae948bf599f341b53e09e73faddb372ee70 [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);
72 ssl3_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)) {
Steven Valdez5440fe02016-07-18 12:40:30 -040081 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
82 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 Benjaminf01f42a2016-11-16 19:05:33 +0900117 const uint16_t version = ssl3_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
David Benjamin1386aad2017-07-19 23:57:40 -0400168 ScopedCBB cbb;
David Benjamin794cc592017-03-25 22:24:23 -0500169 CBB body, ticket, extensions;
David Benjamin1386aad2017-07-19 23:57:40 -0400170 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin794cc592017-03-25 22:24:23 -0500171 SSL3_MT_NEW_SESSION_TICKET) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400172 !CBB_add_u32(&body, hs->new_session->timeout) ||
173 !CBB_add_u32(&body, hs->new_session->ticket_age_add) ||
David Benjamin794cc592017-03-25 22:24:23 -0500174 !CBB_add_u16_length_prefixed(&body, &ticket) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400175 !ssl_encrypt_ticket(ssl, &ticket, hs->new_session.get()) ||
David Benjamin794cc592017-03-25 22:24:23 -0500176 !CBB_add_u16_length_prefixed(&body, &extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400177 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500178 }
179
Alessandro Ghedini67bb45f2017-03-30 16:33:24 -0500180 if (ssl->cert->enable_early_data) {
David Benjamin31b0c9b2017-07-20 14:49:15 -0400181 hs->new_session->ticket_max_early_data = kMaxEarlyDataAccepted;
David Benjamin794cc592017-03-25 22:24:23 -0500182
183 CBB early_data_info;
184 if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
185 !CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
David Benjamin31b0c9b2017-07-20 14:49:15 -0400186 !CBB_add_u32(&early_data_info,
187 hs->new_session->ticket_max_early_data) ||
David Benjamin794cc592017-03-25 22:24:23 -0500188 !CBB_flush(&extensions)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400189 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500190 }
191 }
192
David Benjaminc11ea9422017-08-29 16:33:21 -0400193 // Add a fake extension. See draft-davidben-tls-grease-01.
David Benjamin794cc592017-03-25 22:24:23 -0500194 if (!CBB_add_u16(&extensions,
195 ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
196 !CBB_add_u16(&extensions, 0 /* empty */)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400197 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500198 }
199
David Benjamin1386aad2017-07-19 23:57:40 -0400200 if (!ssl_add_message_cbb(ssl, cbb.get())) {
201 return 0;
David Benjamin794cc592017-03-25 22:24:23 -0500202 }
203 }
204
205 return 1;
David Benjamin794cc592017-03-25 22:24:23 -0500206}
207
David Benjaminc3c88822016-11-14 10:32:04 +0900208static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400209 // At this point, most ClientHello extensions have already been processed by
210 // the common handshake logic. Resolve the remaining non-PSK parameters.
David Benjaminc3c88822016-11-14 10:32:04 +0900211 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400212 SSLMessage msg;
213 if (!ssl->method->get_message(ssl, &msg)) {
214 return ssl_hs_read_message;
215 }
David Benjamin731058e2016-12-03 23:15:13 -0500216 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400217 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin34202b92016-11-16 19:07:53 +0900218 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
219 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
220 return ssl_hs_error;
221 }
222
Steven Valdez520e1222017-06-13 12:45:25 -0400223 OPENSSL_memcpy(hs->session_id, client_hello.session_id,
224 client_hello.session_id_len);
225 hs->session_id_len = client_hello.session_id_len;
226
David Benjaminc11ea9422017-08-29 16:33:21 -0400227 // Negotiate the cipher suite.
David Benjamin45738dd2017-02-09 20:01:26 -0500228 hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
229 if (hs->new_cipher == NULL) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900230 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
231 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
232 return ssl_hs_error;
233 }
234
David Benjaminc11ea9422017-08-29 16:33:21 -0400235 // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
236 // deferred. Complete it now.
David Benjamin707af292017-03-10 17:47:18 -0500237 uint8_t alert = SSL_AD_DECODE_ERROR;
238 if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
239 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
240 return ssl_hs_error;
241 }
242
David Benjaminc11ea9422017-08-29 16:33:21 -0400243 // The PRF hash is now known. Set up the key schedule and hash the
244 // ClientHello.
Steven Valdez908ac192017-01-12 13:17:07 -0500245 if (!tls13_init_key_schedule(hs) ||
David Benjamin7934f082017-08-01 16:32:25 -0400246 !ssl_hash_message(hs, msg)) {
Steven Valdez908ac192017-01-12 13:17:07 -0500247 return ssl_hs_error;
248 }
249
David Benjamin707af292017-03-10 17:47:18 -0500250 hs->tls13_state = state_select_session;
251 return ssl_hs_ok;
252}
Steven Valdez908ac192017-01-12 13:17:07 -0500253
David Benjamin707af292017-03-10 17:47:18 -0500254static enum ssl_ticket_aead_result_t select_session(
David Benjamin37af90f2017-07-29 01:42:16 -0400255 SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr<SSL_SESSION> *out_session,
David Benjamin7934f082017-08-01 16:32:25 -0400256 int32_t *out_ticket_age_skew, const SSLMessage &msg,
257 const SSL_CLIENT_HELLO *client_hello) {
David Benjamin707af292017-03-10 17:47:18 -0500258 SSL *const ssl = hs->ssl;
259 *out_session = NULL;
260
David Benjaminc11ea9422017-08-29 16:33:21 -0400261 // Decode the ticket if we agreed on a PSK key exchange mode.
David Benjamin707af292017-03-10 17:47:18 -0500262 CBS pre_shared_key;
263 if (!hs->accept_psk_mode ||
264 !ssl_client_hello_get_extension(client_hello, &pre_shared_key,
265 TLSEXT_TYPE_pre_shared_key)) {
266 return ssl_ticket_aead_ignore_ticket;
267 }
268
David Benjaminc11ea9422017-08-29 16:33:21 -0400269 // Verify that the pre_shared_key extension is the last extension in
270 // ClientHello.
David Benjamin707af292017-03-10 17:47:18 -0500271 if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) !=
272 client_hello->extensions + client_hello->extensions_len) {
273 OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST);
274 *out_alert = SSL_AD_ILLEGAL_PARAMETER;
275 return ssl_ticket_aead_error;
276 }
277
278 CBS ticket, binders;
279 uint32_t client_ticket_age;
280 if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders,
281 &client_ticket_age, out_alert,
282 &pre_shared_key)) {
283 return ssl_ticket_aead_error;
284 }
285
David Benjaminc11ea9422017-08-29 16:33:21 -0400286 // TLS 1.3 session tickets are renewed separately as part of the
287 // NewSessionTicket.
David Benjaminfd45ee72017-08-31 14:49:09 -0400288 bool unused_renew;
David Benjamin37af90f2017-07-29 01:42:16 -0400289 UniquePtr<SSL_SESSION> session;
David Benjamin707af292017-03-10 17:47:18 -0500290 enum ssl_ticket_aead_result_t ret =
291 ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket),
292 CBS_len(&ticket), NULL, 0);
293 switch (ret) {
294 case ssl_ticket_aead_success:
295 break;
296 case ssl_ticket_aead_error:
297 *out_alert = SSL_AD_INTERNAL_ERROR;
298 return ret;
299 default:
300 return ret;
301 }
302
David Benjamin37af90f2017-07-29 01:42:16 -0400303 if (!ssl_session_is_resumable(hs, session.get()) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400304 // Historically, some TLS 1.3 tickets were missing ticket_age_add.
David Benjamin707af292017-03-10 17:47:18 -0500305 !session->ticket_age_add_valid) {
David Benjamin707af292017-03-10 17:47:18 -0500306 return ssl_ticket_aead_ignore_ticket;
307 }
308
David Benjaminc11ea9422017-08-29 16:33:21 -0400309 // Recover the client ticket age and convert to seconds.
David Benjamin707af292017-03-10 17:47:18 -0500310 client_ticket_age -= session->ticket_age_add;
311 client_ticket_age /= 1000;
312
313 struct OPENSSL_timeval now;
314 ssl_get_current_time(ssl, &now);
315
David Benjaminc11ea9422017-08-29 16:33:21 -0400316 // Compute the server ticket age in seconds.
David Benjamin707af292017-03-10 17:47:18 -0500317 assert(now.tv_sec >= session->time);
318 uint64_t server_ticket_age = now.tv_sec - session->time;
319
David Benjaminc11ea9422017-08-29 16:33:21 -0400320 // To avoid overflowing |hs->ticket_age_skew|, we will not resume
321 // 68-year-old sessions.
David Benjamin707af292017-03-10 17:47:18 -0500322 if (server_ticket_age > INT32_MAX) {
David Benjamin707af292017-03-10 17:47:18 -0500323 return ssl_ticket_aead_ignore_ticket;
324 }
325
David Benjaminc11ea9422017-08-29 16:33:21 -0400326 // TODO(davidben,svaldez): Measure this value to decide on tolerance. For
327 // now, accept all values. https://crbug.com/boringssl/113.
David Benjamin707af292017-03-10 17:47:18 -0500328 *out_ticket_age_skew =
329 (int32_t)client_ticket_age - (int32_t)server_ticket_age;
330
David Benjaminc11ea9422017-08-29 16:33:21 -0400331 // Check the PSK binder.
David Benjamin7934f082017-08-01 16:32:25 -0400332 if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) {
David Benjamin707af292017-03-10 17:47:18 -0500333 *out_alert = SSL_AD_DECRYPT_ERROR;
334 return ssl_ticket_aead_error;
335 }
336
David Benjamin37af90f2017-07-29 01:42:16 -0400337 *out_session = std::move(session);
David Benjamin707af292017-03-10 17:47:18 -0500338 return ssl_ticket_aead_success;
339}
340
341static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
342 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400343 SSLMessage msg;
344 if (!ssl->method->get_message(ssl, &msg)) {
345 return ssl_hs_read_message;
346 }
David Benjamin707af292017-03-10 17:47:18 -0500347 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400348 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
David Benjamin707af292017-03-10 17:47:18 -0500349 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
350 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
351 return ssl_hs_error;
352 }
353
David Benjamin4eb95cc2016-11-16 17:08:23 +0900354 uint8_t alert = SSL_AD_DECODE_ERROR;
David Benjamin37af90f2017-07-29 01:42:16 -0400355 UniquePtr<SSL_SESSION> session;
David Benjamin7934f082017-08-01 16:32:25 -0400356 switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, msg,
David Benjamin707af292017-03-10 17:47:18 -0500357 &client_hello)) {
358 case ssl_ticket_aead_ignore_ticket:
David Benjamin37af90f2017-07-29 01:42:16 -0400359 assert(!session);
David Benjamin707af292017-03-10 17:47:18 -0500360 if (!ssl_get_new_session(hs, 1 /* server */)) {
David Benjaminf01f42a2016-11-16 19:05:33 +0900361 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
362 return ssl_hs_error;
363 }
David Benjamin707af292017-03-10 17:47:18 -0500364 break;
Steven Valdeza833c352016-11-01 13:39:36 -0400365
David Benjamin707af292017-03-10 17:47:18 -0500366 case ssl_ticket_aead_success:
David Benjaminc11ea9422017-08-29 16:33:21 -0400367 // Carry over authentication information from the previous handshake into
368 // a fresh session.
David Benjamin37af90f2017-07-29 01:42:16 -0400369 hs->new_session =
370 SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY);
Steven Valdez2d850622017-01-11 11:34:52 -0500371
David Benjaminc11ea9422017-08-29 16:33:21 -0400372 if (// Early data must be acceptable for this ticket.
Alessandro Ghedini67bb45f2017-03-30 16:33:24 -0500373 ssl->cert->enable_early_data &&
Steven Valdez2d850622017-01-11 11:34:52 -0500374 session->ticket_max_early_data != 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400375 // The client must have offered early data.
Steven Valdez2d850622017-01-11 11:34:52 -0500376 hs->early_data_offered &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400377 // Channel ID is incompatible with 0-RTT.
Steven Valdez2a070722017-03-25 20:54:16 -0500378 !ssl->s3->tlsext_channel_id_valid &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400379 // Custom extensions is incompatible with 0-RTT.
Steven Valdezf4ecc842017-08-10 14:02:56 -0400380 hs->custom_extensions.received == 0 &&
David Benjaminc11ea9422017-08-29 16:33:21 -0400381 // The negotiated ALPN must match the one in the ticket.
Steven Valdez2d850622017-01-11 11:34:52 -0500382 ssl->s3->alpn_selected_len == session->early_alpn_len &&
383 OPENSSL_memcmp(ssl->s3->alpn_selected, session->early_alpn,
384 ssl->s3->alpn_selected_len) == 0) {
385 ssl->early_data_accepted = 1;
386 }
387
David Benjamin707af292017-03-10 17:47:18 -0500388 if (hs->new_session == NULL) {
389 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
390 return ssl_hs_error;
391 }
392
David Benjamin046bc1f2017-08-31 15:06:42 -0400393 ssl->s3->session_reused = true;
David Benjamin707af292017-03-10 17:47:18 -0500394
David Benjaminc11ea9422017-08-29 16:33:21 -0400395 // Resumption incorporates fresh key material, so refresh the timeout.
David Benjamin31b0c9b2017-07-20 14:49:15 -0400396 ssl_session_renew_timeout(ssl, hs->new_session.get(),
David Benjamin707af292017-03-10 17:47:18 -0500397 ssl->session_ctx->session_psk_dhe_timeout);
398 break;
399
400 case ssl_ticket_aead_error:
401 ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
402 return ssl_hs_error;
403
404 case ssl_ticket_aead_retry:
405 hs->tls13_state = state_select_session;
406 return ssl_hs_pending_ticket;
407 }
408
David Benjaminc11ea9422017-08-29 16:33:21 -0400409 // Record connection properties in the new session.
David Benjamin707af292017-03-10 17:47:18 -0500410 hs->new_session->cipher = hs->new_cipher;
411
David Benjaminc11ea9422017-08-29 16:33:21 -0400412 // Store the initial negotiated ALPN in the session.
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500413 if (ssl->s3->alpn_selected != NULL) {
David Benjamind304a2f2017-07-12 23:00:28 -0400414 hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
415 ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
David Benjamin45738dd2017-02-09 20:01:26 -0500416 if (hs->new_session->early_alpn == NULL) {
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500417 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
418 return ssl_hs_error;
419 }
David Benjamin45738dd2017-02-09 20:01:26 -0500420 hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
Steven Valdez27a9e6a2017-02-14 13:20:40 -0500421 }
422
David Benjamin707af292017-03-10 17:47:18 -0500423 if (ssl->ctx->dos_protection_cb != NULL &&
424 ssl->ctx->dos_protection_cb(&client_hello) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400425 // Connection rejected for DOS reasons.
David Benjamin707af292017-03-10 17:47:18 -0500426 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
427 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
428 return ssl_hs_error;
429 }
430
David Benjaminc11ea9422017-08-29 16:33:21 -0400431 // Incorporate the PSK into the running secret.
David Benjamin8f820b42016-11-30 11:24:40 -0500432 if (ssl->s3->session_reused) {
David Benjamin45738dd2017-02-09 20:01:26 -0500433 if (!tls13_advance_key_schedule(hs, hs->new_session->master_key,
434 hs->new_session->master_key_length)) {
David Benjamin8f820b42016-11-30 11:24:40 -0500435 return ssl_hs_error;
436 }
Steven Valdez908ac192017-01-12 13:17:07 -0500437 } else if (!tls13_advance_key_schedule(hs, kZeroes, hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400438 return ssl_hs_error;
439 }
440
Steven Valdez2d850622017-01-11 11:34:52 -0500441 if (ssl->early_data_accepted) {
442 if (!tls13_derive_early_secrets(hs)) {
443 return ssl_hs_error;
444 }
445 } else if (hs->early_data_offered) {
David Benjamin046bc1f2017-08-31 15:06:42 -0400446 ssl->s3->skip_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500447 }
448
David Benjaminc11ea9422017-08-29 16:33:21 -0400449 // Resolve ECDHE and incorporate it into the secret.
David Benjamin046bc1f2017-08-31 15:06:42 -0400450 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900451 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400452 if (need_retry) {
Steven Valdez2d850622017-01-11 11:34:52 -0500453 ssl->early_data_accepted = 0;
David Benjamin046bc1f2017-08-31 15:06:42 -0400454 ssl->s3->skip_early_data = true;
David Benjamin8f94c312017-08-01 17:35:55 -0400455 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500456 hs->tls13_state = state_send_hello_retry_request;
Steven Valdez5440fe02016-07-18 12:40:30 -0400457 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400458 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400459 return ssl_hs_error;
460 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400461
David Benjamin8f94c312017-08-01 17:35:55 -0400462 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500463 hs->tls13_state = state_send_server_hello;
Steven Valdez5440fe02016-07-18 12:40:30 -0400464 return ssl_hs_ok;
465}
Steven Valdez143e8b32016-07-11 13:19:03 -0400466
David Benjaminc3c88822016-11-14 10:32:04 +0900467static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) {
468 SSL *const ssl = hs->ssl;
David Benjamin1386aad2017-07-19 23:57:40 -0400469 ScopedCBB cbb;
470 CBB body, extensions;
Steven Valdez5440fe02016-07-18 12:40:30 -0400471 uint16_t group_id;
David Benjamin1386aad2017-07-19 23:57:40 -0400472 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez5440fe02016-07-18 12:40:30 -0400473 SSL3_MT_HELLO_RETRY_REQUEST) ||
474 !CBB_add_u16(&body, ssl->version) ||
David Benjaminf3c8f8d2016-11-17 17:20:47 +0900475 !tls1_get_shared_group(hs, &group_id) ||
Steven Valdez5440fe02016-07-18 12:40:30 -0400476 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin3baa6e12016-10-07 21:10:38 -0400477 !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
478 !CBB_add_u16(&extensions, 2 /* length */) ||
479 !CBB_add_u16(&extensions, group_id) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400480 !ssl_add_message_cbb(ssl, cbb.get())) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400481 return ssl_hs_error;
482 }
483
David Benjamin7934f082017-08-01 16:32:25 -0400484 hs->tls13_state = state_read_second_client_hello;
485 return ssl_hs_flush;
Steven Valdez5440fe02016-07-18 12:40:30 -0400486}
487
David Benjamin7934f082017-08-01 16:32:25 -0400488static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900489 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400490 SSLMessage msg;
491 if (!ssl->method->get_message(ssl, &msg)) {
492 return ssl_hs_read_message;
493 }
494 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400495 return ssl_hs_error;
496 }
David Benjamin731058e2016-12-03 23:15:13 -0500497 SSL_CLIENT_HELLO client_hello;
David Benjamin7934f082017-08-01 16:32:25 -0400498 if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400499 OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
500 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
501 return ssl_hs_error;
502 }
503
David Benjamin046bc1f2017-08-31 15:06:42 -0400504 bool need_retry;
David Benjamin6e4fc332016-11-17 16:43:08 +0900505 if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
Steven Valdez5440fe02016-07-18 12:40:30 -0400506 if (need_retry) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400507 // Only send one HelloRetryRequest.
Steven Valdez5440fe02016-07-18 12:40:30 -0400508 ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
509 OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
Steven Valdez143e8b32016-07-11 13:19:03 -0400510 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400511 return ssl_hs_error;
512 }
513
David Benjamin7934f082017-08-01 16:32:25 -0400514 if (!ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400515 return ssl_hs_error;
516 }
517
David Benjamin8f94c312017-08-01 17:35:55 -0400518 ssl->method->next_message(ssl);
David Benjamin3977f302016-12-11 13:30:41 -0500519 hs->tls13_state = state_send_server_hello;
Steven Valdez143e8b32016-07-11 13:19:03 -0400520 return ssl_hs_ok;
521}
522
David Benjaminc3c88822016-11-14 10:32:04 +0900523static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
524 SSL *const ssl = hs->ssl;
David Benjamin81b7bc32017-01-12 19:44:57 -0500525
Steven Valdez038da9b2017-07-10 12:57:25 -0400526 uint16_t version = ssl->version;
Steven Valdez16821262017-09-08 17:03:42 -0400527 if (ssl_is_resumption_experiment(ssl->version)) {
Steven Valdez038da9b2017-07-10 12:57:25 -0400528 version = TLS1_2_VERSION;
529 }
530
David Benjaminc11ea9422017-08-29 16:33:21 -0400531 // Send a ServerHello.
David Benjamin1386aad2017-07-19 23:57:40 -0400532 ScopedCBB cbb;
533 CBB body, extensions, session_id;
534 if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
Steven Valdez038da9b2017-07-10 12:57:25 -0400535 !CBB_add_u16(&body, version) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400536 !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
537 !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
Steven Valdez16821262017-09-08 17:03:42 -0400538 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez520e1222017-06-13 12:45:25 -0400539 (!CBB_add_u8_length_prefixed(&body, &session_id) ||
540 !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len))) ||
David Benjamin45738dd2017-02-09 20:01:26 -0500541 !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
Steven Valdez16821262017-09-08 17:03:42 -0400542 (ssl_is_resumption_experiment(ssl->version) && !CBB_add_u8(&body, 0)) ||
Steven Valdez143e8b32016-07-11 13:19:03 -0400543 !CBB_add_u16_length_prefixed(&body, &extensions) ||
David Benjamin8baf9632016-11-17 17:11:16 +0900544 !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
Steven Valdez924a3522017-03-02 16:05:03 -0500545 !ssl_ext_key_share_add_serverhello(hs, &extensions) ||
Steven Valdez16821262017-09-08 17:03:42 -0400546 (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez038da9b2017-07-10 12:57:25 -0400547 !ssl_ext_supported_versions_add_serverhello(hs, &extensions)) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400548 !ssl_add_message_cbb(ssl, cbb.get())) {
549 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400550 }
551
Steven Valdez16821262017-09-08 17:03:42 -0400552 if (ssl_is_resumption_experiment(ssl->version) &&
Steven Valdez520e1222017-06-13 12:45:25 -0400553 !ssl3_add_change_cipher_spec(ssl)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400554 return ssl_hs_error;
Steven Valdez520e1222017-06-13 12:45:25 -0400555 }
556
David Benjaminc11ea9422017-08-29 16:33:21 -0400557 // Derive and enable the handshake traffic secrets.
Steven Valdez4cb84942016-12-16 11:29:28 -0500558 if (!tls13_derive_handshake_secrets(hs) ||
Steven Valdez4cb84942016-12-16 11:29:28 -0500559 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
560 hs->hash_len)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400561 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400562 }
563
David Benjaminc11ea9422017-08-29 16:33:21 -0400564 // Send EncryptedExtensions.
David Benjamin1386aad2017-07-19 23:57:40 -0400565 if (!ssl->method->init_message(ssl, cbb.get(), &body,
Steven Valdez143e8b32016-07-11 13:19:03 -0400566 SSL3_MT_ENCRYPTED_EXTENSIONS) ||
David Benjamin8c880a22016-12-03 02:20:34 -0500567 !ssl_add_serverhello_tlsext(hs, &body) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400568 !ssl_add_message_cbb(ssl, cbb.get())) {
569 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400570 }
571
David Benjaminc3648fa2017-07-01 10:50:56 -0400572 if (!ssl->s3->session_reused) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400573 // Determine whether to request a client certificate.
David Benjaminc3648fa2017-07-01 10:50:56 -0400574 hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
David Benjaminc11ea9422017-08-29 16:33:21 -0400575 // Only request a certificate if Channel ID isn't negotiated.
David Benjaminc3648fa2017-07-01 10:50:56 -0400576 if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
577 ssl->s3->tlsext_channel_id_valid) {
David Benjaminfd45ee72017-08-31 14:49:09 -0400578 hs->cert_request = false;
David Benjaminc3648fa2017-07-01 10:50:56 -0400579 }
Steven Valdez143e8b32016-07-11 13:19:03 -0400580 }
581
David Benjaminc11ea9422017-08-29 16:33:21 -0400582 // Send a CertificateRequest, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500583 if (hs->cert_request) {
584 CBB sigalgs_cbb;
David Benjamin1386aad2017-07-19 23:57:40 -0400585 if (!ssl->method->init_message(ssl, cbb.get(), &body,
David Benjamin81b7bc32017-01-12 19:44:57 -0500586 SSL3_MT_CERTIFICATE_REQUEST) ||
David Benjamin69522112017-03-28 15:38:29 -0500587 !CBB_add_u8(&body, 0 /* no certificate_request_context. */) ||
588 !CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
589 !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) ||
590 !ssl_add_client_CA_list(ssl, &body) ||
David Benjamin81b7bc32017-01-12 19:44:57 -0500591 !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) ||
David Benjamin1386aad2017-07-19 23:57:40 -0400592 !ssl_add_message_cbb(ssl, cbb.get())) {
593 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400594 }
595 }
596
David Benjaminc11ea9422017-08-29 16:33:21 -0400597 // Send the server Certificate message, if necessary.
David Benjamin81b7bc32017-01-12 19:44:57 -0500598 if (!ssl->s3->session_reused) {
599 if (!ssl_has_certificate(ssl)) {
600 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
David Benjamin1386aad2017-07-19 23:57:40 -0400601 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500602 }
603
David Benjamin0f24bed2017-01-12 19:46:50 -0500604 if (!tls13_add_certificate(hs)) {
David Benjamin1386aad2017-07-19 23:57:40 -0400605 return ssl_hs_error;
David Benjamin81b7bc32017-01-12 19:44:57 -0500606 }
607
608 hs->tls13_state = state_send_server_certificate_verify;
609 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400610 }
611
David Benjamin81b7bc32017-01-12 19:44:57 -0500612 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500613 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400614}
615
David Benjamin44148742017-06-17 13:20:59 -0400616static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) {
617 switch (tls13_add_certificate_verify(hs)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400618 case ssl_private_key_success:
David Benjamin3977f302016-12-11 13:30:41 -0500619 hs->tls13_state = state_send_server_finished;
David Benjamin25ac2512017-01-12 19:31:28 -0500620 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400621
622 case ssl_private_key_retry:
David Benjamin44148742017-06-17 13:20:59 -0400623 hs->tls13_state = state_send_server_certificate_verify;
Steven Valdez143e8b32016-07-11 13:19:03 -0400624 return ssl_hs_private_key_operation;
625
626 case ssl_private_key_failure:
627 return ssl_hs_error;
628 }
629
630 assert(0);
631 return ssl_hs_error;
632}
633
David Benjaminc3c88822016-11-14 10:32:04 +0900634static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900635 SSL *const ssl = hs->ssl;
David Benjamin0f24bed2017-01-12 19:46:50 -0500636 if (!tls13_add_finished(hs) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400637 // Update the secret to the master secret and derive traffic keys.
David Benjamin25ac2512017-01-12 19:31:28 -0500638 !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) ||
David Benjamin6e4fc332016-11-17 16:43:08 +0900639 !tls13_derive_application_secrets(hs) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400640 !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0,
641 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400642 return ssl_hs_error;
643 }
644
David Benjamin794cc592017-03-25 22:24:23 -0500645 if (ssl->early_data_accepted) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400646 // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on
647 // the wire sooner and also avoids triggering a write on |SSL_read| when
648 // processing the client Finished. This requires computing the client
649 // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1.
David Benjamin794cc592017-03-25 22:24:23 -0500650 size_t finished_len;
651 if (!tls13_finished_mac(hs, hs->expected_client_finished, &finished_len,
652 0 /* client */)) {
653 return ssl_hs_error;
654 }
655
656 if (finished_len != hs->hash_len) {
657 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
658 return ssl_hs_error;
659 }
660
David Benjaminc11ea9422017-08-29 16:33:21 -0400661 // Feed the predicted Finished into the transcript. This allows us to derive
662 // the resumption secret early and send half-RTT tickets.
663 //
664 // TODO(davidben): This will need to be updated for DTLS 1.3.
David Benjamin794cc592017-03-25 22:24:23 -0500665 assert(!SSL_is_dtls(hs->ssl));
David Benjamind304a2f2017-07-12 23:00:28 -0400666 assert(hs->hash_len <= 0xff);
David Benjamin6dc8bf62017-07-19 16:38:21 -0400667 uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0,
668 static_cast<uint8_t>(hs->hash_len)};
669 if (!hs->transcript.Update(header, sizeof(header)) ||
670 !hs->transcript.Update(hs->expected_client_finished, hs->hash_len) ||
David Benjamin8f94c312017-08-01 17:35:55 -0400671 !tls13_derive_resumption_secret(hs) ||
672 !add_new_session_tickets(hs)) {
David Benjamin794cc592017-03-25 22:24:23 -0500673 return ssl_hs_error;
674 }
675 }
676
Steven Valdez2d850622017-01-11 11:34:52 -0500677 hs->tls13_state = state_read_second_client_flight;
678 return ssl_hs_flush;
679}
680
681static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
682 SSL *const ssl = hs->ssl;
683 if (ssl->early_data_accepted) {
684 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->early_traffic_secret,
685 hs->hash_len)) {
686 return ssl_hs_error;
687 }
David Benjaminfd45ee72017-08-31 14:49:09 -0400688 hs->can_early_write = true;
689 hs->can_early_read = true;
690 hs->in_early_data = true;
Steven Valdez2d850622017-01-11 11:34:52 -0500691 hs->tls13_state = state_process_end_of_early_data;
692 return ssl_hs_read_end_of_early_data;
693 }
Steven Valdez2d850622017-01-11 11:34:52 -0500694 hs->tls13_state = state_process_end_of_early_data;
695 return ssl_hs_ok;
696}
697
698static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
Steven Valdez520e1222017-06-13 12:45:25 -0400699 hs->tls13_state = state_process_change_cipher_spec;
David Benjaminc11ea9422017-08-29 16:33:21 -0400700 // If early data was accepted, the ChangeCipherSpec message will be in the
701 // discarded early data.
Steven Valdez520e1222017-06-13 12:45:25 -0400702 if (hs->early_data_offered && !hs->ssl->early_data_accepted) {
703 return ssl_hs_ok;
704 }
Steven Valdezc7d4d212017-09-11 13:53:08 -0400705 return ssl_is_resumption_client_ccs_experiment(hs->ssl->version)
Steven Valdez520e1222017-06-13 12:45:25 -0400706 ? ssl_hs_read_change_cipher_spec
707 : ssl_hs_ok;
708}
709
710static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
Steven Valdez2d850622017-01-11 11:34:52 -0500711 SSL *const ssl = hs->ssl;
712 if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
713 hs->hash_len)) {
714 return ssl_hs_error;
715 }
David Benjamin7934f082017-08-01 16:32:25 -0400716 hs->tls13_state = ssl->early_data_accepted ? state_read_client_finished
717 : state_read_client_certificate;
718 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400719}
720
David Benjamin7934f082017-08-01 16:32:25 -0400721static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900722 SSL *const ssl = hs->ssl;
723 if (!hs->cert_request) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400724 // OpenSSL returns X509_V_OK when no certificates are requested. This is
725 // classed by them as a bug, but it's assumed by at least NGINX.
David Benjamin45738dd2017-02-09 20:01:26 -0500726 hs->new_session->verify_result = X509_V_OK;
Adam Langley37646832016-08-01 16:16:46 -0700727
David Benjaminc11ea9422017-08-29 16:33:21 -0400728 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400729 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400730 return ssl_hs_ok;
731 }
732
David Benjamin4087df92016-08-01 20:16:31 -0400733 const int allow_anonymous =
734 (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0;
David Benjamin7934f082017-08-01 16:32:25 -0400735 SSLMessage msg;
736 if (!ssl->method->get_message(ssl, &msg)) {
737 return ssl_hs_read_message;
738 }
739 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) ||
740 !tls13_process_certificate(hs, msg, allow_anonymous) ||
741 !ssl_hash_message(hs, msg)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400742 return ssl_hs_error;
743 }
744
David Benjamin8f94c312017-08-01 17:35:55 -0400745 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400746 hs->tls13_state = state_read_client_certificate_verify;
747 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400748}
749
David Benjamin7934f082017-08-01 16:32:25 -0400750static enum ssl_hs_wait_t do_read_client_certificate_verify(
David Benjaminc3c88822016-11-14 10:32:04 +0900751 SSL_HANDSHAKE *hs) {
752 SSL *const ssl = hs->ssl;
David Benjamin45738dd2017-02-09 20:01:26 -0500753 if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400754 // Skip this state.
David Benjamin7934f082017-08-01 16:32:25 -0400755 hs->tls13_state = state_read_channel_id;
Steven Valdez143e8b32016-07-11 13:19:03 -0400756 return ssl_hs_ok;
757 }
758
David Benjamin7934f082017-08-01 16:32:25 -0400759 SSLMessage msg;
760 if (!ssl->method->get_message(ssl, &msg)) {
761 return ssl_hs_read_message;
762 }
763
David Benjamin3a1dd462017-07-11 16:13:10 -0400764 switch (ssl_verify_peer_cert(hs)) {
765 case ssl_verify_ok:
766 break;
767 case ssl_verify_invalid:
768 return ssl_hs_error;
769 case ssl_verify_retry:
David Benjamin7934f082017-08-01 16:32:25 -0400770 hs->tls13_state = state_read_client_certificate_verify;
David Benjamin3a1dd462017-07-11 16:13:10 -0400771 return ssl_hs_certificate_verify;
772 }
773
David Benjamin7934f082017-08-01 16:32:25 -0400774 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) ||
775 !tls13_process_certificate_verify(hs, msg) ||
776 !ssl_hash_message(hs, msg)) {
David Benjamin6929f272016-11-16 19:10:08 +0900777 return ssl_hs_error;
Steven Valdez143e8b32016-07-11 13:19:03 -0400778 }
779
David Benjamin8f94c312017-08-01 17:35:55 -0400780 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400781 hs->tls13_state = state_read_channel_id;
782 return ssl_hs_ok;
Nick Harper60a85cb2016-09-23 16:25:11 -0700783}
784
David Benjamin7934f082017-08-01 16:32:25 -0400785static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) {
David Benjamin8f94c312017-08-01 17:35:55 -0400786 SSL *const ssl = hs->ssl;
787 if (!ssl->s3->tlsext_channel_id_valid) {
David Benjamin7934f082017-08-01 16:32:25 -0400788 hs->tls13_state = state_read_client_finished;
Nick Harper60a85cb2016-09-23 16:25:11 -0700789 return ssl_hs_ok;
790 }
791
David Benjamin7934f082017-08-01 16:32:25 -0400792 SSLMessage msg;
793 if (!ssl->method->get_message(ssl, &msg)) {
794 return ssl_hs_read_message;
795 }
796 if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) ||
797 !tls1_verify_channel_id(hs, msg) ||
798 !ssl_hash_message(hs, msg)) {
Nick Harper60a85cb2016-09-23 16:25:11 -0700799 return ssl_hs_error;
800 }
801
David Benjamin8f94c312017-08-01 17:35:55 -0400802 ssl->method->next_message(ssl);
David Benjamin7934f082017-08-01 16:32:25 -0400803 hs->tls13_state = state_read_client_finished;
804 return ssl_hs_ok;
Steven Valdez143e8b32016-07-11 13:19:03 -0400805}
806
David Benjamin7934f082017-08-01 16:32:25 -0400807static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) {
David Benjaminc3c88822016-11-14 10:32:04 +0900808 SSL *const ssl = hs->ssl;
David Benjamin7934f082017-08-01 16:32:25 -0400809 SSLMessage msg;
810 if (!ssl->method->get_message(ssl, &msg)) {
811 return ssl_hs_read_message;
812 }
813 if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400814 // If early data was accepted, we've already computed the client Finished
815 // and derived the resumption secret.
David Benjamin7934f082017-08-01 16:32:25 -0400816 !tls13_process_finished(hs, msg, ssl->early_data_accepted) ||
David Benjaminc11ea9422017-08-29 16:33:21 -0400817 // evp_aead_seal keys have already been switched.
Steven Valdeza833c352016-11-01 13:39:36 -0400818 !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0,
David Benjamin794cc592017-03-25 22:24:23 -0500819 hs->hash_len)) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400820 return ssl_hs_error;
821 }
822
David Benjamin794cc592017-03-25 22:24:23 -0500823 if (!ssl->early_data_accepted) {
David Benjamin7934f082017-08-01 16:32:25 -0400824 if (!ssl_hash_message(hs, msg) ||
David Benjamin794cc592017-03-25 22:24:23 -0500825 !tls13_derive_resumption_secret(hs)) {
826 return ssl_hs_error;
827 }
828
David Benjaminc11ea9422017-08-29 16:33:21 -0400829 // We send post-handshake tickets as part of the handshake in 1-RTT.
David Benjamin794cc592017-03-25 22:24:23 -0500830 hs->tls13_state = state_send_new_session_ticket;
David Benjamin8f94c312017-08-01 17:35:55 -0400831 } else {
David Benjaminc11ea9422017-08-29 16:33:21 -0400832 // We already sent half-RTT tickets.
David Benjamin8f94c312017-08-01 17:35:55 -0400833 hs->tls13_state = state_done;
David Benjamin794cc592017-03-25 22:24:23 -0500834 }
835
David Benjamin8f94c312017-08-01 17:35:55 -0400836 ssl->method->next_message(ssl);
Steven Valdez143e8b32016-07-11 13:19:03 -0400837 return ssl_hs_ok;
838}
839
David Benjaminc3c88822016-11-14 10:32:04 +0900840static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400841 // If the client doesn't accept resumption with PSK_DHE_KE, don't send a
842 // session ticket.
Steven Valdeza833c352016-11-01 13:39:36 -0400843 if (!hs->accept_psk_mode) {
David Benjamin3977f302016-12-11 13:30:41 -0500844 hs->tls13_state = state_done;
Steven Valdeza833c352016-11-01 13:39:36 -0400845 return ssl_hs_ok;
846 }
847
David Benjamin794cc592017-03-25 22:24:23 -0500848 if (!add_new_session_tickets(hs)) {
849 return ssl_hs_error;
Steven Valdez08b65f42016-12-07 15:29:45 -0500850 }
851
David Benjamin25ac2512017-01-12 19:31:28 -0500852 hs->tls13_state = state_done;
853 return ssl_hs_flush;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400854}
855
David Benjaminc3c88822016-11-14 10:32:04 +0900856enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
David Benjamin3977f302016-12-11 13:30:41 -0500857 while (hs->tls13_state != state_done) {
Steven Valdez143e8b32016-07-11 13:19:03 -0400858 enum ssl_hs_wait_t ret = ssl_hs_error;
David Benjamind304a2f2017-07-12 23:00:28 -0400859 enum server_hs_state_t state =
860 static_cast<enum server_hs_state_t>(hs->tls13_state);
Steven Valdez143e8b32016-07-11 13:19:03 -0400861 switch (state) {
David Benjamin25fe85b2016-08-09 20:00:32 -0400862 case state_select_parameters:
David Benjaminc3c88822016-11-14 10:32:04 +0900863 ret = do_select_parameters(hs);
David Benjamin25fe85b2016-08-09 20:00:32 -0400864 break;
David Benjamin707af292017-03-10 17:47:18 -0500865 case state_select_session:
866 ret = do_select_session(hs);
867 break;
Steven Valdez5440fe02016-07-18 12:40:30 -0400868 case state_send_hello_retry_request:
David Benjaminc3c88822016-11-14 10:32:04 +0900869 ret = do_send_hello_retry_request(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400870 break;
David Benjamin7934f082017-08-01 16:32:25 -0400871 case state_read_second_client_hello:
872 ret = do_read_second_client_hello(hs);
Steven Valdez5440fe02016-07-18 12:40:30 -0400873 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400874 case state_send_server_hello:
David Benjaminc3c88822016-11-14 10:32:04 +0900875 ret = do_send_server_hello(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400876 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400877 case state_send_server_certificate_verify:
David Benjamin44148742017-06-17 13:20:59 -0400878 ret = do_send_server_certificate_verify(hs);
Steven Valdez2d850622017-01-11 11:34:52 -0500879 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400880 case state_send_server_finished:
David Benjaminc3c88822016-11-14 10:32:04 +0900881 ret = do_send_server_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400882 break;
Steven Valdez2d850622017-01-11 11:34:52 -0500883 case state_read_second_client_flight:
884 ret = do_read_second_client_flight(hs);
885 break;
886 case state_process_end_of_early_data:
887 ret = do_process_end_of_early_data(hs);
888 break;
Steven Valdez520e1222017-06-13 12:45:25 -0400889 case state_process_change_cipher_spec:
890 ret = do_process_change_cipher_spec(hs);
891 break;
David Benjamin7934f082017-08-01 16:32:25 -0400892 case state_read_client_certificate:
893 ret = do_read_client_certificate(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400894 break;
David Benjamin7934f082017-08-01 16:32:25 -0400895 case state_read_client_certificate_verify:
896 ret = do_read_client_certificate_verify(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400897 break;
David Benjamin7934f082017-08-01 16:32:25 -0400898 case state_read_channel_id:
899 ret = do_read_channel_id(hs);
Nick Harper60a85cb2016-09-23 16:25:11 -0700900 break;
David Benjamin7934f082017-08-01 16:32:25 -0400901 case state_read_client_finished:
902 ret = do_read_client_finished(hs);
Steven Valdez143e8b32016-07-11 13:19:03 -0400903 break;
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400904 case state_send_new_session_ticket:
David Benjaminc3c88822016-11-14 10:32:04 +0900905 ret = do_send_new_session_ticket(hs);
Steven Valdez1e6f11a2016-07-27 11:10:52 -0400906 break;
Steven Valdez143e8b32016-07-11 13:19:03 -0400907 case state_done:
908 ret = ssl_hs_ok;
909 break;
910 }
911
Steven Valdez4d71a9a2017-08-14 15:08:34 -0400912 if (hs->tls13_state != state) {
David Benjaminf60bcfb2017-08-18 15:23:44 -0400913 ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1);
914 }
915
Steven Valdez143e8b32016-07-11 13:19:03 -0400916 if (ret != ssl_hs_ok) {
917 return ret;
918 }
919 }
920
921 return ssl_hs_ok;
922}
David Benjamin86e95b82017-07-18 16:34:25 -0400923
David Benjaminf60bcfb2017-08-18 15:23:44 -0400924const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) {
925 enum server_hs_state_t state =
926 static_cast<enum server_hs_state_t>(hs->tls13_state);
927 switch (state) {
928 case state_select_parameters:
929 return "TLS 1.3 server select_parameters";
930 case state_select_session:
931 return "TLS 1.3 server select_session";
932 case state_send_hello_retry_request:
933 return "TLS 1.3 server send_hello_retry_request";
934 case state_read_second_client_hello:
935 return "TLS 1.3 server read_second_client_hello";
936 case state_send_server_hello:
937 return "TLS 1.3 server send_server_hello";
938 case state_send_server_certificate_verify:
939 return "TLS 1.3 server send_server_certificate_verify";
940 case state_send_server_finished:
941 return "TLS 1.3 server send_server_finished";
942 case state_read_second_client_flight:
943 return "TLS 1.3 server read_second_client_flight";
944 case state_process_change_cipher_spec:
945 return "TLS 1.3 server process_change_cipher_spec";
946 case state_process_end_of_early_data:
947 return "TLS 1.3 server process_end_of_early_data";
948 case state_read_client_certificate:
949 return "TLS 1.3 server read_client_certificate";
950 case state_read_client_certificate_verify:
951 return "TLS 1.3 server read_client_certificate_verify";
952 case state_read_channel_id:
953 return "TLS 1.3 server read_channel_id";
954 case state_read_client_finished:
955 return "TLS 1.3 server read_client_finished";
956 case state_send_new_session_ticket:
957 return "TLS 1.3 server send_new_session_ticket";
958 case state_done:
959 return "TLS 1.3 server done";
960 }
961
962 return "TLS 1.3 server unknown";
963}
964
David Benjamin86e95b82017-07-18 16:34:25 -0400965} // namespace bssl